Ashar
Ashar

Reputation: 3245

How to use Ansible fail modules to print multiple custom messages

I want my playbook to fail under two conditions.

  1. If the SQL query's results is not returned by the database
  2. If the SQL query's result returned has the string "775"

Below Playbook works fine and does the job.

- name: "Play 1"
  hosts: localhost
   - name: "Search for Number"
     command: >
       mysql --user="{{ DBUSER }}" --password="{{ DBPASS }}" deployment
       --host=localhost --batch --skip-column-names
       --execute="SELECT num FROM deploy_tbl"     
     register: command_result 
     failed_when: command_result.stdout is search('775') or command_result.rc != 0
     when: Layer == 'APP'  

I now wanted to print custom messages for both the conditions so I added the below lines after the above playbook code.

   - name: Make Sure the mandatory input values are passed 
     fail:
       msg: "This REQ is already Deployed. Hence retry with a Unique Number."
     when: command_result.stdout is search('775')

   - name: Make Sure the mandatory input values are passed 
     fail:
       msg: "Database is not reachable."
     when: command_result.rc != 0 

This give me syntax error when running the playbook.

I'm on the latest version of Ansible.

Can you please tell me how can we update my plabook to print either of the custom message based on condition check ?

Upvotes: 2

Views: 4967

Answers (1)

Zeitounator
Zeitounator

Reputation: 44615

You should probably post your entire playbook at once in a single code block because there are absolutely no syntax problems in the bits you pasted out.

Meanwhile, if you want to achieve your requirement, you first have to understand that, by default, your playbook will stop as soon as an error is raised on a task. So in your case, the fail tasks will never be played as they are after the failing task.

One way to go around this problem would be to use ignore_error on your task.

In most cases, I find that blocks and their error handling feature are better suited to handle such scenarios.

  • The example below uses a block. I faked the sql call with a playbook var (that you can modify to play around) and a debug task using the same when conditions as yours.
  • I also modified the way to call fail so that you only have to do it once with the ternary filter.
  • If you are not familiar with the >- notation in yaml, have a look at a definition of scalar blocks. I used that to limit line length and ease readability.
---
- hosts: localhost
  gather_facts: false

  vars:
    command_result:
      stdout: "775"
      rc: "0"

  tasks:
    - block:
       - name: Fake task to mimic sql query
         debug:
           var: command_result
         failed_when: command_result.stdout is search('775') or command_result.rc != 0

      rescue:
        - name: Make Sure the mandatory input values are passed
          fail:
            msg: >-
              {{
                command_result.stdout is search('775') |
                ternary(
                  "This REQ is already Deployed. Hence retry with a Unique Number.",
                  "Database is not reachable."
                )
              }}

which gives:

PLAY [localhost] *********************************************************************

TASK [Fake task to mimic sql query] **************************************************
fatal: [localhost]: FAILED! => {
    "command_result": {
        "rc": "0",
        "stdout": "775"
    },
    "failed_when_result": true
}

TASK [Make Sure the mandatory input values are passed] *******************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "This REQ is already Deployed. Hence retry with a Unique Number."}

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

Upvotes: 1

Related Questions