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
75
Help us understand the problem. What is going on with this article?
@sakaimo

ansibleでの実行結果のsuccess/failedとignore_errors/failed_whenがよくわからなかったので調べてみた

More than 5 years have passed since last update.

知りたいこと

  • ansibleでのsuccessとfailedの判定
  • それをハンドリングするための ignore_errors と failed_when の使い方

事前実験

存在しないコマンドを実行してみる

ansibleでの接続先(リモートサーバー。CentOS6)で `sakaimo --version' コマンドしてみる。ちなみに現時点のsakaimoのversionは39.7くらいのはず。

# sakaimo --version
-bash: sakaimo: command not found

CentOSさんにはこんなコマンドは存在しないのでnot foundになります。

ansibleでやってみる

playbook

- shell: sakaimo --version

- debug: msg="debug"

実行結果

PLAY [app] ********************************************************************

TASK: [sakaimo| shell sakaimo --version] *************************************
failed: [qa-lecture01] => {"changed": true, "cmd": "sakaimo --version", "delta": "0:00:00.146319", "end": "2015-05-12 10:52:53.548610", "rc": 127, "start": "2015-05-12 10:52:53.402291", "warnings": []}
stderr: /bin/sh: sakaimo: command not found

FATAL: all hosts have already failed -- aborting

PLAY RECAP ********************************************************************
           to retry, use: --limit @/root/qa-lecture-playbook.retry

qa-lecture01               : ok=0    changed=0    unreachable=0    failed=1

一つ目でエラーが出た場合に- debug: msg="debug"は実行されていないことがわかります。しれっと「エラーが出た場合」と言っていますが、何がansibleで「エラー」と判定されるのかどうかを知りたくて調べてるんですけどねw

ignore_errors

ignore_errorsを付けてみる。

playbook

- shell: sakaimo --version
  ignore_errors: True #←ここ

- debug: msg="debug"

出力結果

PLAY [app] ********************************************************************

TASK: [sakaimo | shell sakaimo --version] *************************************
failed: [qa-lecture01] => {"changed": true, "cmd": "sakaimo --version", "delta": "0:00:00.143888", "end": "2015-05-12 10:53:30.886426", "rc": 127, "start": "2015-05-12 10:53:30.742538", "warnings": []}
stderr: /bin/sh: sakaimo: command not found
...ignoring

TASK: [sakaimo | debug msg="debug"] ****************************************
ok: [qa-lecture01] => {
    "msg": "debug"
}

PLAY RECAP ********************************************************************
qa-lecture01               : ok=2    changed=1    unreachable=0    failed=0

ignore_errors: Trueでは文字通りエラーがあっても無視して先にすすんでくれるようです。(debugが出力されているから) つまりcommand not foundはエラーとして認識されるみたいね。

実行結果によって分岐させてみる

when: result|failedを付けてみた。

playbook

- shell: sakaimo --version
  register: result
  ignore_errors: True

- debug: msg="debug"
  when: result|failed #←ここ

実行結果

PLAY [app] ********************************************************************

TASK: [sakaimo | shell sakaimo --version] *************************************
failed: [qa-lecture01] => {"changed": true, "cmd": "sakaimo --version", "delta": "0:00:00.142611", "end": "2015-05-12 11:00:33.019179", "rc": 127, "start": "2015-05-12 11:00:32.876568", "warnings": []}
stderr: /bin/sh: sakaimo: command not found
...ignoring

TASK: [sakaimo | debug msg="debug"] ****************************************
ok: [qa-lecture01] => {
    "msg": "debug"
}

PLAY RECAP ********************************************************************
qa-lecture01               : ok=2    changed=1    unreachable=0    failed=0

failedをsuccessにしてみたplaybook

- shell: sakaimo --version
  register: result
  ignore_errors: True

- debug: msg="debug"
  when: result|success #←ここ

実行結果

PLAY [app] ********************************************************************

TASK: [sakaimo | shell sakaimo --version] *************************************
failed: [qa-lecture01] => {"changed": true, "cmd": "sakaimo --version", "delta": "0:00:00.144219", "end": "2015-05-12 11:01:29.798585", "rc": 127, "start": "2015-05-12 11:01:29.654366", "warnings": []}
stderr: /bin/sh: sakaimo: command not found
...ignoring

TASK: [sakaimo | debug msg="debug"] ****************************************
skipping: [qa-lecture01]

PLAY RECAP ********************************************************************
qa-lecture01               : ok=1    changed=1    unreachable=0    failed=0

resultがfailedなので、debugがskipされています。ということはcommand not foundは'failed'と判定されるということね。

TASK: [sakaimo | debug msg="debug"] ****************************************
skipping: [qa-lecture01]

では成功するコマンドだったらどうなるのか。unameコマンドで実験。

リモートサーバーでの実行結果は

# uname
Linux

になってます。

playbook

- shell: uname
  register: result
  ignore_errors: True

- debug: msg="debug"
  when: result|success

実行結果

PLAY [app] ********************************************************************

TASK: [sakaimo | shell uname] *************************************************
changed: [qa-lecture01]

TASK: [sakaimo | debug msg="debug"] *******************************************
ok: [qa-lecture01] => {
    "msg": "debug"
}

PLAY RECAP ********************************************************************
qa-lecture01               : ok=2    changed=1    unreachable=0    failed=0

successをfailedにしてみる

playbook

- shell: uname
  register: result
  ignore_errors: True

- debug: msg="debug"
  when: result|failed #←ここ

実行結果

PLAY [app] ********************************************************************

TASK: [sakaimo | shell uname] *************************************************
changed: [qa-lecture01]

TASK: [sakaimo | debug msg="debug"] *******************************************
skipping: [qa-lecture01]

PLAY RECAP ********************************************************************
qa-lecture01               : ok=1    changed=1    unreachable=0    failed=0

これにより、unameでLinuxって返ってきてることはsuccessと判断されているってことね。

failed_when

どうやらfailed_whenは「こういう時はfailedにしてね」って感じのコマンドのようです。
ansible公式サイトより

例としてこんなんが載ってるので、

- name: this command prints FAILED when it fails
  command: /usr/bin/example-command -x -y -z
  register: command_result
  failed_when: "'FAILED' in command_result.stderr"

私の例で言うと

- shell: sakaimo --version
  register: result
  failed_when: "'command not found' in result.stderr"

- debug: msg="debug"

標準エラー(stderr)に「command not found」っていう文字列が含まれていたらfailedとして判定してね、って指定しました。

実行結果

PLAY [app] ********************************************************************

TASK: [sakaimo | shell sakaimo --version] *************************************
failed: [qa-lecture01] => {"changed": true, "cmd": "sakaimo --version", "delta": "0:00:00.139589", "end": "2015-05-12 12:07:03.049756", "failed": true, "failed_when_result": true, "rc": 127, "start": "2015-05-12 12:07:02.910167", "stdout_lines": [], "warnings": []}
stderr: /bin/sh: sakaimo : command not found

FATAL: all hosts have already failed -- aborting

PLAY RECAP ********************************************************************
           to retry, use: --limit @/root/qa-lecture-playbook.retry

qa-lecture01               : ok=0    changed=0    unreachable=0    failed=1

うん、想定通りエラーになりました。そしてエラーになって処理が止まっているので、debugは出力されていません。

では今度は実行結果にerrorrrrrっていう文字列があったらfailedにするようにしてみます。

- shell: sakaimo --version
  register: result
  failed_when: "'errorrrrr'in result.stderr"

- debug: msg="debug"

にした場合、

PLAY [app] ********************************************************************

TASK: [sakaimo | shell sakaimo --version] *************************************
changed: [qa-lecture01]

TASK: [sakaimo | debug msg="debug"] *******************************************
ok: [qa-lecture01] => {
    "msg": "debug"
}

PLAY RECAP ********************************************************************
qa-lecture01               : ok=2    changed=1    unreachable=0    failed=0

となりました。errorrrrrは(リモートサーバーから)出力されていないので  successとみなされ failedではないとみなされ、次の処理に進んでdebugも表示されています。

ではwhen: result|successを追加したらどうでしょうか。

- shell: sakaimo --version
  register: result
  failed_when: "'errorrrrr'in result.stderr"

- debug: msg="debug"
  when: result|success #←ここ
PLAY [app] ********************************************************************

TASK: [sakaimo | shell sakaimo --version] *************************************
changed: [qa-lecture01]

TASK: [sakaimo | debug msg="debug"] *******************************************
skipping: [qa-lecture01]

PLAY RECAP ********************************************************************
qa-lecture01               : ok=1    changed=1    unreachable=0    failed=0

debugがskipされています。つまりresultfailedだったってことですね。

ということは、failed_whenを使って「こういう時はfailedにしてね」という指定はできるけれども、これは「それ以外のときはsuccsessだよ」という指定ではないってことですよねあたりまえかw

ためしに

- shell: sakaimo --version
  register: result
  failed_when: "'errorrrrr'in result.stderr"

- debug: msg="debug"
  when: result|failed #←ここを変えた

にして実行したら

PLAY [app] ********************************************************************

TASK: [sakaimo | shell sakaimo --version] *************************************
changed: [qa-lecture01]

TASK: [sakaimo | debug msg="debug"] *******************************************
ok: [qa-lecture01] => {
    "msg": "debug"
}

PLAY RECAP ********************************************************************
qa-lecture01               : ok=2    changed=1    unreachable=0    failed=0

になりました。

ということは

- shell: sakaimo --version
  register: result
  failed_when: "'errorrrrr'in result.stderr"

- debug: msg="debug"
  when: result|failed #←ここを変えた

において、

  • sakaimo --versionのリモートサーバーでの実行結果は-bash: sakaimo: command not found
  • だからresultにはfailedが入る (when: result|failed がtrue判定されてdebugが出力されているから)
  • なんだけどfailed_when: "'errorrrrr'in result.stderr"でfailedの条件を指定してしまっている
  • だからこの3行全体での処理結果としては「failedじゃない」(successとはいえない)けど、resultfailedなのでdebugは実行される

...あれ、頭がこんがらがってきた。

75
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
sakaimo
みなさんの記事に助けられております。私も何かお役に立てるよう頑張ります。。。 Google Apps Script、Query関数、Data Portal、たまにChromeエクステンション を使って 自動化・効率化・見える化を担当しています。社内データの可視化やデータリテラシー研修やGASレクチャーをやってます。

Comments

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