ITよろづや

ITから生活の参考になる情報を備忘録代わりに残していきます

Ansible with_itemsで複数のサブリストを変数の別ファイルから参照するループ処理

Ansible with_itemsで複数のサブリストを変数の別ファイルから参照するループ処理について、調べていたのですが、以下のサイトの情報を参考にうまく動作しました。

 

Ansibleでwith_itemsを使って複数のサブリストを使っていると、同一のファイルがだんだんと長い文になってきて、変数を別ファイルに持たせて参照させたいけど、書き方が分からなくて参考にしました。

 

情報元はこちら。

yaml - ansible with_items list of lists is flattening - Stack Overflow

 

ansibleを使って、リストのリストをループさせて、いくつかのパッケージをインストールしようとしています。しかし、{{item}}はサブリスト自体ではなく、サブリストのすべての要素を返します。ansibleの外からマニフェストリストから来るyamlファイルがあり、それは次のようなものです。

 

---
modules:
 - ['module','version','extra']
 - ['module2','version','extra']
 - ['module3','version','extra']

 

私のタスクは次のようなものです。

 

task:
 - include_vars: /path/to/external/file.yml
 - name: install modules
   yum: name={{item.0}} state=installed
   with_items: "{{ modules }}"

 

それを実行すると、次のようになります。

 

fatal: [localhost]: FAILED! => {"failed": true, "msg": "ERROR! int object has no element 0"}


試しにやってみると

 

- debug: msg="{{item}}"
  with_items: "{{module}}"

 

サブリストだけではなく、すべての要素(モジュール、バージョン、エキストラなど)が表示されます(これは私が期待していることです)。

 

 

この問題を解決する別の方法は、リストのリストの代わりに複雑なアイテムを使用することです。次のように変数を構成します。

 

- modules:
  - {name: module1, version: version1, info: extra1}
  - {name: module2, version: version2, info: extra2}
  - {name: module3, version: version3, info: extra3}

 

その後with_items、次のように、引き続き使用できます。

 

- name: Printing Stuffs...
  shell: echo This is "{{ item.name }}", "{{ item.version }}" and "{{ item.info }}"
  with_items: "{{modules}}"

 

とここまでが引用ですが、

 

実際に実行ファイルに、

 

   with_items: "{{ modules }}"

 

そして、変数を格納したファイルに、

 

modules:
  - {name: module1, version: version1, info: extra1}
  - {name: module2, version: version2, info: extra2}
  - {name: module3, version: version3, info: extra3}

 

でいけました。

 

Ansible構築・運用ガイドブック インフラ自動化のための現場のノウハウ (Compass Books)