Akif
Akif

Reputation: 6776

Ansible shell module does not recognize "failed" attribute on a failed task

Following code results 'dict object' has no attribute 'failed' error:

shell module:

- hosts: localhost
  tasks:
    - shell: "not_available_command"
      register: module_result
      until: module_result.failed == false
      retries: 2
      delay: 1

Result:

fatal: [localhost]: FAILED! => {
"failed": true, 
"msg": "The conditional check 'module_result.failed == false' failed. The error was: error while evaluating conditional (module_result.failed == false): 'dict object' has no attribute 'failed'"

}

But when I changed the syntax of until as:

      until: module_result.stderr == ""

It successfully retries. I executed it with -vvv option for debugging; after 2 retries it failed as expected:

fatal: [localhost]: FAILED! => {
"attempts": 2, 
"changed": true, 
"cmd": "not_available_command", 
"delta": "0:00:00.010290", 
"end": "2017-09-25 17:28:14.078318", 
"failed": true, 
"invocation": {
    "module_args": {
        "_raw_params": "not_available_command", 
        "_uses_shell": true, 
        "chdir": null, 
        "creates": null, 
        "executable": null, 
        "removes": null, 
        "warn": true
    }
}, 
"rc": 127, 
"start": "2017-09-25 17:28:14.068028", 
"stderr": "/bin/sh: 1: not_available_command: not found", 
"stderr_lines": [
    "/bin/sh: 1: not_available_command: not found"
], 
"stdout": "", 
"stdout_lines": []

}

As seen both failed or stderr attributes are existed however failed is not recognized when tried to define until syntax.

Let's try with a different module:

get_url module:

- hosts: localhost
  tasks:
    - get_url:
        url: "http://unavailable_file_on_the_web.txt"
        dest: "{{ playbook_dir }}"
      register: module_result
      until: module_result.failed == false
      retries: 2
      delay: 1

This time until: module_result.failed == false syntax works; 'failed' attribute is recognized.

So how to identify this issue on modules? Does it seem to be a bug?

Upvotes: 3

Views: 1526

Answers (1)

Konstantin Suvorov
Konstantin Suvorov

Reputation: 68239

Yes, it seems like a bug or not expected behaviour: failed field is not populated during intermediate attempts. You can inspect it with ANSIBLE_DEBUG=1:

{
  "changed": true,
  "end": "2017-09-25 13:01:17.269225",
  "stdout": "",
  "cmd": "not_available_command",
  "rc": 127,
  "start": "2017-09-25 13:01:17.257604",
  "stderr": "/bin/sh: not_available_command: command not found",
  "delta": "0:00:00.011621",
  "invocation": {
    "module_args": {
      "warn": true,
      "executable": null,
      "_uses_shell": true,
      "_raw_params": "not_available_command",
      "removes": null,
      "creates": null,
      "chdir": null
    }
  },
  "warnings": []
}

In Ansible 2.4 the failed field is present.

For your information there are task result tests like failed/succeeded.
You can use them in your when/until statements:

until: module_result | succeeded

This works well in 2.2.x and 2.3.x.

Upvotes: 4

Related Questions