Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
7
Help us understand the problem. What is going on with this article?
@satken2

Ansibleでのエラーハンドリングなど

More than 1 year has passed since last update.

Ansibleで、通常実行でもCheck modeでもきちんとエラーを吐かずに動くようにするためには、エラーハンドリングが必須になる。

ignore_errors

ignore_errosをyesにすると、そのタスクでエラーが発生しても無視して次のタスクに進むことができる。
コマンドの実行結果を確認したい時などに使える。

test.yml
    - name: 必ず失敗するタスク
      command: /bin/false
      ignore_errors: yes

    - debug:
        msg: '手前のタスクが失敗しても、無視して次に進む'

RECAPではignoredにカウントされ、okにはならない。

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

changed_when

これを使うと、モジュール本来のchangedステータスを上書きすることができる。

test.yml
    - name: 必ず失敗するタスク
      command: /bin/false
      changed_when: no

これの実行結果は常にokだ。

failed_when

これもchanged_whenに似ていて、モジュール本来のfailedステータスを上書きすることができる。

test.yml
    - name: 必ず失敗するタスク
      command: /bin/false
      failed_when: no

上のコードはignore_errorsと似ているように思えるが、ignore_errorsがRECAPでignoredにカウントされるのに対し、上記の場合はokとカウントされる。

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

check_mode

バージョン2.2からdeprecatedになったalways_runに代わって推奨されているオプション。

これは少しややこしいが、以下のような動作になる。
check_mode: yesの場合、--checkオプションがつけられていない場合でも常にdry runになる。
check_mode: noの場合、--checkオプションがつけらている場合でも常に通常実行になる。

noにする時は、事故が起きないように気を付けよう。

block~rescue

これはプログラミング言語でいうtry~catchに近い。
エラーが発生しても全体を強制終了させることなく継続させることができる。

test.yml
tasks:
- name: Handle the error
  block:
    - debug:
        msg: 'ここは実行されます'
    - name: 必ず失敗するタスク
      command: /bin/false
    - debug:
        msg: '手前のタスクがfailになるので、このタスクまでは到達しません'
  rescue:
    - debug:
        msg: 'タスクが失敗した場合、ここが実行されます'

check modeにおけるshell/commandの挙動について

check modeで実行した場合、commandモジュールやshellモジュールは無条件でskippedのステータスになる仕様のようだ。
これはchanged_whenなどで上書きすることはできない。

このことはAnsibleの公式ドキュメントにも以下のように書かれている。
冪等性を担保したい時はCreate/Removeオプションを使えとのこと。

Check mode is supported when passing creates or removes. If running in check mode and either of these are specified, the module will check for the existence of the file and report the correct changed status. If these are not supplied, the task will be skipped.

例で示すと、以下のようなPlaybookをcheck modeで実行した時、2番目のタスクはwhenの内容に関わらず常にskippedになってしまう。
これだと、2番目のタスクが実際に実行されるかを事前に確認することができない。(Playbookを目で追えば分かるが)

test.yml
tasks:
  - name: 何かコマンドを実行
    shell: /bin/some/command/a
    register: result
    check_mode: no

  - name: 前のコマンドが失敗した時だけ実行するコマンド
    shell: /bin/some/command/b
    when: not result.rc == 0

shellやcommandは通常実行した時は常にchangedになるのだから、check modeにおいても常にchangedになるべきでは?と思うのだが、何か意図があるのだろうか。
同じことを疑問に思っている人はこことか、ここで見つけたが、どちらも結局解決はしていないようだ。

うまいやり方を知っている人は教えてください。

参考URL

https://docs.ansible.com/ansible/latest/user_guide/playbooks_error_handling.html
https://docs.ansible.com/ansible/latest/user_guide/playbooks_checkmode.html

7
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
satken2
SIerのインフラエンジニア。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
7
Help us understand the problem. What is going on with this article?