web-dev-qa-db-fra.com

Modification possible de la valeur par défaut en fonction d'une condition

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)?

Détails

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).

Pseudocode

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'
        '' 
16
Francesco Abeni

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   
13
Navern

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.

4
ssc

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 '' }}"
3
S.K. Venkat