Aller au contenu

Recommendation Cue 0.7#

Cue Flow#

Rappel sur les tasks flow#

Pour l’orchestration des "pre" et "post" task, on se repose sur le moteur flow, qui est une brique interne à Cue.

⚠ cue Flow n’est pas cue Tool.Task

La description d’une Task dans package tool de cue, avec $id et $after, ne correspond pas du tout aux tasks dans Flow

// A Task defines a step in the execution of a command.
Task: {
    $type: "tool.Task" // legacy field 'kind' still supported for now.

    // $id indicates the operation to run. It must be of the form
    // packagePath.Operation.
    $id: =~#"\."#

    // $after can be used to specify a task is run after another one, when
    // it does not otherwise refer to an output of that task.
    $after?: Task | [...Task]
}

Dans notre cas, on charge tout ce qui se trouve sous les branches pre_tasks, pre_apply_tasks, pre_plan_tasks, pre_destroy_tasks et post_tasks, post_apply_tasks, post_plan_tasks, post_destroy_tasks.

Problème lors de la construction des dépendances.#

Attention aux if#

run: [=~"_tasks$"]: [string]: {
    _cst_id: *"" | string
    if _cst_id == #RDSDBSecret._cst_id {
        namespace: string
        url:       run.pre_tasks["vault_\(infra_zone.name)"].url
        path:      "secret/zones/\(zone.provider.type)/\(zone.name)/rds/\(namespace)/db"

    }
}

La présence du if dans if _cst_id == #RDSDBSecret._cst_id semble poser problème au calcul des dépendances de cue flow et provoque des dépendances illogiques.

On va remplacer le if par un test :

run: [=~"_tasks$"]: [=~"_db$"]: #RDSDBSecret & {
    namespace: string
    url:       run.pre_tasks["vault_\(infra_zone.name)"].url
    path:      "secret/zones/\(zone.provider.type)/\(zone.name)/rds/\(namespace)/db"
}

Attention aux interpolations#

Lors d’une interpolation, il semble ne pas toujours voir la dépendance, par exemple :

login: exec.#Run & {
    cmd: ["nix-shell", "--quiet", "--run", """
        az login -u \(secret.data.username) -p \(secret.data.password) --allow-no-subscriptions --output table
        """,
    ]
}

on va le convertir en

login: exec.#Run & {
    let UserName = tasks.secret.data.username
    let Password = tasks.secret.data.password
    cmd: ["nix-shell", "--quiet", "--run", """
        az login -u \(UserName) -p \(Password) --allow-no-subscriptions --output table
        """,
    ]
}

pour rendre la dépendance explicite.

Dépendance aux taches vault#

Si la dépendance est liée à un élément concret, il ne sera pas vu comme dépendance de la tache.

Par exemple :

url: pre_tasks.vault_infra.url

Url est défini en dur -- donc il est concret au moment de l’évaluation -- il ne dépend pas de l’exécution de la tache vault_infra, donc notre tâche ne dépend pas de vault_infra.

Pour résoudre ce problème, on va lier explicitement la tache vault_infra à notre tâche.

_vault_login: pre_tasks.vault_infra
url:          _vault_login.url

Dépendance aux taches file.#Create#

Ici le lien avec la tache file.#Create n’est pas garantie

create_secret_list_script: file.#Create & {
    name:       "secret_list.sh"
    path:       "scripts"
    executable: true
    content:    mon.#ScriptVaultSecretList
}

"prometheus_auth_\(s.svc_hint)": exec.#RunJSON & {
    cmd: ["bash", "-c", "./scripts/secret_list.sh \(zone.infra_zone_name) \(secret_path)/prometheus-ingress basic-auth"]
    stdout: [...]
}

En utilisant abspath -- qui n’est pas concret au moment de l’évaluation -- on s’assure que le fichier secret_list.sh sera créé au moment de l’exécution.

"prometheus_auth_\(s.svc_hint)": exec.#RunJSON & {
    cmd: ["bash", "-c", "\(create_secret_list_script.abspath) \(zone.infra_zone_name) \(secret_path)/prometheus-ingress basic-auth"]
    stdout: [...]
}