As rookie

ルーキーインフラエンジニアがインフラのこと以外も結構書いてしまうブログ

ansibleで多重ループ subelements編 (7日坊主)

  • この記事はsolo_advent_calender 2016年12月7日のものです。

こんにちは ショート advent calender7日目です。

今回は6日目で軽くふれていたansibleのloop構文with_subelements を使っていきます。

mokicks.hatenablog.com

公式サイト Loops — Ansible Documentation

まずはvarsファイルを用意します。

# group_vars/all
yum_list
  - state: present
    package:
      - vim
      - unzip
  - state: latest
    package:
      - nginx
      - bind-utils

以前の記事とは違い一つのディクショナリを用意するだけで大丈夫そうです。 JSONだと

{ yum_list: [ { state: present, package: [ vim, unzip ] }, { state: latest, package: [ nginx, bind-utils ] } }

こういう感じです。

yumモジュールで vimunzip はstateをpresentで実行しnginxbind-utils はstateをlatestで実行するようになる予定です。

それに対応したtaskがこちら

# tasks/main.yml
---
- name: install by yum
  yum: name={{ item.1 }} state={{ item.0.state }}
  with_subelements:
    - "{{ yum_list }}"
    - package

with_subelements は与えられたリストを順に展開し,ネストされたリストのキーを判定しその値を使います。

展開して取り出した値を扱いたい場合は {{ item.0 }} {{ item.1 }} のように与えた順に指定します。

流れを書くと

まず

  - state: present
    package:
      - vim
      - unzip

で一回目のloopでこの値を渡します。

次に、 {{ item.1 }}でpackageの中身であるvimunzip を順に取り出します。

{{ item.0.state }} でstateのpresentが取り出されれます。

上記のpackageのループが終わると

  - state: latest
    package:
      - nginx
      - bind-utils

の値を渡します。

実行結果は以下のようになりました

TASK [loop_test : install by yum] **********************************************
ok: [vagrant] => (item=({u'state': u'present'}, u'vim'))
ok: [vagrant] => (item=({u'state': u'present'}, u'unzip'))
ok: [vagrant] => (item=({u'state': u'latest'}, u'nginx'))
ok: [vagrant] => (item=({u'state': u'latest'}, u'bind-utils'))

ネストされているものでループしたいときはこのようにwith_subelements を使うのが良いでしょう

以上