web-dev-qa-db-fra.com

Ansible - Utilisez default si une variable n'est pas définie

Je personnalise la création de linux users dans mon rôle. Je dois laisser les utilisateurs de mon rôle personnaliser home_directory, group_name, name, password.

Je me demandais s'il existe un moyen plus flexible de gérer les valeurs par défaut.

Je sais que le code ci-dessous est possible:

- name: Create default
  user:
    name: "default_name"
  when: my_variable is not defined

 - name: Create custom
  user:
    name: "{{my_variable}}"
  when: my_variable is defined

Mais comme je l'ai mentionné, il y a beaucoup de variables optionnelles et cela crée beaucoup de possibilités.

Y at-il quelque chose comme le code ci-dessus?

user:
  name: "default_name", "{{my_variable}}"

Le code doit définir name="default_name" lorsque my_variable n'est pas défini.

Je pourrais définir toutes les variables sur defaults/main.yml et créer l'utilisateur de la manière suivante:

- name: Create user
  user:
    name: "{{my_variable}}"

Mais ces variables sont dans un très gros hash et il y a des hashs dans ce hash qui ne peuvent être un défaut.

74
Bernardo Vale

Vous pouvez utiliser le default de Jinja:

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"
149
tedder42

Pas tout à fait lié, mais vous pouvez également rechercher la variable undefined ET empty (par exemple my_variable:). (NOTE: ne fonctionne qu'avec la version ansible> 1.9, voir: lien )

- name: Create user
  user:
    name: "{{ ((my_variable == None) | ternary('default_value', my_variable)) \
    if my_variable is defined else 'default_value' }}"
3
Tommy Nguyen

Si vous souhaitez boucler une seule lecture sur les éléments, définissez cette liste dans group_vars/all ou à un autre emplacement qui ait du sens:

all_items:
  - first
  - second
  - third
  - fourth

Ensuite, votre tâche peut ressembler à ceci:

  - name: List items or default list
    debug:
      var: item
    with_items: "{{ varlist | default(all_items) }}"

Transmettez varlist en tant que tableau JSON:

ansible-playbook <playbook_name> --extra-vars='{"varlist": [first,third]}'

Avant cela, vous voudrez peut-être aussi une tâche qui vérifie que chaque élément de varlist est aussi de all_items:

  - name: Ensure passed variables are in all_items
    fail:
      msg: "{{ item }} not  in all_items list"
    when: item not in all_items
    with_items: "{{ varlist | default(all_items) }}"
3
Jack

Si vous utilisez lookup pour définir l'environnement de lecture par défaut, vous avez également défini le deuxième paramètre de default sur true:

- set_facts:
    ansible_ssh_user: "{{ lookup('env', 'SSH_USER') | default('foo', true) }}"

Vous pouvez également concaténer plusieurs définitions par défaut:

- set_facts:
    ansible_ssh_user: "{{ some_var.split('-')[1] | default(lookup('env','USER'), true) | default('foo') }}"
1
panticz.de

Si quelqu'un recherche une option qui gère les variables imbriquées, il existe plusieurs options de ce type dans ce problème de github .

En bref, vous devez utiliser le filtre "default" pour chaque niveau de vars imbriqués. Pour une variable "a.nested.var" cela ressemblerait à:

- hosts: 'localhost'
  tasks:
    - debug:
        msg: "{{ ((a | default({})).nested | default({}) ).var | default('bar') }}"

ou vous pouvez définir les valeurs par défaut des plans vides pour chaque niveau de vars, en utilisant éventuellement un filtre "combine". Ou utilisez le filtre "json_query". Mais l'option que j'ai choisie me semble plus simple si vous n'avez qu'un seul niveau d'imbrication.

1
Roman Kruglov