Ansible-변수가 정의되지 않은 경우 기본값 사용


101

users내 역할 내에서 Linux 생성을 사용자 정의하고 있습니다 . 내 역할 사용자 정의 사용자에게 알려야합니다 home_directory, group_name, name, password.

기본값에 대처하는 더 유연한 방법이 있는지 궁금합니다.

아래 코드가 가능하다는 것을 알고 있습니다.

- 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

그러나 내가 언급했듯이, 많은 선택적 변수가 있으며 이것은 많은 가능성을 만듭니다.

위의 코드와 같은 것이 있습니까?

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

정의되지 않은 name="default_name"경우 코드를 설정해야합니다 my_variable.

모든 변수를 설정 defaults/main.yml하고 다음과 같이 사용자를 만들 수 있습니다.

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

하지만 그 변수들은 정말 큰 해시 안에 있고 그 해시 안에는 기본값이 될 수없는 해시들이 있습니다.


답변:


192

Jinja의 default다음을 사용할 수 있습니다 .

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

10
그리고 기본 변수가 다른 변수에 의존하는 경우. 예를 들어 default('/home/' {{ anothervar }}), 이러한 값을 연결하는 방법이 있습니까?
Bernardo Vale

8
주변의 '를 제거하면 default_valuedefault_value라는 변수가 사용됩니다
dagonza

7
변수가와 같이 중첩 된 경우 작동하지 않습니다 {{ dict.key | default(5) }}. dict정의되지 않은 경우 실패합니다 .
Jordan Stewart 19

1
참고로, 이제 오류가 발생합니다.[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}.
bryan kennedy

1
@JordanStewart 나는 중첩 변수로 같은 경우를 가졌습니다. 아래에 가능한 해결책과 함께 답변을 게시했습니다.
Roman Kruglov

11

완전히 관련되지는 않지만 undefinedAND empty(예 :) my_variable:변수 를 모두 확인할 수도 있습니다 . (참고 : ansible 버전> 1.9에서만 작동합니다. 참조 : 링크 )

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

2
이것은 훌륭하고 매우 유용합니다.
eagle33322

5

중첩 된 변수를 처리하는 옵션을 찾는 사람이 있다면이 github 문제 에 이러한 옵션이 몇 가지 있습니다 .

즉, 중첩 된 변수의 모든 수준에 대해 "기본"필터를 사용해야합니다. "a.nested.var"변수의 경우 다음과 같습니다.

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

또는 "combine"필터를 사용하여 각 수준의 var에 대해 빈 딕셔너리의 기본값을 설정할 수 있습니다. 또는 "json_query"필터를 사용하십시오. 그러나 내가 선택한 옵션은 중첩 수준이 하나 뿐인 경우 더 간단 해 보입니다.


4

항목에 대해 반복하려는 단일 플레이가있는 경우 해당 목록을 group_vars / all 또는 다른 곳에 정의하십시오.

all_items:
  - first
  - second
  - third
  - fourth

그러면 작업은 다음과 같이 보일 수 있습니다.

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

varlist를 JSON 배열로 전달합니다.

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

그 이전에, 당신은 또한 작업을 할 수도 있다는 점에서 각 항목에 있음을 확인 varlist가 에 또한 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

조회를 사용하여 환경에서 기본 읽기를 설정하는 경우 default의 두 번째 매개 변수도 true로 설정했습니다.

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

여러 기본 정의를 연결할 수도 있습니다.

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

1

질문은 꽤 오래되었지만 어떨까요?

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

덜 번거로워 보입니다 ...


1

부울 팩트에 기본값을 할당하는 경우 default () 내부에 따옴표가 사용되지 않았는지 확인하십시오.

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

다른 변수의 경우 확인 된 답변에 제공된 동일한 방법을 사용했습니다.

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.