Ansible の with_items の出力を抑制する方法
ネタがない上に 3 月になってしまったので恒例の Ansible 小ネタですw まずはこの playbook を見てみましょう。
--- - hosts: localhost connection: local gather_facts: false tasks: - name: execute docker commands command: "docker {{ item }}" with_items: - "ps --help" - "logs --help" changed_when: false register: command_result - name: output docker command's help debug: msg: "{{ item.stdout_lines }}" with_items: "{{ command_result.results }}" when: command_result.results is defined and item.stdout_lines is defined
やっていることは command のリストを用意して loop 実行して、その結果を表示する、ですね。 ただ実際に実行してみると
$ ansible-playbook loop.yml PLAY [localhost] **************************************************************************************************************************** TASK [execute docker commands] ************************************************************************************************************** ok: [localhost] => (item=ps --help) ok: [localhost] => (item=logs --help) TASK [output docker command's help] ********************************************************************************************************* ok: [localhost] => (item={'changed': False, 'end': '2019-03-09 13:21:42.414016', 'stdout': "\nUsage:\tdocker ps [OPTIONS]\n\nList containers\ n\nOptions:\n -a, --all Show all containers (default shows just running)\n -f, --filter filter Filter output based on conditi ons provided\n --format string Pretty-print containers using a Go template\n -n, --last int Show n last created containers (in cludes all\n states) (default -1)\n -l, --latest Show the latest created container (includes all\n states)\n --no-trunc Don't truncate output\n -q, --quiet Only display numeric IDs\n -s, --size Display total file sizes", 'cmd': ['docker', 'ps', '--help'], 'rc': 0, 'start': '2019-03-09 13:21:42.361156', 'stderr': '', 'delta': '0:00 :00.052860', 'invocation': {'module_args': {'creates': None, 'executable': None, '_uses_shell': False, '_raw_params': 'docker ps --help', 're moves': None, 'argv': None, 'warn': True, 'chdir': None, 'stdin': None}}, '_ansible_parsed': True, 'stdout_lines': ['', 'Usage:\tdocker ps [O PTIONS]', '', 'List containers', '', 'Options:', ' -a, --all Show all containers (default shows just running)', ' -f, --filter filter Filter output based on conditions provided', ' --format string Pretty-print containers using a Go template', ' -n, --last in t Show n last created containers (includes all', ' states) (default -1)', ' -l, --latest Show the lat est created container (includes all', ' states)', " --no-trunc Don't truncate output", ' -q, --quiet Only display numeric IDs', ' -s, --size Display total file sizes'], 'stderr_lines': [], '_ansible_no_log': False, 'failed': False, 'item': 'ps --help', '_ansible_item_result': True, '_ansible_ignore_errors': None, '_ansible_item_label': 'ps --help'}) => { "msg": [ "", "Usage:\tdocker ps [OPTIONS]", "", "List containers", "", "Options:", " -a, --all Show all containers (default shows just running)", " -f, --filter filter Filter output based on conditions provided", " --format string Pretty-print containers using a Go template", " -n, --last int Show n last created containers (includes all", " states) (default -1)", " -l, --latest Show the latest created container (includes all", " states)", " --no-trunc Don't truncate output", " -q, --quiet Only display numeric IDs", " -s, --size Display total file sizes" ] } ok: [localhost] => (item={'changed': False, 'end': '2019-03-09 13:21:42.671432', 'stdout': '\nUsage:\tdocker logs [OPTIONS] CONTAINER\n\nFet ch the logs of a container\n\nOptions:\n --details Show extra details provided to logs\n -f, --follow Follow log output \n --since string Show logs since timestamp (e.g.\n 2013-01-02T13:23:37) or relative (e.g. 42m for 42\n minutes)\n --tail string Number of lines to show from the end of the logs\n (default "all")\n -t, --timestamps Show timestamps\n --until string Show logs before a timestamp (e.g.\n 2013-01-02T13:23:37) or relative (e.g. 42m for 42\n minutes)', 'cmd': ['docker', 'logs', '--help'], 'rc': 0, 'start': '2019-03-09 13:21:42 .619107', 'stderr': '', 'delta': '0:00:00.052325', 'invocation': {'module_args': {'creates': None, 'executable': None, '_uses_shell': False, '_raw_params': 'docker logs --help', 'removes': None, 'argv': None, 'warn': True, 'chdir': None, 'stdin': None}}, '_ansible_parsed': True, 'stdout_lines': ['', 'Usage:\tdocker logs [OPTIONS] CONTAINER', '', 'Fetch the logs of a container', '', 'Options:', ' --details Show extra details provided to logs', ' -f, --follow Follow log output', ' --since string Show logs since timestamp (e.g.', ' 2013-01-02T13:23:37) or relative (e.g. 42m for 42', ' minutes)', ' --tail string Numb er of lines to show from the end of the logs', ' (default "all")', ' -t, --timestamps Show timestamps', ' - -until string Show logs before a timestamp (e.g.', ' 2013-01-02T13:23:37) or relative (e.g. 42m for 42', ' minutes)'], 'stderr_lines': [], '_ansible_no_log': False, 'failed': False, 'item': 'logs --help', '_ansible_item_result': True, '_ansible_ignore_errors': None, '_ansible_item_label': 'logs --help'}) => { "msg": [ "", "Usage:\tdocker logs [OPTIONS] CONTAINER", "", "Fetch the logs of a container", "", "Options:", " --details Show extra details provided to logs", " -f, --follow Follow log output", " --since string Show logs since timestamp (e.g.", " 2013-01-02T13:23:37) or relative (e.g. 42m for 42", " minutes)", " --tail string Number of lines to show from the end of the logs", " (default \"all\")", " -t, --timestamps Show timestamps", " --until string Show logs before a timestamp (e.g.", " 2013-01-02T13:23:37) or relative (e.g. 42m for 42", " minutes)" ] } PLAY RECAP ********************************************************************************************************************************** localhost : ok=2 changed=0 unreachable=0 failed=0
(ターミナルの行折返しの表示を真似てあえて改行を加えて書きましたが) item の全内容が loop 毎に表示されてとても見づらいですね。
それならということで no_log
を付けてみるわけですが、これはもちろん全出力が抑えられてしまいます。
$ ansible-playbook loop.yml PLAY [localhost] **************************************************************************************************************************** TASK [execute docker commands] ************************************************************************************************************** ok: [localhost] => (item=ps --help) ok: [localhost] => (item=logs --help) TASK [output docker command's help] ********************************************************************************************************* ok: [localhost] => (item=None) ok: [localhost] => (item=None) ok: [localhost] PLAY RECAP ********************************************************************************************************************************** localhost : ok=2 changed=0 unreachable=0 failed=0
まだ手はあるぞということで item 自体の内容を減らしてみますが、これだと当然 item 内に参照したい値が複数ある場合にやっぱり困ります。
- name: output docker command's help debug: msg: "{{ item }}" with_items: "{{ command_result.results | map(attribute='stdout_lines') | list }}" when: command_result.results is defined
そんな時に使えるのが loop_control の label です。
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#loop-control
使い方はまさにこのユースケースどおりで、 label 部分のみ制御することができます。
--- - hosts: localhost connection: local gather_facts: false tasks: - name: execute docker commands command: "docker {{ item }}" with_items: - "ps --help" - "logs --help" changed_when: false register: command_result - name: output docker command's help debug: msg: "{{ item.stdout_lines }}" with_items: "{{ command_result.results }}" loop_control: label: "{{ item.cmd | default(item) }}" when: command_result.results is defined and item.stdout_lines is defined
結果は
$ ansible-playbook loop.yml PLAY [localhost] **************************************************************************************************************************** TASK [execute docker commands] ************************************************************************************************************** ok: [localhost] => (item=ps --help) ok: [localhost] => (item=logs --help) TASK [output docker command's help] ********************************************************************************************************* ok: [localhost] => (item=['docker', 'ps', '--help']) => { "msg": [ "", "Usage:\tdocker ps [OPTIONS]", "", "List containers", "", "Options:", " -a, --all Show all containers (default shows just running)", " -f, --filter filter Filter output based on conditions provided", " --format string Pretty-print containers using a Go template", " -n, --last int Show n last created containers (includes all", " states) (default -1)", " -l, --latest Show the latest created container (includes all", " states)", " --no-trunc Don't truncate output", " -q, --quiet Only display numeric IDs", " -s, --size Display total file sizes" ] } ok: [localhost] => (item=['docker', 'logs', '--help']) => { "msg": [ "", "Usage:\tdocker logs [OPTIONS] CONTAINER", "", "Fetch the logs of a container", "", "Options:", " --details Show extra details provided to logs", " -f, --follow Follow log output", " --since string Show logs since timestamp (e.g.", " 2013-01-02T13:23:37) or relative (e.g. 42m for 42", " minutes)", " --tail string Number of lines to show from the end of the logs", " (default \"all\")", " -t, --timestamps Show timestamps", " --until string Show logs before a timestamp (e.g.", " 2013-01-02T13:23:37) or relative (e.g. 42m for 42", " minutes)" ] } PLAY RECAP ********************************************************************************************************************************** localhost : ok=2 changed=0 unreachable=0 failed=0
label 部分がコマンドの内容になり、出力は stdout_lines のみになってスッキリしましたね。
困った時は Loop Control 、使ってみてください。
Ansible実践ガイド 第2版 (impress top gear)
- 作者: 北山晋吾,塚本正隆,畠中幸司
- 出版社/メーカー: インプレス
- 発売日: 2018/03/01
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る