Ansible - Bir değişken tanımlanmamışsa varsayılanı kullanın


105

Rolüm usersiçinde linux yaratmayı özelleştiriyorum . Benim rol özelleştirmek kullanıcılarını izin gerekiyor home_directory, group_name, name, password.

Varsayılan değerlerle başa çıkmanın daha esnek bir yolu olup olmadığını merak ediyordum.

Aşağıdaki kodun mümkün olduğunu biliyorum:

- 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

Ama bahsettiğim gibi, birçok isteğe bağlı değişken var ve bu pek çok olasılık yaratıyor.

Yukarıdaki kod gibi bir şey var mı?

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

Kod, tanımlanmadığı name="default_name"zaman ayarlanmalıdır my_variable.

Tüm değişkenleri ayarlayabilir defaults/main.ymlve kullanıcıyı şu şekilde oluşturabilirim:

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

Ancak bu değişkenler gerçekten büyük bir karmanın içindedir ve bu karmanın içinde varsayılan olamayacak bazı karmalar vardır.


Yanıtlar:


199

Jinja'yı kullanabilirsiniz default:

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

10
Ve varsayılan değişken başka bir değişkene bağlıysa. Örneğin default('/home/' {{ anothervar }}), bu değerleri birleştirmenin bir yolu var mı?
Bernardo Vale

8
Sadece 'etrafındaki' default_value
kısmını

7
Değişken gibi iç içe geçmişse çalışmaz {{ dict.key | default(5) }}. dictTanımsızsa başarısız olur .
Jordan Stewart

1
Bilginize, bu şimdi bir hataya neden olacak:[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}.
bryan kennedy

1
@JordanStewart Aynı durum vardı - iç içe değişkenlerle. Aşağıda olası çözümlerle bir cevap gönderdim.
Roman Kruglov

12

Tamamen ilişkili değildir, ancak hem undefinedAND empty(örneğin my_variable:) değişkenini de kontrol edebilirsiniz . (NOT: yalnızca yanıtlanabilir sürüm> 1.9 ile çalışır, bkz: bağlantı )

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

2
Bu harika, çok kullanışlı.
eagle33322

6

İç içe geçmiş değişkenleri işleyen bir seçenek arayanlar varsa, bu github konusunda bu tür birkaç seçenek vardır .

Kısacası, iç içe geçmiş değişkenlerin her düzeyi için "varsayılan" filtre kullanmanız gerekir. Bir "a.nested.var" değişkeni için şöyle görünür:

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

ya da her değişken düzeyi için boş dicts varsayılan değerleri ayarlayabilirsiniz, belki "birleştirme" filtresi kullanarak. Veya "json_query" filtresini kullanın. Ancak, yalnızca tek bir yuvalama düzeyiniz varsa, seçtiğim seçenek bana daha basit görünüyor.


5

Öğeler üzerinde döngü yapmak istediğiniz tek bir oyununuz varsa, o listeyi group_vars / all veya mantıklı olan başka bir yerde tanımlayın:

all_items:
  - first
  - second
  - third
  - fourth

O zaman görevin şöyle görünebilir:

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

Varlist'i JSON dizisi olarak geçirin:

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

Bunun öncesinde, aynı zamanda bir görevi isteyebileceği her öğe olmadığını kontrol eder varlist içinde 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) }}"

4

Ortamdan varsayılan okumayı ayarlamak için arama kullanıyorsanız, varsayılanın ikinci parametresini de true olarak ayarlamış olursunuz:

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

Ayrıca birden çok varsayılan tanımı birleştirebilirsiniz:

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

2

Soru oldukça eski, peki ya:

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

Bana daha az hantal görünüyor ...


1

Boole gerçeği için varsayılan değer atıyorsanız, default () içinde tırnak işareti kullanılmadığından emin olun.

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

Diğer değişkenler için, doğrulanmış yanıtta verilen aynı yöntemi kullandı.

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.