はじめに
Ansibleでタスクの実行結果をregisterに保存しておくと後続タスクで利用することができますが、階層が深かったりするので、結果から任意の値でディクショナリやリストを作れれば色々と便利ですよね。
今回はregisterから任意のディクショナリやリストを生成して、後続タスクで利用してみたいと思います。
sample
ターゲットホストの下記ユーザのUIDを取得し、それらをディクショナリやリストにして、後続タスクで参照します。
- test1(UID:501)
- test2(UID:502)
UIDを取得してresisterに保存
- name: UID取得
command: "id -u {{ item }}"
with_items:
- test1
- test2
register: uid
- debug: var=uid.results
idコマンドでuidを取得し、registerに結果を保存します。
結果
TASK [sample : UID取得 _raw_params=id -u {{ item }}] *****************************
changed: [targethost] => (item=test1)
changed: [targethost] => (item=test2)
TASK [sample : debug var=uid.results] ****************************************
ok: [targethost] => {
"uid.results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": [
"id",
"-u",
"test1"
],
"delta": "0:00:00.002434",
"end": "2017-03-24 17:29:35.322215",
"invocation": {
"module_args": {
"_raw_params": "id -u test1",
"_uses_shell": false,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
},
"module_name": "command"
},
"item": "test1",
"rc": 0,
"start": "2017-03-24 17:29:35.319781",
"stderr": "",
"stdout": "501",
"stdout_lines": [
"501"
],
"warnings": []
},
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": [
"id",
"-u",
"test2"
],
"delta": "0:00:00.002320",
"end": "2017-03-24 17:29:35.535008",
"invocation": {
"module_args": {
"_raw_params": "id -u test2",
"_uses_shell": false,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
},
"module_name": "command"
},
"item": "test2",
"rc": 0,
"start": "2017-03-24 17:29:35.532688",
"stderr": "",
"stdout": "502",
"stdout_lines": [
"502"
],
"warnings": []
}
]
}
ちょっと長いですが、今回はwith_items
で2回ループさせているので、uid.resultsというリストに結果が格納されています。
それぞれのitem
とstdout
(今回はuid)からディクショナリを作成します。
ディクショナリ作成
- name: dict作成
set_fact:
uid_dict: >-
{%- set tmpdict = {} -%}
{%- for i in range(uid.results|length) -%}
{%- set _ = tmpdict.update({uid.results[i].item: uid.results[i].stdout}) -%}
{%- endfor -%}
{{ tmpdict }}
- debug: var=uid_dict
結果
TASK [sample : dict作成 uid_dict={%- set tmpdict = {} -%} {%- for i in range(uid.results|length) -%} {%- set _ = tmpdict.update({uid.results[i].item: uid.results[i].stdout}) -%} {%- endfor -%} {{ tmpdict }}] ***
ok: [targethost]
TASK [sample : debug var=uid_dict] *******************************************
ok: [targethost] => {
"uid_dict": {
"test1": "501",
"test2": "502"
}
}
uid_dictという、key:ユーザ名,value:UIDのディクショナリができました。
次はUIDだけのリストを作成してみます。
リスト作成
- name: list作成
set_fact:
uid_list: >-
{%- set tmplist = [] -%}
{%- for i in range(uid.results|length) -%}
{%- set _ = tmplist.append(uid.results[i].stdout) -%}
{%- endfor -%}
{{ tmplist }}
- debug: var=uid_list
結果
TASK [sample : list作成 uid_list={%- set tmplist = [] -%} {%- for i in range(uid.results|length) -%} {%- set _ = tmplist.append(uid.results[i].stdout) -%} {%- endfor -%} {{ tmplist }}] ***
ok: [targethost]
TASK [sample : debug var=uid_list] *******************************************
ok: [targethost] => {
"uid_list": [
"501",
"502"
]
}
作成できました。
それでは、後続タスクでこれらを参照してみます。
まず、uid_dictのtest1のvalue(=501)をrawモジュールに渡して/etc/passwdをuidでgrepしてみます。
ディクショナリを使う
- name: uid_dictを使う
raw: "cat /etc/passwd | grep {{ uid_dict.test1 }}"
register: use_uid_dict
- debug: var=use_uid_dict.stdout
結果
TASK [sample : uid_dictを使う _raw_params=cat /etc/passwd | grep {{ uid_dict.test1 }}] ***
changed: [targethost]
TASK [set_dict : debug var=use_uid_dict.stdout] ********************************
ok: [targethost] => {
"use_uid_dict.stdout": "test1:x:501:501::/home/test1:/bin/bash\r\n"
}
うまくいきました。
次はuid_listを使ってwith_itemsでループさせてみます。
uid_listにはUIDが格納されているので、同じく/etc/passwdをgrepしてみます。
リストを使う
- name: uid_listを使う
raw: "cat /etc/passwd | grep {{ item }}"
with_items: "{{ uid_list }}"
register: use_uid_list
- debug: var=use_uid_list.results
結果
TASK [sample : uid_listを使う _raw_params=cat /etc/passwd | grep {{ item }}] ******
changed: [targethost] => (item=501)
changed: [targethost] => (item=502)
TASK [sample : debug var=use_uid_list.results] *******************************
ok: [targethost] => {
"use_uid_list.results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"changed": true,
"invocation": {
"module_args": {
"_raw_params": "cat /etc/passwd | grep 501"
},
"module_name": "raw"
},
"item": "501",
"rc": 0,
"stderr": "Shared connection to xxx.xxx.xxx.xxx closed.\r\n",
"stdout": "test1:x:501:501::/home/test1:/bin/bash\r\n",
"stdout_lines": [
"test1:x:501:501::/home/test1:/bin/bash"
]
},
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"changed": true,
"invocation": {
"module_args": {
"_raw_params": "cat /etc/passwd | grep 502"
},
"module_name": "raw"
},
"item": "502",
"rc": 0,
"stderr": "Shared connection to xxx.xxx.xxx.xxx closed.\r\n",
"stdout": "test2:x:502:502::/home/test2:/bin/bash\r\n",
"stdout_lines": [
"test2:x:502:502::/home/test2:/bin/bash"
]
}
]
}
ちょっと長いですが、各resultsのstdoutを見ると、うまくいっているのが分かります。
まとめ
今回のサンプルはあまりいい例ではありませんが、このように任意のディクショナリやリストを作成すると何かと便利に使えると思います。