Ansible에서 사전에 목록에 추가하거나 키를 추가


33

( Ansible 역할의 콜백 또는 후크 및 재사용 가능한 일련의 작업과 관련됨 ) :

jina2 템플릿 표현식을 사용하는 것보다 목록에 추가하거나 Ansible의 사전에 키를 추가하는 더 좋은 방법이 있습니까?

나는 당신이 다음과 같은 것을 할 수 있다는 것을 알고 있습니다 :

- name: this is a hack
  shell: echo "{% originalvar.append('x') %}New value of originalvar is {{originalvar}}"

그러나 실제로 이런 종류의 메타 작업이나 도우미가 있습니까?

깨지기 쉽고 문서화되지 않은 것으로 보이며 Ansible에서 변수가 어떻게 작동하는지에 대한 많은 가정에 의존합니다.

필자의 유스 케이스는 각각 기본 역할 (데이터베이스 서버)에 일부 구성을 제공해야하는 여러 역할 (데이터베이스 서버 확장)입니다. db 서버 설정 파일에 줄을 추가하는 것만 큼 간단하지 않습니다. 각 변경은 적용 같은 라인 , 예를 들어, 확장 bdrpg_stat_statements모두 대상 행에 표시해야합니다

shared_preload_libaries = 'bdr, pg_stat_statements'

현재 값을 추출하고 구문 분석 한 다음 다시 쓰는 정규 표현식으로 구성 파일을 여러 번 (확장 당 한 번) 처리하기 위해이 작업을 수행 할 수 있습니까? 그렇다면 여러 실행에서 어떻게 i 등식을 만드는가?

설정을 구문 분석하기가 어렵고 쉼표로 구분 된 다른 값을 추가하는 것만 큼 간단하지 않은 경우 어떻게해야합니까? XML 구성 파일을 생각하십시오.


그거 알아? 나는 당신의 부작용이 많은 지브의 컷을 좋아합니다 ☺
DomQ

답변:


13

변수로 두 목록을와 병합 할 수 있습니다 +. group_vars이 내용 의 파일이 있다고 가정 해보십시오 .

---
# group_vars/all
pgsql_extensions:
  - ext1
  - ext2
  - ext3

그리고 다음 pgsql.conf.j2과 같은 템플릿에서 사용됩니다 .

# {{ ansible_managed }}
pgsql_extensions={% for item in pgsql_extensions %}{{ item }}, {% endfor %}

그런 다음 다음과 같이 테스트 데이터베이스 서버에 확장을 추가 할 수 있습니다.

---
# group_vars/testing_db
append_exts:
  - ext4
  - ext5
pgsql_extensions: "{{ pgsql_extensions + append_exts }}"

테스트 서버에서 역할을 실행하면 추가 확장이 추가됩니다.

나는 이것이 사전에도 효과가 있는지 확신하지 못하고 공백에주의하고 줄 끝에 매달려있는 쉼표를 남겨 둡니다.


할 수는 있지만 모든 작업을 수행해야합니다 group_vars. 역할은 확장 프로그램 자체 설정에 대한 세부 정보를 처리 할 수 ​​없습니다. 그것은의 추기은 바르 역할 한 역할은 다른 역할에 의해 노출 된 VAR에 추가 할 수 있습니다, 나는 특히 찾고 있어요 것이다.
Craig Ringer

기본 역할이 각 확장 역할에 대해 알고 있습니까? 나는 연결을 with_items문장 으로 남겨 둘 수있는 비슷한 경우를 가졌다 .
GnP

아니, 그건 정말 문제입니다. 한 배포에서 기본 역할은 al 일 수 있습니다
Craig Ringer

4
두 목록을 연결하기 위해이 작업을 수행하려고하면 왼쪽도 오른쪽에 있기 때문에 무한 재귀 템플릿이라고 생각합니다. 이것을 사용하는 방법을 오해하고 있습니까?
Ibrahim

2
@spectras 적어도 Ansible 2.7부터는 작동하지 않습니다. 이브라힘이 제안한대로 "템플릿 문자열에서 재귀 루프가 발견되었습니다"라는 오류가 발생합니다.
rluba

33

Ansible v2.x부터 다음을 수행 할 수 있습니다.

