職場でなんとなく使用しているAnsible。
ユーザ作成/削除、コンポートのインストールetc..、あらゆる場面でAnsibleは登場します。
しかし、Ansible playbookを一度でも実行したことがある人なら一度でも思ったことがあるはず。
「このコマンドの実行結果成功してるの?失敗してるの?」
そうです。playbookの実行結果というのは非常に見ずらいのです。
冪等性という概念も相まって非常に分かりづらいです。。
本記事ではそんな、playbookの出力結果の見方について解説していこうと思います。
事前準備
本記事で使用するAnsibleの実行環境に関しては、以下の記事にて作成した検証環境を使用します。
【CFn】Ansibleの検証環境をECS(EC2)上に構築する①(環境構築編)
【CFn】Ansibleの検証環境をECS(EC2)上に構築する②(Ansible実行編)
ディレクトリ構成に関して以下の通りとします。
/etc/
└ ansible
├─ hosts ・・・inventoryファイル
└─ adduser.yml ・・・playbookファイル
hosts(inventory)ファイルの中身は以下の通りです
[Web]
web01
web02
[all:vars]
ansible_ssh_user=ec2-user
ansible_ssh_private_key_file=/home/ec2-user/.ssh/id_rsa
今回使用するplaybookは以下の通り、新しくadduser.ymlを作成します。
「ターゲットホスト(WebコンテナA,B)にて新規ユーザを作成する」といった処理です。
---
- hosts: Web # 今回inventoryのdbグループにだけ実施
sudo: yes # 管理者権限で実行するには必要となる
tasks: # playbookで実行する内容を記述
- name: add a new user # タスク名を記述(省略可)
user: name=testuser # ユーザー追加のモジュール
playbookの基本
早速playbookを実行します。
本記事では、文法チェック含め以下の実行コマンドに関しての出力結果を確認します。
playbookの文法チェック。(オプション「–syntax-check」)$ ansible-playbook -i hosts ./adduser.yml --syntax-check
playbookのDryRun。(オプション「-C(–check)」)$ ansible-playbook -i hosts ./adduser.yml --check
playbookの実行。$ ansible-playbook -i hosts ./adduser.yml
playbookの文法チェック
playbookには、実行する前にそのplaybookの中身の構文に間違いが無いかを確認するオプションがあります。
作成したplaybookが正しく機能するかを確認したり、デバッグの際に使用します。
--syntax-check
・・・構文チェック
■ 問題が無い場合
シンプルにファイル名のみが帰ってきます。
(場合によりWarningエラーが返ってきますが、ただの警告文なので無視して大丈夫です。)
# playbookの文法チェック。(オプション「--syntax-check」)
$ ansible-playbook -i hosts ./adduser.yml --syntax-check
playbook: ./adduser.yml
■ 問題がある場合
このように問題箇所を指し示す形でエラーが出力されます。
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: No JSON object could be decoded
Syntax Error while loading YAML.
mapping values are not allowed in this context
The error appears to be in '/etc/ansible/adduser.yml': line 3, column 10, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
sudo: yes
- name: add a new user
^ here
playbookのDryRun
playbookには、DryRunオプションがあります。
本番環境等、絶対に失敗できない環境ではこのDryRunオプションを指定する形で仮実行し、playbook処理に問題が無いかを確認します。
-C(--check)
・・・DryRunオプション
■ 問題が無い場合
このようにPLAY RECAPにOK=1(実行した処理の数、今回で言うとユーザ作成処理分)、chenged=1(処理によってサーバの状態に変更が生じた数、今回で言うとtestuserが追加されたという変更分)と表示されます。
というかPLAY RECAPまで表示されて、Failedのカウントが0以外であれば基本的には処理に問題はありません。
(場合によりWarningエラーが返ってきますが、ただの警告文なので無視して大丈夫です。)
# playbookのDryRun
$ ansible-playbook -i hosts ./adduser.yml --check
PLAY [Web] *************************************************************************************************************************************************************
TASK [Add the user 'testuser'] *****************************************************************************************************************************************
[WARNING]: Platform linux on host web02 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could
change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
changed: [web02]
[WARNING]: Platform linux on host web01 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could
change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
changed: [web01]
PLAY RECAP *************************************************************************************************************************************************************
web01 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web02 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
■ 問題がある場合
以下のようにFAILEDの数がカウントされていれば、playbook処理が失敗していることになります。
(今回で言うと、オプションの–checkが-checkになっていることのエラーです)
# playbookのDryRun
$ ansible-playbook -i hosts ./adduser.yml -check
PLAY [Web] *************************************************************************************************************************************************************
TASK [Add the user 'testuser'] *****************************************************************************************************************************************
fatal: [web01]: FAILED! => {"msg": "the connection plugin 'heck' was not found"}
fatal: [web02]: FAILED! => {"msg": "the connection plugin 'heck' was not found"}
PLAY RECAP *************************************************************************************************************************************************************
web01 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
web02 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
もしくわ、ssh接続等に問題があり、そもそものサーバ間の通信に問題があれば、以下のようなエラーが出力されます。SSH設定を見直しましょう。
# playbookのDryRun
$ ansible-playbook -i hosts ./adduser.yml --check
fatal: [192.168.100.253]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", "unreachable": true}
playbookの実行
DryRunの結果、問題がなければ本実行します。
ansible-playbook
- playbookを実行する際は、
ansible
に-playbook
を付ける形で実行します。
- playbookを実行する際は、
-i hosts
-i(--inventory)
でInventoryファイルを指定します。hosts
はInventoryファイルのことです。
./adduser.yml
- 実行するplaybook.ymlです。playbookファイルはymlかjson形式で記載します。
■ 実行結果
DryRun時と特に変わりはありません。
# playbookの実行
$ ansible-playbook -i hosts ./adduser.yml
PLAY [Web] *************************************************************************************************************************************************************
TASK [Add the user 'testuser'] *****************************************************************************************************************************************
[WARNING]: Platform linux on host web01 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could
change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
changed: [web01]
[WARNING]: Platform linux on host web02 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could
change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
changed: [web02]
PLAY RECAP *************************************************************************************************************************************************************
web01 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web02 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
なお、再度playbookを実行すると以下のような結果になります。
# playbookの実行(2回目)
$ ansible-playbook -i hosts ./adduser.yml
PLAY [Web] *************************************************************************************************************************************************************
TASK [Add the user 'testuser'] *****************************************************************************************************************************************
[WARNING]: Platform linux on host web01 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could
change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [web01]
[WARNING]: Platform linux on host web02 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could
change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [web02]
PLAY RECAP *************************************************************************************************************************************************************
web01 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web02 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
先程とは変わって、changedが0になっていますね。
これはtestuserは既に作成されているため、同じ処理を実行してもサーバ側に変化がないからです。
このように同じ処理を何度実行しても同じ結果になる性質を「冪等性」といいます。
冪等性に関しては、以下の記事で解説しているのでよければご覧下さい。
出力結果の見方
playbookの出力結果について見ていきます。
基本的にはplaybookは以下の形式で出力されます。
PLAY [Web] *************************************************************************************************************************************************************
TASK [Add the user 'testuser'] *****************************************************************************************************************************************
[WARNING]: Platform linux on host web01 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could
change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
changed: [web01]
[WARNING]: Platform linux on host web02 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could
change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
changed: [web02]
PLAY RECAP *************************************************************************************************************************************************************
web01 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web02 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ではそれぞれのセクションの意味について解説していきます。
PLAY
簡単に言うと、このターゲットに対して、playbookを実行するよーって意味です。
今回でいうと、ターゲット「Web」に対して処理を実行するっていう宣言みたいなものですね。
playbook実行後、無視されがちなセクションですが、ターゲットの指定に間違えがないか改めて確認する癖を付けておきましょう。
TASK
処理を行うタスク名とその実行結果を出力するセクションです。
タスクの実行結果に応じて、以下のステータスが出力されます。
・changed:playbookが問題なく実行され、ターゲットノードに変化が加えられた状態
・ok:playbook自体は問題なく実行されているが、その結果対象サーバの変化が無い状態
・skipped:playbookの処理自体は走ってるけど、対象ホストにタスクを実行しなかった
・failed : 対象ホストにタスクを実行したら、何らかのエラーが発生した
TASK [Add the user 'testuser'] *****************************************************************************************************************************************
changed: [web01]
changed: [web02]
これらの意味を理解していないと、どのタスクを実行したのか、どのターゲットに対してどのような処理が通ったのか、判断が付かないと思います。
必ずステータス値の意味合いを理解し、playbook実行後は以下三点を確認するようにしましょう。
・TASK [タスク名] ・・・どのタスクを実行したのか
・ステータス値: ・・・処理の結果
・[ターゲットホスト名] ・・・どのターゲットに対して処理を実行したのか
PLAY RECAP
実行結果の詳細なステータス(サマリー)が出力されるセクションです。
それぞれの項目の意味合いは以下の通りとなります。
- ok
- 対象ホストで正常に実行したタスクの数
- changed
- 対象ホストの状態を変更したタスクの数
- unreachable
- 対象ホストに接続できなかったタスクの数
- failed
- 対象ホストでエラーが発生したタスクの数
- skipped
- 対象ホストに対して、タスクの実行を飛ばした数
- rescued
- rescue ディレクティブを実行した数
- ignored
- 実行時に発生したエラーを無視したタスク数
PLAY RECAP *************************************************************************************************************************************************************
web01 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web02 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
例えば今回の出力結果でいうと、web01,02に対して、新規ユーザを追加するタスクを実行し(ok=1)、各ターゲットにユーザが追加され、ホストの状態にユーザが1名追加されるという変化が生じた(changed=1)という見方になります。
まとめ
Ansibleは非常に便利な半面、使い勝手が少々悪い部分があります。
その部分をしっかりと理解し、「なんとなく実行してなんとなく結果を判断する」といったことがないようにしましょう。
コメント