How to avoid repeating when conditionals in ansible? - ansible

I have this playbook:
---
- name: Test
hosts: localhost
tasks:
- name: Ansible grep pattern with ignore_errors example
shell: "grep 'authorization' /tmp/junk.test"
register: grep_output
ignore_errors: true
- name: Output debug grep_output
debug:
var: grep_output
verbosity: 0
shell: "echo 'Hello!'"
when: grep_output.failed
When I run it I get this error:
ERROR! conflicting action statements: debug, shell
So I have to rewrite the playbook to look like this:
---
- name: Test
hosts: localhost
tasks:
- name: Ansible grep pattern with ignore_errors example
shell: "grep 'authorization' /tmp/junk.test"
register: grep_output
ignore_errors: true
- name: Output debug grep_output
debug:
var: grep_output
verbosity: 0
when: grep_output.failed
- name: Echo hello
shell: "echo 'Hello!'"
when: grep_output.failed
So I am repeating the when: grep_output.failed. Is there a better way of writing the above playbook?
Thanks

You can use the block statement. It allows you to group modules and use a single when statement for the entire block.
This should work:
---
- name: Test
hosts: localhost
tasks:
- name: Ansible grep pattern with ignore_errors example
shell: "grep 'authorization' /tmp/junk.test"
register: grep_output
ignore_errors: true
- block:
- name: Output debug grep_output
debug:
var: grep_output
verbosity: 0
- name: Echo hello
shell: "echo 'Hello!'"
when: grep_output.failed

Related

ansible: I am not getting the entire error message for task

I have a ansible playbook for testing like this
---
- name: "test"
hosts: localhost
tasks:
- name: "list files"
block:
- name: "list files"
command: /usr/bin/example-command -x -y -z
register: output
rescue:
- script: test.py {{ output.msg }}
args:
executable: python3
and it will fail, I want to capture the error msg and send it to python script, test.py (for now, I just write the msg to a file
import sys
with open("/tmp/workfile", "w") as f:
f.write(sys.argv[1])
executing the playbook and I looked at the /tmp/workfile, I got
[Errno
Why am I not getting the entire error message?
Thanks
You need to quote the argument to your script. Consider the following playbook:
---
- name: test
hosts: localhost
gather_facts: false
vars:
output:
msg: This is a test.
tasks:
- script: test.py {{ output.msg }}
args:
executable: python3
register: script1
- script: test.py "{{ output.msg }}"
args:
executable: python3
register: script2
- debug:
msg:
- "{{ script1.stdout }}"
- "{{ script2.stdout }}"
Where test.py is simply:
import sys
print('argv[1]: ', sys.argv[1])
The final task outputs:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
"argv[1]: This\n",
"argv[1]: This is a test.\n"
]
}

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

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 .....
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.002641'
end: '2023-01-25 20:51:04.049532'
failed: false
msg: ''
rc: 0
start: '2023-01-25 20:51:04.046891'
stderr: ''
stderr_lines: []
stdout: qa
stdout_lines:
- qa
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 .....

ansible ERROR! conflicting action statements: hosts, command while running

- name: test
hosts: all
gather_facts: no
tasks:
#command 1
- name: ansible-test command 1
iosxr_command:
commands:
- show inventory
when: ansible_network_os == 'iosxr'
register: output
- debug:
var: output.stdout
- name: print command executed
hosts: 127.0.0.1
connection: local
command:
- echo sh inventory
register: output1
- debug:
var: output1.stdout
this is my playbook
ERROR! conflicting action statements: hosts, command
The error appears to be in '/root/container/playbook2.yaml': line 16, column 5, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: print command executed
^ here
I am encountering this error.
Please help me fix the issue.
Indents. You need to start a new play with a new set of hosts and a new task list.
- name: test
hosts: all
gather_facts: no
tasks:
#command 1
- name: ansible-test command 1
iosxr_command:
commands:
- show inventory
when: ansible_network_os == 'iosxr'
register: output
- debug:
var: output.stdout
- name: print command executed
hosts: 127.0.0.1
connection: local
gather_facts: no
tasks:
- command: echo sh inventory
register: output1
- debug:
var: output1.stdout

ansible ERROR! conflicting action statements: var, include_tasks

Following is my code:
- hosts: 11RRvEPG01
gather_facts: no
vars_files:
- /etc/ansible/epg/epg_command.yml
vars:
- output: []
tasks:
- name: run epg command
eric_eccli_command:
commands: "{{item}}"
with_items: "{{epg_command}}"
register: command_output
- name: show execution output
include_tasks:
file: /etc/ansible/epg_check_output.yml
var:
output: "{{item.stdout|last}}"
with_items: "{{command_output.results}}"
I got an error message when I ran it:
ERROR! conflicting action statements: var, include_tasks
Correct syntax is
- name: show execution output
include_tasks:
file: /etc/ansible/epg_check_output.yml
vars:
output: "{{ item.stdout|last }}"
with_items: "{{ command_output.results }}"
(change var for vars)

Playbook is getting hanged for some time and resuming itself after that

When i used WHEN condition for block which contains a lot of tasks the playbook is getting stuck before entering into that block and staying in the hung state for a longtime.
i have added ANSIBLE_SSH_PIPELINING=True in ansible.cfg, but it's not working.
- block:
- block:
- name: Interface Status Details
include: interface_details.yml
register: result
- name: Interface Result Global
set_fact:
LowerCaseResult: "{{ result.stdout }}
- debug: var=LowerCaseResult
- block:
- name: Calling Dependency Playbook
include: one_test.yml
register: result
- debug: var=result
when: "'is up' in LowerCaseResult"
- block:
- name: Calling Dependency Playbook
include: two_test.yml
register: cmd_result
- debug: var= cmd_result
when: "'is up' not in LowerCaseResult"
when: true
Debug is not printing the playbook is getting stuck for a long time no error message is produced.
(ansible 2.7.9)
ansible-lint does not complain about nested block (interesting!) See nested blocks lose conditions on parent blocks #12395 (ansible locked and limited conversation to collaborators on Apr 25) This might cause problems until resolved.
Problems in the code
1) Nothing is registered by include use include_tasks
- name: Interface Status Details
include_tasks: interface_details.yml
register: result
2) The closing quotation is missing; If there is no stdout in this result the task will fail
- name: Interface Result Global
set_fact:
LowerCaseResult: "{{ result.stdout }}
correct, set default to 'is NOT up'
- name: Interface Result Global
set_fact:
LowerCaseResult: "{{ result.stdout|default('is NOT up') }}"
3) Extra space after var=
- debug: var= cmd_result
correct
- debug: var=cmd_result
The play below might be working
- hosts: localhost
tasks:
- block:
- block:
- name: Interface Status Details
include_tasks: interface_details.yml
register: result
- debug: var=result
- name: Interface Result Global
set_fact:
LowerCaseResult: "{{ result.stdout|default('is NOT up') }}"
- debug: var=LowerCaseResult
- block:
- name: Calling Dependency Playbook
include_tasks: one_test.yml
register: result
- debug: var=result
when: "'is up' in LowerCaseResult"
- block:
- name: Calling Dependency Playbook
include_tasks: two_test.yml
register: cmd_result
- debug: var=cmd_result
when: "'is up' not in LowerCaseResult"
when: true

Resources