17
16

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でのエラーハンドリングなど

Last updated at Posted at 2019-08-25

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

17
16
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
17
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?