はじめに
Anslbleを使うと複数のホストにまとめて設定を叩き込むことができます。便利ですね。でもホスト数が増えると結果を確認するのも一苦労。なんとかならないか調べたらなんとかできたので、記録を残します。
RACAP表示がてんこもり
ansible-playbook
を実行すると、最後に要約(RECAP)が表示されます。
PLAY RECAP ********************************************************************************************************
hoatA : ok=7 changed=0 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
hoatB : ok=7 changed=0 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
hoatC : ok=15 changed=3 unreachable=0 failed=0 skipped=8 rescued=0 ignored=0
hoatD : ok=5 changed=0 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
hostE : ok=12 changed=1 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
hostF : ok=12 changed=1 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
hostG : ok=12 changed=1 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
hostH : ok=12 changed=1 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
hostI : ok=10 changed=0 unreachable=0 failed=0 skipped=26 rescued=0 ignored=0
hostJ : ok=10 changed=0 unreachable=0 failed=0 skipped=26 rescued=0 ignored=0
hostK : ok=12 changed=1 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
hostL : ok=10 changed=0 unreachable=0 failed=0 skipped=26 rescued=0 ignored=0
hostM : ok=10 changed=0 unreachable=0 failed=0 skipped=26 rescued=0 ignored=0
hostN : ok=10 changed=0 unreachable=0 failed=0 skipped=8 rescued=0 ignored=0
hostO : ok=10 changed=0 unreachable=0 failed=0 skipped=8 rescued=0 ignored=0
hsotP : ok=16 changed=1 unreachable=0 failed=0 skipped=26 rescued=0 ignored=0
実行ログ全体からすれば要約なのはわかりますが、それでもホスト数がそれなりだと量が多いです。まだ1画面におさまる範囲ならなんとか見渡せますが、もっと数が増えるとひととおり確認するのも大変です。うっかり見落としてしまいそうな気もします。
できれば、全ホストのトータルの値を見てまずfailed
がないことを確認するなどしたいと思うのですが、はたして方法はあるのでしょうか。
探してみた
なんとかまとめられる方法がないか検索したら、わりとあっさり見つかりました。
読んでいくと、callback pluginを用意してどうにかした→callback pluginがAnsible collectionのひとつcommunity.generalに追加された、ということがわかります。
さっそくやってみた
ざっくりやったことは4つ。
-
community.general
のインストール -
ansible.cfg
への追加 - 変数定義
- Playbookへの追加
ひとつずつみていきます。
community.general
のインストール
ansible-galaxy collection install community.general
ansible.cfg
への追加
まず、ansible.cfg
にコールバックを追加します。Playbookと同じ場所に置いておくと読まれます。
[defaults]
stdout_callback = community.general.diy
変数定義
変数定義がてんこもりです。diy.py
というだけあって、自分で全部どうにかするという感じです。これをPlaybookに直接書くのは微妙なので、ファイルを分けました。内容はissueに書かれていたサンプルほぼそのままです。(cyan
の定義がなくて怒られたのでそこだけ追加しています)
color_reset: "\e[0m"
green: "\e[0m\e[38;5;2m"
yellow: "\e[0m\e[38;5;226m"
red: "\e[0m\e[38;5;1m"
cyan: "\e[0m\e[38;5;51m"
ansible_callback_diy_playbook_on_stats_msg: >-
{%- macro new_message(type, value) -%}
{%- set types = {"ok": { "color": green },
"changed": { "color": yellow },
"unreachable": { "color": red },
"failed": { "color": red },
"skipped": { "color": cyan },
"rescued": { "color": cyan },
"ignored": { "color": cyan } } -%}
{%- set msg = type+"="+("%-5s" | format(value)) -%}
{%- if value > 0 -%}
{%- set msg = types[type].color+msg+color_reset -%}
{%- endif -%}
{{- msg -}}
{%- endmacro -%}
{%- set newline, stats = "\n",ansible_callback_diy.stats -%}
{{- newline -}}
{{- "PLAY RECAP ******************************************************************************************************************"+newline -}}
{{- "-----------------------------------------------------------------------------------------------------------------------------"+newline -}}
{{- "SERVER RECAP"+newline+newline -}}
{%- for server, count in stats.processed.items() | sort -%}
{%- set ok = stats.ok[server] | default(0) -%}
{%- set ok_msg = new_message("ok", ok) -%}
{%- set changed = stats.changed[server] | default(0) -%}
{%- set changed_msg = new_message("changed", changed) -%}
{%- set unreachable = stats.dark[server] | default(0) -%}
{%- set unreachable_msg = new_message("unreachable", unreachable) -%}
{%- set failed = stats.failures[server] | default(0) -%}
{%- set failed_msg = new_message("failed", failed) -%}
{%- set skipped = stats.skipped[server] | default(0) -%}
{%- set skipped_msg = new_message("skipped", skipped) -%}
{%- set rescued = stats.rescued[server] | default(0) -%}
{%- set rescued_msg = new_message("rescued", rescued) -%}
{%- set ignored = stats.ignored[server] | default(0) -%}
{%- set ignored_msg = new_message("ignored", ignored) -%}
{%- set server_msg = "%-26s" | format(server) -%}
{{- server_msg+" : "+ok_msg+" "+changed_msg+" "+unreachable_msg+" "+failed_msg+" "+skipped_msg+" "+rescued_msg+" "+ignored_msg+newline -}}
{%- endfor -%}
{{- newline -}}
{%- set ok = stats.ok | dict2items | map(attribute='value') | sum -%}
{%- set ok_msg = new_message("ok", ok) -%}
{%- set changed = stats.changed | dict2items | map(attribute='value') | sum -%}
{%- set changed_msg = new_message("changed", changed) -%}
{%- set unreachable = stats.dark | dict2items | map(attribute='value') | sum -%}
{%- set unreachable_msg = new_message("unreachable", unreachable) -%}
{%- set failed = stats.failures | dict2items | map(attribute='value') | sum -%}
{%- set failed_msg = new_message("failed", failed) -%}
{%- set skipped = stats.skipped | dict2items | map(attribute='value') | sum -%}
{%- set skipped_msg = new_message("skipped", skipped) -%}
{%- set rescued = stats.rescued | dict2items | map(attribute='value') | sum -%}
{%- set rescued_msg = new_message("rescued", rescued) -%}
{%- set ignored = stats.ignored | dict2items | map(attribute='value') | sum -%}
{%- set ignored_msg = new_message("ignored", ignored) -%}
{{- "-----------------------------------------------------------------------------------------------------------------------------"+newline -}}
{%- set task_msg = "%-26s" | format("TASK RECAP") -%}
{{ task_msg+" : "+ok_msg+" "+changed_msg+" "+unreachable_msg+" "+failed_msg+" "+skipped_msg+" "+rescued_msg+" "+ignored_msg+newline -}}
{{- newline -}}
{%- set ok = stats.ok | length -%}
{%- set ok_msg = new_message("ok", ok) -%}
{%- set changed = stats.changed | length -%}
{%- set changed_msg = new_message("changed", changed) -%}
{%- set unreachable = stats.dark | length -%}
{%- set unreachable_msg = new_message("unreachable", unreachable) -%}
{%- set failed = stats.failures | length -%}
{%- set failed_msg = new_message("failed", failed) -%}
{%- set skipped = stats.skipped | length -%}
{%- set skipped_msg = new_message("skipped", skipped) -%}
{%- set rescued = stats.rescued | length -%}
{%- set rescued_msg = new_message("rescued", rescued) -%}
{%- set ignored = stats.ignored | length -%}
{%- set ignored_msg = new_message("ignored", ignored) -%}
{{- "-----------------------------------------------------------------------------------------------------------------------------"+newline -}}
{%- set host_msg = "%-26s" | format("HOST RECAP") -%}
{{ host_msg+" : "+ok_msg+" "+changed_msg+" "+unreachable_msg+" "+failed_msg+" "+skipped_msg+" "+rescued_msg+" "+ignored_msg+newline+newline -}}
Playbookへの追加
そしてPlaybookの末尾に下記を追加します。
- hosts: all
gather_facts: no
vars_files:
- callback_vars.yml
実行してみた
結果は下記。
PLAY RECAP ********************************************************************************************************
-----------------------------------------------------------------------------------------------------------------------------
SERVER RECAP
hoatA : ok=7 changed=0 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
hoatB : ok=7 changed=0 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
hoatC : ok=15 changed=3 unreachable=0 failed=0 skipped=8 rescued=0 ignored=0
hoatD : ok=5 changed=0 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
hostE : ok=12 changed=1 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
hostF : ok=12 changed=1 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
hostG : ok=12 changed=1 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
hostH : ok=12 changed=1 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
hostI : ok=10 changed=0 unreachable=0 failed=0 skipped=26 rescued=0 ignored=0
hostJ : ok=10 changed=0 unreachable=0 failed=0 skipped=26 rescued=0 ignored=0
hostK : ok=12 changed=1 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
hostL : ok=10 changed=0 unreachable=0 failed=0 skipped=26 rescued=0 ignored=0
hostM : ok=10 changed=0 unreachable=0 failed=0 skipped=26 rescued=0 ignored=0
hostN : ok=10 changed=0 unreachable=0 failed=0 skipped=8 rescued=0 ignored=0
hostO : ok=10 changed=0 unreachable=0 failed=0 skipped=8 rescued=0 ignored=0
hsotP : ok=16 changed=1 unreachable=0 failed=0 skipped=26 rescued=0 ignored=0
-----------------------------------------------------------------------------------------------------------------------------
TASK RECAP : ok=170 changed=9 unreachable=0 failed=0 skipped=206 rescued=0 ignored=0
-----------------------------------------------------------------------------------------------------------------------------
HOST RECAP : ok=16 changed=7 unreachable=0 failed=0 skipped=16 rescued=0 ignored=0
できました。このサンプルではテキストに色がつくようになっています。画像だと下記のような感じです。
おわりに
変数定義はPlaybookによらず同じなので、使いまわしするといいように思います。
名前の通りDIYなので、ああしたいこうしたいという場合はレッツチャレンジ!