はじめに
本記事は、Ansibleのplaybookでwith_items
等でループ処理した時の実行結果をregister
した後に、debug
モジュールを利用して、標準出力結果をループ数分取り出す方法を試行錯誤した結果です。ループしなければ簡単なのですが、地味にはまりました。
なお、デバッグオプション(-v)をつけてplaybookを実行すれば、register
とdebug
モジュールでこんなことをしなくても画面に出力されますが、改行されず見づらい等もあるので、自分用の備忘メモもかねて。
アジェンダ
ENV. 実行環境
Sample Playbook サンプルプレイブック
Results サンプルプレイブック実行結果
解説
Env.
# cat /etc/redhat-release
CentOS release 6.7 (Final)
# ansible --version
ansible 2.1.0 (devel d358a22542) last updated 2016/04/04 23:43:05 (GMT +900)
lib/ansible/modules/core: (detached HEAD a38bdfc720) last updated 2016/04/04 23:43:15 (GMT +900)
lib/ansible/modules/extras: (detached HEAD 7c3999a92a) last updated 2016/04/04 23:43:22 (GMT +900)
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
Sample playbook
reg_ret_with_items.yml
- hosts: localhost
gather_facts: no
vars:
TEST_CMD:
- cmd: echo "# LOOP01 *** THIS IS LOOP01 STDOUT ***"
- cmd: echo "# LOOP02 *** THIS IS LOOP02 STDOUT ***"
- cmd: echo "# LOOP03 *** THIS IS LOOP03 STDOUT ***"
tasks:
- raw: echo "# NOLOOP *** THIS IS NOLOOP STDOUT ***"
register: RESULT
- name: "DEBUG0: Output RESULT.stdout_lines"
debug: var=RESULT.stdout_lines
- raw: "{{ item.cmd }}"
register: CMD_RESULT
with_items: '{{ TEST_CMD }}'
- name: "DEBUG1: Output CMD_RESULT.stdout_lines"
debug: var=CMD_RESULT.stdout_lines
- name: "DEBUG2: Output CMD_RESULT.results"
debug: var=CMD_RESULT.results
- name: "DEBUG3: Output CMD_RESULT.results.stdout_lines by using with_items loop"
debug: var=item.stdout_lines
with_items: '{{ CMD_RESULT.results }}'
- name: "DEBUG4: Output CMD_RESULT.results.stdout_lines by using jinjya2 fileter"
debug:
msg: |
{% for r in CMD_RESULT.results %}
{{ r.stdout_lines | to_nice_json }}
{% endfor %}
Results
# ansible-playbook reg_ret_with_items.yml
PLAY [localhost] ***************************************************************
TASK [raw] *********************************************************************
ok: [localhost]
TASK [DEBUG0: Output RESULT.stdout_lines] **************************************
ok: [localhost] => {
"RESULT.stdout_lines": [
"# NOLOOP *** THIS IS NOLOOP STDOUT ***"
]
}
TASK [raw] *********************************************************************
ok: [localhost] => (item={u'cmd': u'echo "# LOOP01 *** THIS IS LOOP01 STDOUT ***"'})
ok: [localhost] => (item={u'cmd': u'echo "# LOOP02 *** THIS IS LOOP02 STDOUT ***"'})
ok: [localhost] => (item={u'cmd': u'echo "# LOOP03 *** THIS IS LOOP03 STDOUT ***"'})
TASK [DEBUG1: Output CMD_RESULT.stdout_lines] **********************************
ok: [localhost] => {
"CMD_RESULT.stdout_lines": "VARIABLE IS NOT DEFINED!"
}
TASK [DEBUG2: Output CMD_RESULT.results] ***************************************
ok: [localhost] => {
"CMD_RESULT.results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"invocation": {
"module_args": {
"_raw_params": "echo \"# LOOP01 *** THIS IS LOOP01 STDOUT ***\""
},
"module_name": "raw"
},
"item": {
"cmd": "echo \"# LOOP01 *** THIS IS LOOP01 STDOUT ***\""
},
"rc": 0,
"stderr": "",
"stdout": "# LOOP01 *** THIS IS LOOP01 STDOUT ***\n",
"stdout_lines": [
"# LOOP01 *** THIS IS LOOP01 STDOUT ***"
]
},
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"invocation": {
"module_args": {
"_raw_params": "echo \"# LOOP02 *** THIS IS LOOP02 STDOUT ***\""
},
"module_name": "raw"
},
"item": {
"cmd": "echo \"# LOOP02 *** THIS IS LOOP02 STDOUT ***\""
},
"rc": 0,
"stderr": "",
"stdout": "# LOOP02 *** THIS IS LOOP02 STDOUT ***\n",
"stdout_lines": [
"# LOOP02 *** THIS IS LOOP02 STDOUT ***"
]
},
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"invocation": {
"module_args": {
"_raw_params": "echo \"# LOOP03 *** THIS IS LOOP03 STDOUT ***\""
},
"module_name": "raw"
},
"item": {
"cmd": "echo \"# LOOP03 *** THIS IS LOOP03 STDOUT ***\""
},
"rc": 0,
"stderr": "",
"stdout": "# LOOP03 *** THIS IS LOOP03 STDOUT ***\n",
"stdout_lines": [
"# LOOP03 *** THIS IS LOOP03 STDOUT ***"
]
}
]
}
TASK [DEBUG3: Output CMD_RESULT.results.stdout_lines by using with_items loop] *
ok: [localhost] => (item={'_ansible_no_log': False, 'stdout': u'# LOOP01 *** THIS IS LOOP01 STDOUT ***\n', '_ansible_item_result': True, 'item': {u'cmd': u'echo "# LOOP01 *** THIS IS LOOP01 STDOUT ***"'}, 'stderr': u'', 'rc': 0, 'invocation': {'module_name': u'raw', 'module_args': {u'_raw_params': u'echo "# LOOP01 *** THIS IS LOOP01 STDOUT ***"'}}, 'stdout_lines': [u'# LOOP01 *** THIS IS LOOP01 STDOUT ***']}) => {
"item": {
"invocation": {
"module_args": {
"_raw_params": "echo \"# LOOP01 *** THIS IS LOOP01 STDOUT ***\""
},
"module_name": "raw"
},
"item": {
"cmd": "echo \"# LOOP01 *** THIS IS LOOP01 STDOUT ***\""
},
"rc": 0,
"stderr": "",
"stdout": "# LOOP01 *** THIS IS LOOP01 STDOUT ***\n",
"stdout_lines": [
"# LOOP01 *** THIS IS LOOP01 STDOUT ***"
]
},
"item.stdout_lines": [
"# LOOP01 *** THIS IS LOOP01 STDOUT ***"
]
}
ok: [localhost] => (item={'_ansible_no_log': False, 'stdout': u'# LOOP02 *** THIS IS LOOP02 STDOUT ***\n', '_ansible_item_result': True, 'item': {u'cmd': u'echo "# LOOP02 *** THIS IS LOOP02 STDOUT ***"'}, 'stderr': u'', 'rc': 0, 'invocation': {'module_name': u'raw', 'module_args': {u'_raw_params': u'echo "# LOOP02 *** THIS IS LOOP02 STDOUT ***"'}}, 'stdout_lines': [u'# LOOP02 *** THIS IS LOOP02 STDOUT ***']}) => {
"item": {
"invocation": {
"module_args": {
"_raw_params": "echo \"# LOOP02 *** THIS IS LOOP02 STDOUT ***\""
},
"module_name": "raw"
},
"item": {
"cmd": "echo \"# LOOP02 *** THIS IS LOOP02 STDOUT ***\""
},
"rc": 0,
"stderr": "",
"stdout": "# LOOP02 *** THIS IS LOOP02 STDOUT ***\n",
"stdout_lines": [
"# LOOP02 *** THIS IS LOOP02 STDOUT ***"
]
},
"item.stdout_lines": [
"# LOOP02 *** THIS IS LOOP02 STDOUT ***"
]
}
ok: [localhost] => (item={'_ansible_no_log': False, 'stdout': u'# LOOP03 *** THIS IS LOOP03 STDOUT ***\n', '_ansible_item_result': True, 'item': {u'cmd': u'echo "# LOOP03 *** THIS IS LOOP03 STDOUT ***"'}, 'stderr': u'', 'rc': 0, 'invocation': {'module_name': u'raw', 'module_args': {u'_raw_params': u'echo "# LOOP03 *** THIS IS LOOP03 STDOUT ***"'}}, 'stdout_lines': [u'# LOOP03 *** THIS IS LOOP03 STDOUT ***']}) => {
"item": {
"invocation": {
"module_args": {
"_raw_params": "echo \"# LOOP03 *** THIS IS LOOP03 STDOUT ***\""
},
"module_name": "raw"
},
"item": {
"cmd": "echo \"# LOOP03 *** THIS IS LOOP03 STDOUT ***\""
},
"rc": 0,
"stderr": "",
"stdout": "# LOOP03 *** THIS IS LOOP03 STDOUT ***\n",
"stdout_lines": [
"# LOOP03 *** THIS IS LOOP03 STDOUT ***"
]
},
"item.stdout_lines": [
"# LOOP03 *** THIS IS LOOP03 STDOUT ***"
]
}
TASK [DEBUG4: Output CMD_RESULT.results.stdout_lines by using jinjya2 fileter] *
ok: [localhost] => {
"msg": " [\n \"# LOOP01 *** THIS IS LOOP01 STDOUT ***\"\n]\n [\n \"# LOOP02 *** THIS IS LOOP02 STDOUT ***\"\n]\n [\n \"# LOOP03 *** THIS IS LOOP03 STDOUT ***\"\n]\n"
}
PLAY RECAP *********************************************************************
localhost : ok=7 changed=0 unreachable=0 failed=0
#
解説
ループ処理がない場合
ループ処理がない場合、DEBUG0のように標準出力の結果を画面表示できますが、
with_items
等でループ処理をした場合は、少し工夫が必要です。
ループ処理がある場合
ループ処理がある場合、register
した結果は、変数名.results
の下に配列として格納されているようなので、ループ処理がない時と同じようにしてもうまくいきません。
- DEBUG1では、ループ処理が無いときと同じように書いているため、"VARIABLE IS NOT DEFINED!"として出力に失敗した例です。
-
DEBUG2では、
変数名.results
の配列をまるごと出力した例です。 -
DEBUG3では、
変数名.results.stdout_lines
をwith_itmes
として変数名.results
を指定した例です。item
の中身も出力されるので少し見ずらいです。 -
DEBUG4では、
変数名.results.stdout_lines
をjinjya2 filterを使ってstdout_linesのみを出力した例ですが、jinjya2 filterの理解不足のためか改行処理がうまくいっていません。。。
おわりに
もっと上手い書き方があると思いますので、こんな風にすれば良い等、ありましたら是非コメント頂ければと思います。