Ansibleの使い方(デバッグ編)
- 1 はじめに
- 2 検証環境
- 3 事前準備
- 4 playbookの構文をチェックする方法(–syntax-check)
- 5 デバッグメッセージを表示する方法(-v,-vv...)
- 6 タスク毎に実行を確認する方法(--step)
- 7 debugモジュールを使う方法
- 8 failモジュールを使う方法
- 9 assertモジュールを使う方法
- 10 debuggerオプションを使う方法
- Y 参考図書
- Z 参考情報
1 はじめに
本記事では、Ansibleのデバッグ方法について説明します。
2 検証環境
動作検証をするための環境は以下のとおりです。
192.168.122.0/24
control ------------------------------------- node1
.220 .87
| ホスト名 | 役割 |
|---|---|
| control | コントロールノードとして動作します。Ansibleをインストールします。 |
| node1 | ターゲットノードとして動作します。モジュールが実行されるホストです |
コントロールノード、ターゲットノードのAlmaLinux版数は以下のとおりです。
[root@server ~]# cat /etc/redhat-release AlmaLinux release 9.2 (Turquoise Kodkod)
コントロールノード、ターゲットノードのカーネル版数は以下のとおりです。
[root@server ~]# uname -r 5.14.0-284.11.1.el9_2.x86_64
3 事前準備
ansibleのインストールや公開鍵認証の設定方法などは、Ansibleの使い方(モジュール編) - hana_shinのLinux技術ブログを参照してください。
4 playbookの構文をチェックする方法(–syntax-check)
–syntax-checkは、playbookの構文をチェックするオプションです。構文をチェックするだけで、playbookの実行はしません。
テスト用のplaybookを作成します。このplaybookに誤りはありません。
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
tasks:
- name: The output of magic variables
ansible.builtin.debug:
msg: The name of playbook is {{ ansible_play_name }}--syntax-checkオプションを付けて、playbookを実行します。
[root@control ~]# ansible-playbook -i hosts.ini test.yml --syntax-check playbook: test.ym
意図的にmsgの開始位置を左にずらして、debugモジュールと同じ位置にしてみます。
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
tasks:
- name: The output of magic variables
ansible.builtin.debug:
msg: The name of playbook is {{ ansible_play_name }}--syntax-checkオプションを付けて、playbookを実行すると、構文エラーが発生していることがわかります。
[root@control ~]# ansible-playbook -i hosts.ini test.yml --syntax-check
ERROR! conflicting action statements: debug, msg
The error appears to be in '/root/test.yml': line 4, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
tasks:
- name: The output of magic variables
^ here
5 デバッグメッセージを表示する方法(-v,-vv...)
-vはデバッグメッセージを出力するオプションです。vの個数は最大6個(-vvvvvv)まで指定できます。-vがデバックメッセージを最も簡潔に出力します。vの数が多くなると、デバッグメッセージをより詳細に出力します。-vvvからネットーワークに関するデバッグメッセージが出力されます。
-vを指定してplaybookを実行すると、デバッグメッセージが出力されていることがわかります。
[root@control ~]# ansible-playbook -i hosts.ini test.yml -v
Using /etc/ansible/ansible.cfg as config file
PLAY [Sample Playbook] ******************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.122.220]
TASK [Execute the hostname command] *****************************************************************************************************
changed: [192.168.122.220] => {"changed": true, "cmd": ["/usr/bin/hostname"], "delta": "0:00:00.007782", "end": "2024-02-24 22:11:47.767717", "msg": "", "rc": 0, "start": "2024-02-24 22:11:47.759935", "stderr": "", "stderr_lines": [], "stdout": "node1", "stdout_lines": ["node1"]}
PLAY RECAP ******************************************************************************************************************************
192.168.122.220 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@control ~]#
6 タスク毎に実行を確認する方法(--step)
--stepは、Ansible Playbookを実行する際に、各タスクごとにユーザーに対して処理を続けるか中断するかを確認するオプションです。このオプションを使用すると、Playbookの実行中に各タスクが開始される前に、ユーザーに確認メッセージが表示されます。
テスト用のplaybookを作成します。
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
tasks:
- name: Display nodename
ansible.builtin.debug:
msg: "The name of the remote host is {{ ansible_facts.nodename }}"
- name: Display kernel version
ansible.builtin.debug:
msg: "The kernel version of the remote host is {{ ansible_facts.kernel }}" --stepオプションを指定してplaybookを実行します。各タスクで以下のいずれかを押下します。
・n:タスクを実行しません。
・y:タスクを実行します。
・c:最後のタスクまで自動で実行します。
以下の例では、最初にyを押下して、リモートホストからファクトを収集します。その後、2回ともyを押下してタスクを実行しています。ちなみに、ファクトの収集に対してNを押下すると、リモートホストからホスト名等のファクトを入手できないので、その後のタスクの実行は失敗します。
[root@control ~]# ansible-playbook -i hosts.ini test.yml --step
PLAY [Sample Playbook] ***********************************************************************************
Perform task: TASK: Gathering Facts (N)o/(y)es/(c)ontinue: y
Perform task: TASK: Gathering Facts (N)o/(y)es/(c)ontinue: ***********************************************
TASK [Gathering Facts] ***********************************************************************************
ok: [192.168.122.220]
Perform task: TASK: Display nodename (N)o/(y)es/(c)ontinue: y
Perform task: TASK: Display nodename (N)o/(y)es/(c)ontinue: **********************************************
TASK [Display nodename] **********************************************************************************
ok: [192.168.122.220] => {
"msg": "The name of the remote host is node1"
}
Perform task: TASK: Display kernel version (N)o/(y)es/(c)ontinue: y
Perform task: TASK: Display kernel version (N)o/(y)es/(c)ontinue: ****************************************
TASK [Display kernel version] ****************************************************************************
ok: [192.168.122.220] => {
"msg": "The kernel version of the remote host is 5.14.0-284.11.1.el9_2.x86_64"
}
PLAY RECAP ***********************************************************************************************
192.168.122.220 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@control ~]#
7 debugモジュールを使う方法
debugは、playbookの実行中にメッセージを表示し、変数や式のデバッグするためのモジュールです。詳細は、ansible.builtin.debug module -- Print statements during execution — Ansible Core Documentationを参照してください。
7.1 msgパラメータを使う方法
マジック変数を標準出力に出力するplaybookファイルを作成します。マジック変数とは、Ansible がシステム内の状態を反映する変数です。ユーザーはマジック変数に値を設定することはできません。ここでは、playbookの名前を保持するマジック変数(ansible_play_name)の値を出力してみます。マジック変数は、特別な変数 — Ansible Documentationを参照してください。
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
tasks:
- name: The output of magic variables
ansible.builtin.debug:
msg: The name of playbook is {{ ansible_play_name }}playbookを実行すると、プレイブックの名前(Sample Playbook)が表示れていることがわかります。
[root@control ~]# ansible-playbook -i hosts.ini test.yml
PLAY [Sample Playbook] *****************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************
ok: [192.168.122.220]
TASK [The output of magic variables] ***************************************************************************************
ok: [192.168.122.220] => {
"msg": "The name of playbook is Sample Playbook"
}
PLAY RECAP *****************************************************************************************************************
192.168.122.220 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@control ~]#
7.2 varパラメータを使う方法
次の内容のplaybookファイルを作成します。commandモジュールに対してhostnameコマンドをパラメータとして渡し、registerディレクティブを使ってhostnameコマンドの実行結果をresult変数に格納します。そして、その後のタスクでdebugモジュールを実行してhostnameコマンドの実行結果を表示します。
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
tasks:
- name: Execute the hostname command
shell: /usr/bin/hostname
register: result
- name: Print return information from the previous task
ansible.builtin.debug:
var: resultplaybookを実行すると、hostnameコマンドの実行結果が表示れていることがわかります。
[root@control ~]# ansible-playbook -i hosts.ini test.yml
PLAY [Sample Playbook] ******************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.122.220]
TASK [Execute the hostname command] *****************************************************************************************************
changed: [192.168.122.220]
TASK [Print return information from the previous task] **********************************************************************************
ok: [192.168.122.220] => {
"result": {
"changed": true,
"cmd": "/usr/bin/hostname",
"delta": "0:00:00.011434",
"end": "2024-02-24 20:57:19.969301",
"failed": false,
"msg": "",
"rc": 0,
"start": "2024-02-24 20:57:19.957867",
"stderr": "",
"stderr_lines": [],
"stdout": "node1",
"stdout_lines": [
"node1"
]
}
}
PLAY RECAP ******************************************************************************************************************************
192.168.122.220 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@control ~]#実行結果のうち、ホスト名だけを表示する場合、以下のようにvar変数にresult.stdoutと指定します。
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
tasks:
- name: Execute the hostname command
shell: /usr/bin/hostname
register: result
- name: Print return information from the previous task
debug:
var: result.stdoutplaybookを実行すると、ターゲットノードのホスト名(node1)が表示れていることがわかります。
[root@control ~]# ansible-playbook -i hosts.ini test.yml
PLAY [Sample Playbook] ******************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.122.220]
TASK [Execute the hostname command] *****************************************************************************************************
changed: [192.168.122.220]
TASK [Print return information from the previous task] **********************************************************************************
ok: [192.168.122.220] => {
"result.stdout": "node1"
}
PLAY RECAP ******************************************************************************************************************************
192.168.122.220 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@control ~]#
7.3 verbosityパラメータを使う方法
verbosityは、出力メッセージを詳細に表示するパラメータです。しかし、以下のようなplaybookを作成して実行してみましたが、私の環境では、デバッグメッセージが表示されませんでした。
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
tasks:
- name: Execute the hostname command
ansible.builtin.command:
cmd: /usr/bin/hostname
register: var_hostname
- name: Display hostname command result
ansible.builtin.debug:
var: var_hostname
verbosity: 1playbookを実行します。デバッグメッセージは表示されませんでした。
[root@control ~]# ansible-playbook -i hosts.ini test.yml PLAY [Sample Playbook] ****************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************** ok: [192.168.122.220] TASK [Execute the hostname command] ***************************************************************************************************** changed: [192.168.122.220] TASK [Display hostname command result] ************************************************************************************************** skipping: [192.168.122.220] PLAY RECAP ****************************************************************************************************************************** 192.168.122.220 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 [root@control ~]#
8 failモジュールを使う方法
failは、特定の条件が満たされた場合に、Playbookの実行を中止し、エラーメッセージを表示するモジュールです。
8.1 ファイルの状態を使った例
以下の処理を実行するplaybookを作成します。
・/tmp/test.txtが存在する場合:エラーメッセージ(File does't exist)を表示しない
・/tmp/test.txtが存在しない場合:エラーメッセージ(File does't exist)を表示する
なお、statモジュールについては、Ansibleの使い方(モジュール編) - hana_shinのLinux技術ブログを参照してください。
(1) その1(条件に一致しない場合)
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
tasks:
- name: Check the status of /tmp/test.txt
ansible.builtin.stat:
path: /tmp/test.txt
register: result
- name: Fail if /tmp/test.txt does not exist
ansible.builtin.fail:
msg: "File doesn't exist"
when: not result.stat.existsターゲットノードでテスト用のファイルを作成します。
[root@node1 ~]# touch /tmp/test.txt
playbookを実行します。/tmp/test.txtが存在するので、エラーメッセージが表示されないことがわかります。
[root@control ~]# ansible-playbook -i hosts.ini test.yml PLAY [Sample Playbook] ************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************* ok: [192.168.122.220] TASK [Check the status of /tmp/test.txt] ******************************************************************************************* ok: [192.168.122.220] TASK [if /tmp/test.txt does not exist] ********************************************************************************************* skipping: [192.168.122.220] PLAY RECAP ************************************************************************************************************************* 192.168.122.220 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 [root@control ~]#
(2) その2(条件に一致する場合)
ターゲットノードでテスト用ファイルを削除します。
[root@node1 ~]# rm /tmp/test.txt rm: 通常の空ファイル '/tmp/test.txt' を削除しますか? y
playbookを実行します。/tmp/test.txtが存在しないので、エラーメッセージが表示されていることがわかります。
[root@control ~]# ansible-playbook -i hosts.ini test.yml
PLAY [Sample Playbook] *************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************
ok: [192.168.122.220]
TASK [Check the status of /tmp/test.txt] *******************************************************************************************
ok: [192.168.122.220]
TASK [if /tmp/test.txt does not exist] *********************************************************************************************
fatal: [192.168.122.220]: FAILED! => {"changed": false, "msg": "File does't exist"}
PLAY RECAP *************************************************************************************************************************
192.168.122.220 : ok=2 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
[root@control ~]#
8.2 ファイルサイズを使った例
以下の処理を実行するplaybookを作成します。
・ファイルサイズが3バイト未満の場合:ファイルサイズを表示してplaybookを中断する
・ファイルサイズが3バイト以上の場合:正常終了する
(1) その1(条件に一致する場合)
以下の処理を実行するplaybookを作成します。
・ファイルサイズが3バイト未満の場合:ファイルサイズを表示してplaybookを中断する
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
tasks:
- name: Check the status of /tmp/test.txt
ansible.builtin.stat:
path: /tmp/test.txt
register: result
- name: Fail if /tmp/test.txt size is less than 3 bytes
ansible.builtin.fail:
msg: "File size is {{ result.stat.size }} bytes"
when: result.stat.size < 3ターゲットノードでテスト用のファイル(2byte)を作成します。
[root@node1 ~]# echo 0 > /tmp/test.txt [root@node1 ~]# ls -l /tmp/test.txt -rw-r--r--. 1 root root 2 2月 25 22:22 /tmp/test.txt
playbookを実行します。ファイルサイズが2バイトである旨を表示して、playbookを終了していることがわかります。
[root@control ~]# ansible-playbook -i hosts.ini test.yml
PLAY [Sample Playbook] *************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************
ok: [192.168.122.220]
TASK [Check the status of /tmp/test.txt] *******************************************************************************************
ok: [192.168.122.220]
TASK [if /tmp/test.txt does not exist] *********************************************************************************************
fatal: [192.168.122.220]: FAILED! => {"changed": false, "msg": "File size is 2 byte "}
PLAY RECAP *************************************************************************************************************************
192.168.122.220 : ok=2 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
[root@control ~]#(2) その2(条件に一致しない場合)
ターゲットノードでテスト用のファイル(4byte)を作成します。
[root@node1 ~]# echo 012 > /tmp/test.txt [root@node1 ~]# ls -l /tmp/test.txt -rw-r--r--. 1 root root 4 2月 25 22:25 /tmp/test.txt
playbookを実行します。playbookが正常終了していることがわかります。
[root@control ~]# ansible-playbook -i hosts.ini test.yml PLAY [Sample Playbook] ************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************* ok: [192.168.122.220] TASK [Check the status of /tmp/test.txt] ******************************************************************************************* ok: [192.168.122.220] TASK [if /tmp/test.txt does not exist] ********************************************************************************************* skipping: [192.168.122.220] PLAY RECAP ************************************************************************************************************************* 192.168.122.220 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 [root@control ~]#
9 assertモジュールを使う方法
assertは、条件に一致しない場合、Playbookの実行を中止しエラーメッセージを表示するモジュールです。詳細は、ansible.builtin.assert module -- Asserts given expressions are true — Ansible Core Documentationを参照してください。
以下の処理を実行するplaybookを作成します。
・ファイルサイズが3バイト未満の場合:ファイルサイズを表示してplaybookを中断する
・ファイルサイズが3バイト以上の場合:正常終了する
(1) その1(条件に一致する場合)
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
tasks:
- name: Check the status of /tmp/test.txt
ansible.builtin.stat:
path: /tmp/test.txt
register: result
- name: Fail if /tmp/test.txt size is less than 3 bytes
ansible.builtin.assert:
that:
- result.stat.size >= 3
fail_msg: "The file size is less than 3 bytes. The process will be aborted"ターゲットノードでテスト用のファイル(4byte)を作成します。
[root@node1 ~]# echo 012 > /tmp/test.txt [root@node1 ~]# ls -l /tmp/test.txt -rw-r--r--. 1 root root 4 2月 25 22:25 /tmp/test.txt
playbookを実行します。
[root@control ~]# ansible-playbook -i hosts.ini test.yml
PLAY [Sample Playbook] *************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************
ok: [192.168.122.220]
TASK [Check the status of /tmp/test.txt] *******************************************************************************************
ok: [192.168.122.220]
TASK [if /tmp/test.txt does not exist] *********************************************************************************************
ok: [192.168.122.220] => {
"changed": false,
"msg": "All assertions passed"
}
PLAY RECAP *************************************************************************************************************************
192.168.122.220 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@control ~]#(2) その2(条件に一致しない場合)
ターゲットノードでテスト用のファイル(2byte)を作成します。
[root@node1 ~]# echo 0 > /tmp/test.txt [root@node1 ~]# ls -l /tmp/test.txt -rw-r--r--. 1 root root 2 2月 25 23:14 /tmp/test.txt
playbookを実行します。
[root@control ~]# ansible-playbook -i hosts.ini test.yml
PLAY [Sample Playbook] **************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************
ok: [192.168.122.220]
TASK [Check the status of /tmp/test.txt] ********************************************************************************
ok: [192.168.122.220]
TASK [Fail if /tmp/test.txt size is less than 3 bytes] ******************************************************************
fatal: [192.168.122.220]: FAILED! => {
"assertion": "result.stat.size >= 3",
"changed": false,
"evaluated_to": false,
"msg": "The file size is less than 3 bytes. The process will be aborted"
}
PLAY RECAP **************************************************************************************************************
192.168.122.220 : ok=2 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
[root@control ~]#
10 debuggerオプションを使う方法
debuggerオプションは、playbook実行中、デバッガを起動するオプションです。gdbやcrash等のデバッガと同じように、playbookのステップ実行や変数の値を確認したりすることができます。
playbookを作成します。このとき、"debugger: always"という1行を記載します。
[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
hosts: node1
debugger: always
tasks:
- name: Install the latest version of Apache
ansible.builtin.dnf:
name: httpd
state: latestplaybookを実行します。以下は、hコマンドを押下して、デバッガのヘルプを表示してるところです。
[root@control ~]# ansible-playbook -i hosts.ini test.yml PLAY [Sample Playbook] ***************************************************************************************************************** TASK [Gathering Facts] ***************************************************************************************************************** ok: [192.168.122.220] [192.168.122.220] TASK: Gathering Facts (debug)> h Documented commands (type help <topic>): ======================================== EOF c continue h help p pprint q quit r redo u update_task [192.168.122.220] TASK: Gathering Facts (debug)>
ここでは、cを押下してplaybookの処理を先に進めてみます。最初のc押下でファクトの収集、2つ目のc押下でhttpdパッケージをインストールしています。
[192.168.122.220] TASK: Gathering Facts (debug)> c TASK [Install the latest version of Apache] ******************************************************************************************** ok: [192.168.122.220] [192.168.122.220] TASK: Install the latest version of Apache (debug)> c PLAY RECAP ***************************************************************************************************************************** 192.168.122.220 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@control ~]#
Y 参考図書
本記事の作成に以下の図書を参考にしました。

Ansible実践ガイド 第4版[基礎編] impress top gearシリーズ
Z 参考情報
私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ
Ansible の使い方
Ansible Playbookとはなにか [書き方 | 基本 | YAML] - APC Automation blog


