Ansible - Gunakan default jika variabel tidak ditentukan

101

Saya menyesuaikan userspembuatan linux di dalam peran saya. Saya harus membiarkan pengguna menyesuaikan peran saya home_directory, group_name, name, password.

Saya bertanya-tanya apakah ada cara yang lebih fleksibel untuk mengatasi nilai default.

Saya tahu bahwa kode di bawah ini mungkin:

- 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

Tapi seperti yang saya sebutkan, ada banyak variabel opsional dan ini menciptakan banyak kemungkinan.

Apakah ada yang seperti kode di atas?

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

Kode harus disetel name="default_name"jika my_variabletidak ditentukan.

Saya dapat mengatur semua variabel defaults/main.ymldan membuat pengguna seperti itu:

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

Tetapi variabel-variabel itu ada di dalam hash yang sangat besar dan ada beberapa hash di dalam hash itu yang tidak bisa dijadikan default.

Bernardo Vale
sumber
related: stackoverflow.com/questions/19614027/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Jawaban:

193

Anda dapat menggunakan Jinja default:

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"
tedder42
sumber
10
Dan jika variabel default bergantung pada variabel lain. Misalnya default('/home/' {{ anothervar }}), apakah ada cara untuk menggabungkan nilai-nilai itu?
Bernardo Vale
8
Hapus saja 'sekitar default_valuedan itu akan menggunakan variabel yang disebut default_value
dagonza
7
Tidak berfungsi jika variabel bersarang seperti {{ dict.key | default(5) }}. Ini akan gagal jika dicttidak ditentukan.
Jordan Stewart
1
FYI, ini sekarang akan memunculkan kesalahan:[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}.
bryan kennedy
1
@ JordanStewart Saya memiliki kasus yang sama - dengan variabel bersarang. Saya memposting jawaban dengan kemungkinan solusi di bawah ini.
Roman Kruglov
11

Tidak sepenuhnya terkait, tetapi Anda juga dapat memeriksa kedua variabel undefinedDAN empty(misalnya my_variable:). (CATATAN: hanya bekerja dengan versi yang memungkinkan> 1.9, lihat: tautan )

- name: Create user
  user:
    name: "{{ ((my_variable == None) | ternary('default_value', my_variable)) \
    if my_variable is defined else 'default_value' }}"
Tommy Nguyen
sumber
2
Ini bagus, sangat berguna.
eagle33322
5

Jika ada yang mencari opsi yang menangani variabel bersarang, ada beberapa opsi seperti itu dalam masalah github ini .

Singkatnya, Anda perlu menggunakan filter "default" untuk setiap tingkat vars bertingkat. Untuk variabel "a.nested.var" akan terlihat seperti ini:

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

atau Anda dapat menyetel nilai default dari dicts kosong untuk setiap level vars, mungkin menggunakan filter "gabungkan". Atau gunakan filter "json_query". Tetapi opsi yang saya pilih tampaknya lebih sederhana bagi saya jika Anda hanya memiliki satu tingkat bersarang.

Roman Kruglov
sumber
4

Jika Anda memiliki satu permainan yang ingin Anda putar di atas item, tentukan daftar itu di group_vars / all atau di tempat lain yang masuk akal:

all_items:
  - first
  - second
  - third
  - fourth

Maka tugas Anda akan terlihat seperti ini:

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

Teruskan varlist sebagai array JSON:

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

Sebelum itu, Anda mungkin juga menginginkan tugas yang memeriksa bahwa setiap item di varlist juga ada di 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) }}"
Mendongkrak
sumber
3

Jika Anda menggunakan pencarian untuk menyetel baca default dari lingkungan, Anda juga telah menyetel parameter kedua dari default ke true:

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

Anda juga dapat menggabungkan beberapa definisi default:

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

Pertanyaannya sudah cukup lama, tapi bagaimana dengan:

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

Sepertinya tidak terlalu merepotkan bagiku ...

pshunter.dll
sumber
1

Jika Anda menetapkan nilai default untuk fakta boolean, pastikan tidak ada tanda kutip yang digunakan di dalam default ().

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

Untuk variabel lain digunakan metode yang sama yang diberikan dalam jawaban terverifikasi.

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