Est-il possible de changer la valeur par défaut d'une variable de rôle en fonction d'une condition (c'est-à-dire la valeur d'une autre variable)?
J'ai deux variables liées pour une commande, env
et composer_opts
.
Si les deux sont laissés par défaut (env = "prod"
et composer_opts = "--no-dev"
) tout va bien.
Si je change env
en dev
, la valeur par défaut pour l'autre cassera ma commande, j'ai donc toujours besoin de définir les deux. Serait-il possible d'éviter cela en définissant une valeur conditionnelle par défaut avec un script personnalisé/if?
Important: je ne veux pas toujours définir le composer_opts
valeur selon la valeur env
. Je souhaite le définir uniquement s'il n'est pas déjà défini (c'est-à-dire une valeur dynamique par défaut).
Je voudrais faire quelque chose comme ça (le code suivant n'est pas valide, juste un pseudocode pour exprimer mon besoin)
---
# defaults/main.yml
env: prod
composer_opts:
when: "{{env}}" = 'prod'
'--no-dev --optimize-autoloader --no-interaction'
when: "{{env}}" = 'dev'
''
Je suggère cette solution:
---
- set_fact:
composer_opts: ""
when: "{{env}}" == 'dev'
Il définira composer_opts
variable en chaîne ""
lorsque la variable env
est égale à 'dev
'.
Voici un exemple de playbook basé sur une question mise à jour:
$ cat test.yml
---
- hosts: 127.0.0.1
connection: local
tasks:
- set_fact:
composer_opts: "{% if env == 'prod' %} '--no-dev --optimize-autoloader --no-interaction' {% else %} '' {% endif %}"
- debug: var=composer_opts
Exemple de sortie:
Sudo ansible-playbook test.yml -e env=dev
PLAY [127.0.0.1] **************************************************************
GATHERING FACTS ***************************************************************
ok: [127.0.0.1]
TASK: [set_fact ] *************************************************************
ok: [127.0.0.1]
TASK: [debug var="{{composer_opts}}"] *****************************************
ok: [127.0.0.1] => {
"var": {
" '' ": " '' "
}
}
PLAY RECAP ********************************************************************
127.0.0.1 : ok=3 changed=0 unreachable=0 failed=0
Sudo ansible-playbook test.yml -e env=prod
PLAY [127.0.0.1] **************************************************************
GATHERING FACTS ***************************************************************
ok: [127.0.0.1]
TASK: [set_fact ] *************************************************************
ok: [127.0.0.1]
TASK: [debug var="{{composer_opts}}"] *****************************************
ok: [127.0.0.1] => {
"var": {
" '--no-dev --optimize-autoloader --no-interaction' ": " '--no-dev --optimize-autoloader --no-interaction' "
}
}
PLAY RECAP ********************************************************************
127.0.0.1 : ok=3 changed=0 unreachable=0 failed=0
Alors que réponse de @ Navern fonctionne, j'ai trouvé la notation Jinja2 intégrée ("{% if env == 'prod' %} ...
) pour être extrêmement sensible à la notation et donc assez fragile. Par exemple, lors de l'habillage de la ligne en question pour une meilleure lisibilité, comme dans ce code non testé :
composer_opts: >
"{% if env == 'prod' %}
'--no-dev --optimize-autoloader --no-interaction'
{% else %}
''
{% endif %}"
Je me suis retrouvé avec des résultats inattendus, comme des espaces supplémentaires ou \n
dans composer_opts
.
L'approche que j'utilise est beaucoup plus stupide, mais aussi plus stable:
- name: set composer_opts for dev env
set_fact:
composer_opts: ''
when: "{{env}}" == 'dev'
- name: set composer_opts for prod env
set_fact:
composer_opts: '--no-dev --optimize-autoloader --no-interaction'
when: "{{env}}" == 'prod'
J'ai également trouvé cet article de blog utile, qui suit essentiellement la même approche.
Ansible set_fact basé sur la condition dans une doublure:
- name: "set composer_opts based on environment"
set_fact:
composer_opts: "{{ '--no-dev --optimize-autoloader --no-interaction' if (env == 'prod') else '' }}"