How to print command output in Ansible when there is a condition?

Viewed 4182

My ansible code looks something like the following. Problem is this only works when my inventory has dev,qa, perf and prod servers. For example, if my inventory has only dev servers then it fails. Is there any way to avoid this failure ?

I tried changing both cmd_dev_out and cmd_qa_out to cmd_out but that did not help either.


- name: Execute
  hosts: all
  tasks:
    - name: Execute against dev
      shell: some command
      register: cmd_dev_out
      when: ( servers are dev )

    -  debug: msg="{{ cmd_dev_out }}"

    - name: Execute against qa
      shell: some command
      register: cmd_qa_out
      when: ( servers are qa )

    -  debug: msg="{{ cmd_qa_out }}"

    ....... More conditions below .....
2 Answers

The best would be to use a block in here to logically group the execution of the command and the print of the output of the said command.

Because, if there is no command run, well, obviously you won't get anything as a result.

This is an example using block

- name: Execute
  hosts: all
  tasks:
    - block:
        - name: Execute against dev
          shell: 'echo "dev"'
          register: cmd_dev_out

        -  debug: 
             msg: "{{ cmd_dev_out }}"
      when: "'dev' in inventory_hostname"

    - block:
        - name: Execute against qa
          shell: 'echo "qa"'
          register: cmd_qa_out

        -  debug: 
             msg: "{{ cmd_qa_out }}"
      when: "'qa' in inventory_hostname"

Mind that this means that the condition when is now tied to the block and both the command and the debug will be skipped when the condition is false.

Example of recap:

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

TASK [Execute against dev] *********************************************************************************************************************************************************************************
skipping: [localhost]

TASK [debug] ***********************************************************************************************************************************************************************************************
skipping: [localhost]

TASK [Execute against qa] **********************************************************************************************************************************************************************************
changed: [localhost]

TASK [debug] ***********************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": {
        "changed": true,
        "cmd": "echo \"qa\"",
        "delta": "0:00:00.004859",
        "end": "2020-06-12 21:02:07.750651",
        "failed": false,
        "rc": 0,
        "start": "2020-06-12 21:02:07.745792",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "qa",
        "stdout_lines": [
            "qa"
        ]
    }
}

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

Another, but maybe less elegant solution would be to use the default Jinja filter on your command result in case the command was skipped.

- name: Execute
  hosts: all
  tasks:
    - name: Execute against dev
      shell: 'echo "dev"'
      register: cmd_dev_out
      when: "'dev' in inventory_hostname"

    -  debug: 
         msg: "{{ cmd_dev_out | default('cmd_dev was skipped') }}"
      
    - name: Execute against qa
      shell: 'echo "qa"'
      register: cmd_qa_out
      when: "'qa' in inventory_hostname"

    -  debug: 
         msg: "{{ cmd_qa_out | default('cmd_qa was skipped') }}"     

Figured out another solution. Its given below (add the when condition to the debug statement) :

- name: Execute
  hosts: all
  tasks:
    - name: Execute against dev
      shell: some command
      register: cmd_dev_out
      when: ( servers are dev )

    -  debug: msg="{{ cmd_dev_out }}"
       when: ( servers are dev )

    - name: Execute against qa
      shell: some command
      register: cmd_qa_out
      when: ( servers are qa )

    -  debug: msg="{{ cmd_qa_out }}"
       when: ( servers are qa )
    ....... More conditions below .....
Related