0
0

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 1 year has passed since last update.

【Ansible】Ansible Roleでエラー処理が発生することをテストしたい

Posted at

はじめに

 Ansible Roleに、想定外の状態で停止するエラー処理を実装していること
があると思います。このエラー処理が発生することをテストするにはどうすればよいかを
考えてみました。

TL;DR

  • エラー処理が発生することをテストをするには、blockセクションでAnsible Roleを
    実行してエラーを起こし、rescueセクションでエラーの内容を確認する。
  • rescueセクションでは、変数ansible_failed_taskansible_failed_result
    エラーが発生したタスクの状況が確認可能。

前提条件

  • Ansible Roleの基本的なディレクトリ構成を理解していること。
  • Ansibleにおけるblockセクション、rescueセクションの使い方を理解していること。

実行環境

  • Python: 3.6.8
  • Ansible: 2.9.7

詳細

1. テストするAnsible Role

  • 今回はテスト用にAnsible Role「check-pass-flag」を作成しました。
    メイン処理(tasks/main.yml)はシンプルで、変数pass_flagtrueでない場合に
    エラーが発生します。
  • Ansible Roleでは、想定通りのタスクでエラーが発生するかを確認できるように、以下に注意しました。
    • タスク名は重複しないようにする
    • assertモジュールにはエラーメッセージ(fail_msg)を明示する
tasks/main.yml
---
- name: "Task1 - display pass_flag"
  debug:
    var: pass_flag

- name: "Task2 - check if pass_flag is true"
  assert:
    that:
      - pass_flag is boolean
      - pass_flag is true
    fail_msg: "This task failed because pass_flag is not true"    # エラーメッセージ

2. エラー内容の確認

2-1. エラー内容の確認用Playbook

  • ここでは、エラー内容の確認用Playbookを実行します。ポイントは以下の通りです。
    1. 変数pass_flagfalse(trueではない値)にして、あえてAnsible Roleでエラーを
      発生させる
    2. blockセクションでAnsible Roleを実行してエラーを起こし、rescueセクションで
      エラーの内容を確認する。エラーの内容は、変数ansible_failed_task
      ansible_failed_resultに格納されるので、debugモジュールで確認する
test-check-pass-flag-1.yml
---
- name: "Test Ansible Role check-pass-flag"
  hosts: localhost
  vars:
    pass_flag: false
  gather_facts: false
  tasks:
    - block:
        # ポイント1: 変数pass_flagがfalseなのでエラーが発生する
        - name: "Import check-pass-flag"
          import_role:
            name: "check-pass-flag"
      rescue:
        # ポイント2: blockでエラーが発生すると以下の処理が実行される
        - name: "Display ansible_failed_task"
          debug:
            var: ansible_failed_task

        - name: "Display ansible_failed_result"
          debug:
            var: ansible_failed_result

2-2. 変数ansible_failed_taskの確認

 Playbookを実行すると、想定通りAnsible Roleのタスク「Task2 - check if pass_flag is true」
でエラーが発生したので、まずは変数ansible_failed_taskの内容を確認します。
テストとして、エラーメッセージ(args.fail_msg)やエラーしたタスク名(name)が確認できそうです。

ansible_failed_task
---
args:
  that:
    - pass_flag is boolean
    - pass_flag is true
  fail_msg: This task failed because pass_flag is not true    # エラーメッセージ
action: assert
async_val: 0
async: 0
changed_when: []
delay: 5
delegate_to: None
delegate_facts: None
failed_when: []
loop: None
loop_control: None
notify: None
poll: 15
register: None
retries: 3
until: []
loop_with: None
name: Task2 - check if pass_flag is true    # エラーしたタスク名
# ~以下、省略~

2-3. 変数ansible_failed_resultの確認

 変数ansible_failed_resultも同様に確認します。内容はansible_failed_taskより
少ないようですが、エラーしたassert文が何かまでわかります。
テストとして、エラーしたassert文(assertion)とエラーメッセージ(msg)が確認できそうです。

ansible_failed_result
---
assertion: pass_flag is true    # エラーしたassert文
changed: false
evaluated_to: false
failed: true
msg: This task failed because pass_flag is not true    # エラーメッセージ

3. エラー処理の動作確認

3-1. エラー処理の動作確認用Playbook

  • ここでは、エラー処理の動作確認用Playbookを実行します。ポイントは以下の通りです。
    1. Ansible Roleでエラーが発生しなかった場合に備えて、failモジュールで強制的にエラーを発生させる
    2. 変数ansible_failed_taskansible_failed_resultの内容にもとづき、
      assertモジュールで想定通りのエラーが発生していることを確認する
test-check-pass-flag-2.yml
---
- name: "Test Ansible Role check-pass-flag"
  hosts: localhost
  vars:
    pass_flag: false
  gather_facts: false
  tasks:
    - block:
        # 変数pass_flagがfalseなのでエラーが発生する
        - name: "Import check-pass-flag"
          import_role:
            name: "check-pass-flag"

        # ポイント1: Ansible Roleでエラーが発生しなかった場合、ここでエラーになる
        - name: "Force fail"
          fail:
      rescue:
        # ポイント2: エラーしたタスク名とエラーメッセージを確認
        - name: "Check ansible_failed_task"
          assert:
            that:
              - ansible_failed_task.name == 'Task2 - check if pass_flag is true'
              - >-
                ansible_failed_task.args.fail_msg
                == 'This task failed because pass_flag is not true'

        # ポイント2: エラーしたassert文とエラーメッセージを確認
        - name: "Check ansible_failed_result"
          assert:
            that:
              - ansible_failed_result.assertion == 'pass_flag is true'
              - >-
                ansible_failed_result.msg
                == 'This task failed because pass_flag is not true'

3-2. Playbookの実行結果

 Playbookを実行すると、想定通りAnsible Roleのタスク「Task2 - check if pass_flag is true」
でエラーが発生していますが、rescueセクションで想定通りのエラー処理が発生していることを確認できています。

$ ansible-playbook test-check-pass-flag-2.yml

PLAY [Test Ansible Role check-pass-flag] *******************************************************************************

TASK [check-pass-flag : Task1 - display pass_flag] *********************************************************************
ok: [localhost] =>
  pass_flag: false

TASK [check-pass-flag : Task2 - check if pass_flag is true] ************************************************************
fatal: [localhost]: FAILED! => changed=false
  assertion: pass_flag is true
  evaluated_to: false
  msg: This task failed because pass_flag is not true

TASK [Check ansible_failed_task] ***************************************************************************************
ok: [localhost] => changed=false
  msg: All assertions passed

TASK [Check ansible_failed_result] *************************************************************************************
ok: [localhost] => changed=false
  msg: All assertions passed

PLAY RECAP *************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=1    ignored=0

さいごに

  • blockセクションでAnsible Roleを実行してエラーを起こし、rescueセクションで
    エラーの内容を確認することで、エラー処理の動作確認ができました。
  • Ansible Roleのテストについて、正常の動作だけでなくエラー処理の動作確認も
    することで、より品質の高いAnsible Roleが開発できるのではないかと思います。

参考URL


0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?