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


34

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

jina2テンプレート式を使用する(ab)よりも、リストに追加するか、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'

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

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


わかってる?副作用の多いジブのカットが好きです
☺– DomQ

回答:


13

を使用して、変数内の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 }}"

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

これが辞書でも機能するかどうかはわかりませんが、スペースに注意し、行末にぶら下がりコンマを残してください。


できますが、すべてを行う必要がgroup_varsあり、ロールは拡張機能自体の設定の詳細を処理できません。私が特に探しているロールから変数を追加しているので、あるロールが別のロールによって公開された変数に追加できます。
クレイグリンガー

基本ロールは各拡張ロールについて知っていますか?同様のケースで、連結をwith_items文に任せることができました。
GnP

いいえ、それが本当に問題です。ある展開では、基本的な役割は次のようになります
クレイグリンガー

4
2つのリストを連結するためにこれを行おうとすると、左側も右側にあるため、無限再帰テンプレートであると考えられます。これの使い方を誤解していますか?
イブラヒム

2
@spectras少なくともAnsible 2.7では、これは機能しません。Ibrahimが示唆したように、これによりエラーが発生します:「テンプレート文字列で再帰ループが検出されました」。
-rluba

35

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。ansibleで動作していないことに気づいた2.4.x(修正済み)
Max Kovgan

ユースケース#4に従って、私のシナリオで未定義のエラーを処理するためにデフォルト値を追加しました:set_fact: my_dict_var: '{{my_dict_var|default({})|combine({item[0]: item[1]})}}'。未定義のエラーは、何らかのフィルタリングが使用されるか、結果が登録されていない場合に発生します。
SKベンカット

SK Venkat氏、ここのサンプルコードは、非常に具体的なこと(タプルからの辞書項目の追加)のみを示しています。他に何かをする必要がある場合、このコードはコピーアンドペーストではありません。
マックスコフガン

3

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

--- 
-ホスト:localhost
  タスク: 
    -include_vars:スタック
    -set_facts:roles = {{stacks.Roles | スプリット(' ')}}
    -含める: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}}

1

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

偶然この設定につまずくために私はかなりの時間を取った:S


これは非常に便利ですが、既存のコードベースでe2eを有効にすることに注意してください。卵を壊すかもしれません。
マックスコフガン

0

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

例えば私は、いくつかの共有VARSを定義したいall group_varsと、私はいくつかの他に、それらを拡張しますgrouphost_vars。ロールで作業するときに非常に便利です。

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

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

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つの辞書にマージすることも可能だと思います。

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


-4

Ansibleは自動化システムであり、構成ファイルの管理に関しては、とはそれほど変わりませんapt。ますます多くのソフトウェアがconf.dディレクトリから構成スニペットを読み取る機能を提供する理由は、そのような自動化システムがソフトウェアに構成を追加するさまざまなパッケージ/ロールを持つようにするためです。私は、あなたが考えていることをするという哲学ではなくAnsibleconf.dトリックを使用することを信じています。構成中のソフトウェアがこの機能を提供しない場合、問題が発生している可能性があります。

あなたはXML構成ファイルについて言及しているので、私はこの機会を利用してちょっとしたことをします。プレーンテキストの構成ファイルを使用するというUnixの伝統には理由があります。バイナリ構成ファイルはシステムの自動化にはあまり適していないため、どのようなバイナリ形式でも問題が発生し、構成を処理するプログラムを作成する必要があります。(XMLがプレーンテキスト形式であると考える人は、脳を検査する必要があります。)

さて、あなたの特定のPostgreSQL問題について。トリックをPostgreSQLサポートしconf.dます。最初に、shared_preload_libraries複数回指定できるかどうかを確認します。私はそれができるドキュメントにヒントを見つけませんでしたが、私はまだそれを試してみました。複数回指定できないPostgreSQL場合は、アイデアがある場合に備えて、問題を説明します。これはPostgreSQL問題であり、問題ではありませんAnsible。解決策がなく、異なる役割を実際に1つに統合できなかった場合は、管理対象ホストで構成をコンパイルするシステムを実装します。この場合、私はおそらく、スクリプトを作成したい/usr/local/sbin/update_postgresql_configコンパイルう/etc/postgresql/postgresql.conf.jinjaにします/etc/postgresql/9.x/main/postgresql.conf。スクリプトは、共有プリロードライブラリをから読み込み、/etc/postgresql/shared_preload_libraries.txt1行につき1つのライブラリを作成し、それらをjinjaに提供します。

自動化システムがこれを行うことは珍しくありません。例はDebian exim4パッケージです。


PostgreSQLはconf.dインクルードメカニズムをサポートし、ありがたいことにプレーンテキストファイルを使用します。ただし、複数の拡張機能がそれについて意見を持つ可能性のあるいくつかの構成オプションがあります。たとえば、「max_wal_sendersを以前のものから10増やします」。
クレイグリンガー

4
構成管理システムの制限を回避するためにアプリケーションを変更する必要がある、または再利用可能な役割をあきらめる必要があると言っているようです。
クレイグリンガー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.