0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Ansible: RECAPの総計を表示させる

Last updated at Posted at 2021-09-01

はじめに

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と同じ場所に置いておくと読まれます。

ansible.cfg
[defaults]
stdout_callback = community.general.diy

変数定義

変数定義がてんこもりです。diy.pyというだけあって、自分で全部どうにかするという感じです。これをPlaybookに直接書くのは微妙なので、ファイルを分けました。内容はissueに書かれていたサンプルほぼそのままです。(cyanの定義がなくて怒られたのでそこだけ追加しています)

callback_vars.yml
    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の末尾に下記を追加します。

deploy.yml
- 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なので、ああしたいこうしたいという場合はレッツチャレンジ!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?