3
votes

My Ansible Task is getting failed with false when condition ( Task should fail only if "when" condition is true)

My Playbook

    - name: 'Check if any task is existing'
      command: aws ecs list-tasks --cluster mycluster --query length(taskArns[*])
      register: ecs_tasks

    - name: 'Fail playbook if some task is already existing in cluster'
      fail:
        msg: "There is already an existing task in mycluster"
      when: ecs_tasks.stdout != 0

    - name: 'Create Ranger task'
      command: create ECS task
      register: ecs_task

Output

    "stderr": "", 
    "stderr_lines": [], 
    "stdout": "0", 
    "stdout_lines": [
        "0"
    ]
    }

    TASK [Fail playbook if some task is already existing in cluster] ***************
    task path: /home/somepath/Task.yml:35
    fatal: [127.0.0.1]: FAILED! => {
    "changed": false, 
    "msg": "There is already an existing task in mycluster"
    }

    PLAY RECAP *********************************************************************
09:09:38  127.0.0.1                  : ok=5    changed=4    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0    

Is it some issue with my when Condition format, because i have tried various conditions like >0 and >=1, but no luck as it is still failing for (No tasks exists in my ECS cluster) and also AWS CLI Command returns

aws ecs list-tasks --cluster mycluster --query length(taskArns[*])
0
2

2 Answers

2
votes

The issue is that you are comparing a string (in your registered output) to an int (in your when clause). You should change your when condition to:

when: ecs_tasks.stdout != "0"

Moreover, you do not need a second task to verify for failure as you can easily use the failed_when condition on your first task:

    - name: 'Check if any task is existing'
      command: aws ecs list-tasks --cluster mycluster --query length(taskArns[*])
      register: ecs_tasks
      failed_when: ecs_tasks.stdout != "0"

Side notes:

  • It is usually a good practice to still check for the command return code if it is still meaningful so that you don't unnecessarily parse output that could be misinterpreted. In your case, I guess you can easily change your condition to (note that rc is an int):

    failed_when: ecs_tasks.rc != 0 or ecs_tasks.stdout != "0"
    

    if your command has several return codes that can be considered as successful (e.g. 0 and 2), you can change to

    failed_when: ecs_tasks.rc not in [0,2] or ecs_tasks.stdout != "0"
    
  • You could be tempted to cast your output comparison as int like:

    ecs_tasks.stdout | int != 0
    

    This should work, but be aware that any string value in sdtout not parseable as an int will lead to O, e.g.:

    $ ansible localhost -m debug -a msg="{{ 'whatever' | int }}"
    localhost | SUCCESS => {
    "msg": "0"
    }
    
0
votes

Either of below should work :

- name: 'Fail playbook if some task is already existing in cluster'
  fail:
    msg: "There is already an existing task in mycluster"
  when: ecs_tasks.stderr | length > 0

Or

- name: 'Fail playbook if some task is already existing in cluster'
  fail:
    msg: "There is already an existing task in mycluster"
  when: ecs_tasks.stderr != ""

Refer more here : How to test that a registered variable is not empty?