(関連 コールバックまたはフック、および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構成ファイルについて考えてください。
+
を使用して、変数内の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 }}"
ロールがいずれかのテストサーバーで実行されると、追加の拡張機能が追加されます。
これがディクショナリでも機能するかどうかはわかりません。また、スペースに注意し、行末にぶら下がりカンマを残してください。
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
ループを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}}
わからないwhen彼らはこれを追加しましたが、少なくとも辞書/ハッシュ(リスト/配列ではない)では、変数 hash_behaviour のように:hash_behaviour = merge
あなたのansible.cfg
。
誤ってこの設定に偶然出会うまでにかなりの数時間かかった:S
ここでのほとんどすべての回答にはタスクの変更が必要ですが、実行中ではなく、vars定義の辞書を動的にマージする必要がありました。
例えば。いくつかの共有変数をall
group_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つの辞書にマージすることも可能だと思います。
このアプローチの利点は、変数名の正確なリストを設定する必要がなく、パターンとユーザーだけが動的に設定できることです。