# use case I: appending to LIST variable:

      - name: my appender
        set_fact:
          my_list_var: '{{my_list_myvar + new_items_list}}'

# use case II: appending to LIST variable one by one:

      - name: my appender
        set_fact:
          my_list_var: '{{my_list_var + [item]}}'
        with_items: '{{my_new_items|list}}'

# use case III: appending more keys DICT variable in a "batch":

      - name: my appender
        set_fact:
          my_dict_var: '{{my_dict_var|combine(my_new_keys_in_a_dict)}}'

# use case IV: appending keys DICT variable one by one from tuples
      - name: setup list of tuples (for 2.4.x and up
        set_fact:
          lot: >
            [('key1', 'value1',), ('key2', 'value2',), ..., ('keyN', 'valueN',)],
      - name: my appender
        set_fact:
          my_dict_var: '{{my_dict_var|combine({item[0]: item[1]})}}'
        with_items: '{{lot}}'
# use case V: appending keys DICT variable one by one from list of dicts (thanks to @ssc)

  - name: add new key / value pairs to dict
    set_fact:
      my_dict_var: "{{ my_dict_var | combine({item.key: item.value}) }}"
    with_items:
    - { key: 'key01', value: 'value 01' }
    - { key: 'key02', value: 'value 03' }
    - { key: 'key03', value: 'value 04' }

위의 모든 내용은 http://docs.ansible.com/ansible/playbooks_filters.html에 설명되어 있습니다.


1
유스 케이스 IV에 추가u'(': u\"'\"}"
ssc

1
감사합니다, @ssc. 나는 그것이 2.4.x(FIXED) ansible (FIXED) 와 작동하지 않는 것으로 나타났습니다
Max Kovgan

유스 케이스 # 4에 따르면 시나리오에서 정의되지 않은 오류 를 처리하기 위해 기본값을 추가했습니다 set_fact: my_dict_var: '{{my_dict_var|default({})|combine({item[0]: item[1]})}}'. 일부 필터링이 사용되거나 결과가 등록되지 않은 경우 정의되지 않은 오류가 발생합니다.
SK Venkat

여기 샘플 코드 인 SK Venkat은 매우 구체적인 것을 보여줍니다 (튜플에서 사전 항목 추가). 다른 작업이 필요한 경우이 코드는 복사하여 붙여 넣기가 아닙니다.
Max Kovgan

3

루프를 2로 분할해야합니다

--- 
-호스트 : localhost
  작업 : 
    -include_vars : 스택
    -set_facts : 역할 = {{stacks.Roles | split ( '')}}
    -include : addhost.yml
      with_items : "{{roles}}"

그리고 addhost.yml

-set_facts : 그룹 이름 = {{item}}
-set_facts : ips = {{stacks [item] | split ( '')}}
-local_action : add_host 호스트 이름 = {{item}} groupname = {{groupname}}
  with_items : {{ips}}

1

이들이 언제 추가 했는지 확실하지 않지만 적어도 사전 / 해시 (목록 / 배열 아님)의 경우 변수 hash_behaviour 를 다음과 같이 설정할 수 hash_behaviour = merge있습니다 ansible.cfg.

실수 로이 설정을 우연히 발견하기까지 몇 시간이 걸렸습니다.


이것은 매우 편리하지만 기존 코드베이스에서 e2e를 사용할 수 있도록주의하십시오. 계란이 부러 질 수 있습니다.
Max Kovgan

0

여기의 거의 모든 대답에는 작업 변경이 필요하지만 실행 중에가 아니라 사전을 vars 정의에 동적으로 병합해야했습니다.

예 : 나는 몇 가지 공유 바르를 정의하려면 all group_vars다음 나는 다른 그들을 확장 할 grouphost_vars. 역할을 수행 할 때 매우 유용합니다.

당신이 사용하려고하는 경우 combine또는 unionVAR 파일의 원래 변수를 덮어 쓰기 필터를 내가이 해결 방법을 만들 수 있도록, 당신은 (그것이 해결책이 아니다), 템플릿 동안 무한 루프에 종료됩니다.

일부 이름 패턴을 기반으로 여러 변수를 정의한 다음 자동으로 역할에로드 할 수 있습니다.

group_vars/all.yml

dictionary_of_bla:
  - name: blabla
    value1 : blabla
    value2 : blabla

group_vars/group1.yml

dictionary_of_bla_group1:
  - name: blabla2
    value1 : blabla2
    value2 : blabla2

역할 코드 스 니펫

tasks:
  - name: Run for all dictionary_of_bla.* variations
    include_tasks: do_some_stuff.yml
    with_items: "{{ lookup('varnames','dictionary_of_bla.*').split(',') }}"
    loop_control:
      loop_var: _dictionary_of_bla

do_some_stuff.yml

- name: do magic
  magic:
    trick_name: item.name
    trick_value1: item.value1
    trick_value2: item.value2
  with_items: "{{ vars[_dictionary_of_bla] }}"

스 니펫 일뿐이지만 작동 방식에 대한 아이디어를 얻어야합니다. 참고 : lookup ( 'varnames', '')은 2.8부터 사용할 수 있습니다.

dictionary_of_bla.*런타임 중에 동일한 조회를 사용하여 모든 변수 를 하나의 사전 에 병합하는 것이 가능할 것 입니다.

이 방법의 장점은 정확한 변수 이름 목록을 설정할 필요는 없지만 패턴과 사용자 만 동적으로 설정할 수 있다는 것입니다.


-4

Ansible는 자동화 시스템이며 구성 파일 관리와 관련하여 크게 다르지 않습니다 apt. 점점 더 많은 소프트웨어가 conf.d디렉토리 에서 구성 스 니펫을 읽는 기능을 제공하는 이유 는 그러한 자동화 시스템이 다른 패키지 / 역할이 소프트웨어에 구성을 추가하도록 할 수 있기 때문입니다. 나는 당신이 생각하는 것을하는 것이 아니라 Ansibleconf.d트릭 을 사용하는 것이 철학이라고 믿습니다 . 구성중인 소프트웨어가이 기능을 제공하지 않으면 문제가있을 수 있습니다.

XML 구성 파일을 언급 했으므로 약간의 기발한 기회가 있습니다. 일반 텍스트 구성 파일을 사용하는 유닉스 전통에는 이유가 있습니다. 이진 구성 파일은 시스템 자동화에 적합하지 않으므로 모든 종류의 이진 형식으로 인해 문제가 발생할 수 있으며 구성을 처리 할 프로그램을 만들어야합니다. (누구나 XML이 일반 텍스트 형식이라고 생각하면 두뇌 검사를 받아야한다.)

이제 특정 PostgreSQL문제에 대해 트릭을 PostgreSQL지원하지 않습니다 conf.d. 먼저 shared_preload_libraries여러 번 지정할 수 있는지 확인합니다 . 설명서에서 힌트를 찾을 수는 없지만 여전히 시도해 볼 것입니다. 여러 번 지정할 수 없으면 PostgreSQL아이디어가있는 경우 내 문제를 설명합니다 . 이것은 PostgreSQL문제가 아니라 Ansible문제입니다. 솔루션이없고 다른 역할을 하나로 병합 할 수없는 경우 관리 호스트에서 구성을 컴파일하는 시스템을 구현했습니다. 이 경우 아마도 로 /usr/local/sbin/update_postgresql_config컴파일 되는 스크립트 를 작성했을 것입니다 . 스크립트는에서 공유 사전로드 라이브러리를 한 줄에 하나씩 라이브러리를 읽고 jinja에 제공합니다./etc/postgresql/postgresql.conf.jinja/etc/postgresql/9.x/main/postgresql.conf/etc/postgresql/shared_preload_libraries.txt

자동화 시스템이이를 수행하는 것은 드문 일이 아닙니다. 데비안 exim4패키지 가 그 예입니다 .


PostgreSQL은 conf.d포함 메커니즘을 지원 하며 고맙게도 일반 텍스트 파일을 사용합니다. 그러나 여러 확장에 대한 의견이있을 수있는 몇 가지 구성 옵션이 있습니다 (예 : "max_wal_senders를 이전보다 10 배 증가").
Craig Ringer

4
구성 관리 시스템의 제한 사항을 해결하도록 응용 프로그램을 변경해야하거나 재사용 가능한 역할을 포기해야한다고 말하고있는 것 같습니다.
Craig Ringer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.