【Ansible】外部の変数ファイルから変数の一部を読み込む(selectattr,map)

# はじめに
<バージョン>
ansible 2.9.1

playbookを書いていると、変数が増えてきて変数ファイルだけを
別で作成したいことがあると思います。以下が参考となる変数ファイルです。
この中から、playbookでユーザの入力に基づいて変数を読み込んでみましょう。

```yaml:input_vars.yml
---
input_vars:
  text:
    - type: a
      file: test1.txt
    - type: b
      file: test2.txt
    - type: c
      file: test3.txt
  yaml:
    - name: test4
      file: test4.yml
    - name: test5
      file: test5.yml
    - name: test6
      file: test6.yml
```

# Playbookの紹介
今回はよくある2つのパターンを試します
(1)vars_promptの入力(a,b,c)に基づいてtextという変数の中身を取り出す
　 → aと入力したら、{ type : a , file : test1.txt } という辞書を出力する
(2)yamlという変数内のnameの中身をすべて取り出す
　 → [test4, test5, test6] というリストを出力する
___ポイント___
(1)vars_filesに外部の変数名を記入する
(2)vars_promptでユーザーから入力を受け付ける。（ついでにpromptをfor文で記入）
(3)selectattrで条件にマッチする部分を出力する
(4)mapで指定したキーの中身を出力する

```yaml:select_test.yml
---
- name: select TEST
  hosts: localhost
  gather_facts: no
  vars_files:
    - input_vars.yml  #ポイント(1)
  vars:
    ansible_python_interpreter: /usr/bin/python3
  vars_prompt:
    - name: "usr_input"    #ポイント(2)
      prompt: |
              here are output lists!
              {% for i in input_vars['text'] %}
              {{ i['type'] }} : {{ i['file'] }}
              {% endfor -%}
      private: no
  tasks:
    - name: test1 set_fact
      set_fact:    #ポイント(3)
        select_info: >-
                     {{ input_vars['text'] | selectattr('type', 'contains', usr_input)
                                           | list | first }}     
    - name: test1 debug select_info
      debug:
        msg: "{{ select_info }}"

    - name: test1 debug select_info file
      debug:
        msg: "{{ select_info['file'] }}"

    - name: test2 set_fact
      set_fact:
        yaml_name: "{{ input_vars['yaml'] | map(attribute='name') | list }}"    #ポイント(4)

    - name: test2 debug yaml_name
      debug:
        msg: "{{ yaml_name }}"
```

# 出力結果
想定通りの結果を得ることが出来ました。
ユーザからの入力に基づいて、結果をselect_infoという変数に代入しています。
さらに、select_info[キー名]とすることで中身を取り出すことも可能です。
___注意___
selectattrの結果をわざわざlistに格納していますが、このようにしないと変数の中身が見えません。
そのため、listに格納→first(lastでも可)でリストの先頭を取り出すという処理をしています。

```text:出力
[ec2-user@ip-<addr> ansible]$ ansible-playbook select_test.yml
[WARNING]: No inventory was parsed, only implicit localhost is available

[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

here are output lists!
a : test1.txt
b : test2.txt
c : test3.txt
: a　　←入力を実施

PLAY [select TEST] **************************************************************************************************************************************************************************

TASK [test1 set_fact] ***********************************************************************************************************************************************************************
ok: [localhost]

TASK [test1 debug select_info] **************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": {
        "file": "test1.txt",
        "type": "a"
    }
}

TASK [test1  debug select_info file] ********************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "test1.txt"
}

TASK [test2 set_fact] ***********************************************************************************************************************************************************************
ok: [localhost]

TASK [test2 debug yaml_name] ****************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "test4",
        "test5",
        "test6"
    ]
}

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

# 関連記事
[【Ansible】promptをfor文で記入する](https://qiita.com/masa2223/items/5281dbaa012ad57bb79c)
[【Ansible】辞書型から任意の値を取り出してリストを作成する](https://qiita.com/masa2223/items/ed9717770c81d3693c39)
[【Ansible】外部の変数ファイルから変数の一部を読み込む(json_query)](https://qiita.com/masa2223/items/d740f21a3cc705232d2b)