Ansible: リストへ動的に要素を追加する

はじめに

Playbookを書いていると、情報取得のキーとなるリストを変数として定義し、各キーで取得できたデータを変換・加工した後に再度それらのリスト作る、なんていう場面がよくあると思います。

今回は、APIから情報を取得するケースでこれらのPlaybookを考えてみます。

実装

基本方針としては繰り返しとなる処理部分を共通化して別タスクとして切り出します。共通処理部分では

  • データ取得
  • (必要に応じて)データ変換・加工
  • リストへの追加

という流れでリストへ要素を追加します。このため、共通化処理の呼び出し元では要素を追加するリスト変数の初期化を忘れず行います。まずは Playbookです。

site_dynamic_appending_elem.yml

---
- name: Append data to a list dynamically
  hosts: localhost
  vars:
    api_endpoint: "https://fakerestapi.azurewebsites.net/api/v1"
    book_ids: [1, 2, 3, 4]
  tasks:
    - name: Initialize variable
      ansible.builtin.set_fact:
        _book_titles: []

    - name: Fetch book title list
      ansible.builtin.include_tasks: inner_loop.yml
      loop: "{{ book_ids }}"
      loop_control:
        loop_var: _book_id

    - name: Show list generated dynamcally
      ansible.builtin.debug:
        var: _book_titles

次にPlaybook から呼び出されるタスクファイルです。

inner_loop.yml

---
- name: Append data to a list dynamically
  hosts: localhost
  vars:
    api_endpoint: "https://fakerestapi.azurewebsites.net/api/v1"
    book_ids: [1, 2, 3, 4]
  tasks:
    - name: Initialize variable
      ansible.builtin.set_fact:
        _book_titles: []

    - name: Fetch book title list
      ansible.builtin.include_tasks: inner_loop.yml
      loop: "{{ book_ids }}"
      loop_control:
        loop_var: _book_id

    - name: Show list generated dynamcally
      ansible.builtin.debug:
        var: _book_titles

実行結果

PLAY [Append data to a list dynamically] *******************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Initialize variable] *********************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Fetch book title list] *******************************************************************************************************************************************************************************************************************************
included: /Users/k-boo/t/ansible/loop/inner_loop.yml for localhost => (item=1)
included: /Users/k-boo/t/ansible/loop/inner_loop.yml for localhost => (item=2)
included: /Users/k-boo/t/ansible/loop/inner_loop.yml for localhost => (item=3)
included: /Users/k-boo/t/ansible/loop/inner_loop.yml for localhost => (item=4)

TASK [Fetch Book info] *************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show title in  API response] *************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Book 1"
}

TASK [Append the book title to list] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Fetch Book info] *************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show title in  API response] *************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Book 2"
}

TASK [Append the book title to list] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Fetch Book info] *************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show title in  API response] *************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Book 3"
}

TASK [Append the book title to list] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Fetch Book info] *************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show title in  API response] *************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Book 4"
}

TASK [Append the book title to list] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show list generated dynamcally] **********************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "_book_titles": [
        "Book 1",
        "Book 2",
        "Book 3",
        "Book 4"
    ]
}

PLAY RECAP *************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=19   changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

まとめ

今回はリストへ動的に要素を追加する実装方法について書きました。この実装は共通処理部分で、外部リソースにアクセスしたり、複雑なデータ操作が必要となるような場合に適していると思われます。