Ansible - Verwenden Sie die Standardeinstellung, wenn keine Variable definiert ist

99

Ich passe die Linux- usersErstellung in meiner Rolle an. Ich brauche Benutzer meiner Rolle anpassen lassen home_directory, group_name, name, password.

Ich habe mich gefragt, ob es eine flexiblere Möglichkeit gibt, mit Standardwerten umzugehen.

Ich weiß, dass der folgende Code möglich ist:

- 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

Aber wie gesagt, es gibt viele optionale Variablen und dies schafft viele Möglichkeiten.

Gibt es so etwas wie den obigen Code?

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

Der Code sollte festgelegt werden, name="default_name"wenn er my_variablenicht definiert ist.

Ich könnte alle Variablen aktivieren defaults/main.ymlund den Benutzer so erstellen:

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

Aber diese Variablen befinden sich in einem wirklich großen Hash und es gibt einige Hashes in diesem Hash, die kein Standard sein können.

Bernardo Vale
quelle
Verwandte: stackoverflow.com/questions/19614027/…
Ciro Santilli 8 冠状 病 六四 事件 法轮功

Antworten:

190

Sie können Jinjas verwenden default:

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"
tedder42
quelle
9
Und ob die Standardvariable von einer anderen Variablen abhängt. Gibt es beispielsweise default('/home/' {{ anothervar }})eine Möglichkeit, diese Werte zu verketten?
Bernardo Vale
7
Entfernen Sie einfach das 'um das default_valueund es würde eine Variable namens default_value
dagonza
6
Funktioniert nicht, wenn die Variable wie verschachtelt ist {{ dict.key | default(5) }}. Es wird fehlschlagen, wenn dictes nicht definiert ist.
Jordan Stewart
1
Zu [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}.
Ihrer Information
1
@ JordanStewart Ich hatte den gleichen Fall - mit verschachtelten Variablen. Ich habe unten eine Antwort mit möglichen Lösungen gepostet.
Roman Kruglov
11

Nicht vollständig verwandt, aber Sie können auch nach undefinedUND- Variablen empty(z. B. my_variable:) suchen. (HINWEIS: Funktioniert nur mit ansible Version> 1.9, siehe: Link )

- name: Create user
  user:
    name: "{{ ((my_variable == None) | ternary('default_value', my_variable)) \
    if my_variable is defined else 'default_value' }}"
Tommy Nguyen
quelle
2
Das ist großartig, sehr nützlich.
Eagle33322
4

Wenn Sie ein einzelnes Spiel haben, das Sie über die Elemente schleifen möchten, definieren Sie diese Liste in group_vars / all oder an einer anderen Stelle, die Sinn macht:

all_items:
  - first
  - second
  - third
  - fourth

Dann kann Ihre Aufgabe folgendermaßen aussehen:

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

Übergeben Sie varlist als JSON-Array:

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

Zuvor möchten Sie möglicherweise auch eine Aufgabe, die überprüft, ob sich jedes Element in varlist auch in all_items befindet :

  - 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) }}"
Jack
quelle
4

Wenn jemand nach einer Option sucht, die verschachtelte Variablen verarbeitet, gibt es in diesem Github-Problem mehrere solcher Optionen .

Kurz gesagt, Sie müssen den "Standard" -Filter für jede Ebene verschachtelter Variablen verwenden. Für eine Variable "a.nested.var" würde es so aussehen:

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

oder Sie können Standardwerte für leere Dikte für jede Vars-Ebene festlegen, indem Sie möglicherweise den Filter "Kombinieren" verwenden. Oder verwenden Sie den Filter "json_query". Die von mir gewählte Option erscheint mir jedoch einfacher, wenn Sie nur eine Verschachtelungsebene haben.

Roman Kruglov
quelle
3

Wenn Sie Lookup verwenden, um den Standardwert für das Lesen aus der Umgebung festzulegen, haben Sie auch den zweiten Standardparameter auf true festgelegt:

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

Sie können auch mehrere Standarddefinitionen verketten:

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

Die Frage ist ziemlich alt, aber was ist mit:

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

Es sieht für mich weniger umständlich aus ...

pshunter
quelle
1

Wenn Sie einen Standardwert für boolesche Fakten zuweisen, stellen Sie sicher, dass in default () keine Anführungszeichen verwendet werden.

- name: create bool default
  set_fact:
    name: "{{ my_bool | default(true) }}"

Für andere Variablen wird dieselbe Methode wie in der verifizierten Antwort verwendet.

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"
Samselvaprabu
quelle