web-dev-qa-db-ja.com

リストへの追加またはAnsibleの辞書へのキーの追加

(関連 コールバックまたはフック、およびAnsibleロールでの再利用可能な一連のタスク ):

リストに追加したり、Ansibleのディクショナリにキーを追加したりするのに、jina2テンプレート式を使用する(ab)よりも良い方法はありますか?

私はあなたが次のようなことができることを知っています:

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

しかし、これを行うためのメタタスクやヘルパーは本当にありませんか?

それは壊れやすく、ドキュメント化されていないようで、Ansibleでの変数の動作に関する多くの仮定に依存しています。

私の使用例は、それぞれが基本の役割(データベースサーバー)に構成を提供する必要がある複数の役割(データベースサーバー拡張)です。 dbサーバー設定ファイルに行を追加するほど簡単ではありません。各変更は、同じ行に適用されます。拡張子bdrおよびpg_stat_statementsは両方ともターゲット行に表示する必要があります:

shared_preload_libaries = 'bdr, pg_stat_statements'

これを行うAnsibleの方法は、現在の値を抽出し、それを解析してから再書き込みする正規表現を使用して、構成ファイルを複数回(拡張子ごとに1回)処理するだけですか?もしそうなら、どのようにしてその実行を複数の実行にわたってべき等にするのですか?

構成がこれよりも解析が難しく、コンマ区切りの別の値を追加するほど簡単ではない場合はどうなりますか? XML構成ファイルについて考えてください。

39
Craig Ringer

+を使用して、変数内の2つのリストをマージできます。次の内容の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 }}"

ロールがいずれかのテストサーバーで実行されると、追加の拡張機能が追加されます。

これがディクショナリでも機能するかどうかはわかりません。また、スペースに注意し、行末にぶら下がりカンマを残してください。

16
GnP

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

42
Max Kovgan

ループを2つに分割する必要があります

 --- 
-ホスト:localhost 
タスク:
-include_vars:スタック
-set_facts:roles = {{stacks.Roles | split( '')}} 
-インクルード:addhost.yml 
 with_items: "{{roles}}" 

そしてaddhost.yml

-set_facts:groupname = {{item}} 
-set_facts:ips = {{stacks [item] | split( '')}} 
-local_action:add_Host hostname = {{item}} groupname = {{groupname}} 
 with_items:{{ips}} 
3
Arthur Tsang

わからないwhen彼らはこれを追加しましたが、少なくとも辞書/ハッシュ(リスト/配列ではない)では、変数 hash_behaviour のように:hash_behaviour = mergeあなたのansible.cfg

誤ってこの設定に偶然出会うまでにかなりの数時間かかった:S

1
nuts

ここでのほとんどすべての回答にはタスクの変更が必要ですが、実行中ではなく、vars定義の辞書を動的にマージする必要がありました。

例えば。いくつかの共有変数をallgroup_varsで定義してから、他のgroupまたはHost_varsで拡張したいと思います。役割を扱うときに非常に役立ちます。

combineまたはunionフィルターを使用してvarファイルの元の変数を上書きしようとすると、テンプレート化中に無限ループで終了するため、この回避策を作成しました(解決策ではありません)。

いくつかの名前パターンに基づいて複数の変数を定義し、それらをロールに自動的にロードできます。

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'、 '')は、ansible 2.8以降で使用できます。

同じルックアップを使用して、ランタイム中にすべての変数dictionary_of_bla.*を1つの辞書にマージすることも可能だと思います。

このアプローチの利点は、変数名の正確なリストを設定する必要がなく、パターンとユーザーだけが動的に設定できることです。

0
VeselaHouba