I have this ansible output got from 3 different hosts, using ansible debug module:
TASK [debug] ***************************************************************************************************************************************************************************************
ok: [10.240.22.44] => {
"msg": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": true,
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "/opt/confluent/bin/nodefirmware smm1",
"delta": "0:00:00.128325",
"end": "2020-02-05 11:22:19.435049",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "/opt/confluent/bin/nodefirmware smm1",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "10.240.18.20",
"rc": 0,
"start": "2020-02-05 11:22:19.306724",
"stderr": "",
"stderr_lines": [],
"stdout": "smm1: SMM: 1.10 (TESM14F)\nsmm1: PSOC: 0.7",
"stdout_lines": [
"smm1: SMM: 1.10 (TESM14F)",
"smm1: PSOC: 0.7"
]
},
{
"_ansible_ignore_errors": true,
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "/opt/confluent/bin/nodefirmware smm1",
"delta": "0:00:00.096292",
"end": "2020-02-05 11:22:22.847949",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "/opt/confluent/bin/nodefirmware smm1",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "10.240.19.21",
"rc": 0,
"start": "2020-02-05 11:22:22.751657",
"stderr": "",
"stderr_lines": [],
"stdout": "smm1: SMM: 1.10 (TESM14F)\nsmm1: PSOC: 0.7",
"stdout_lines": [
"smm1: SMM: 1.10 (TESM14F)",
"smm1: PSOC: 0.7"
]
}
]
}
}
I'm trying to parse this output and display in the end, for each hosts, strictly the:
"stdout_lines": [
"smm1: SMM: 1.10 (TESM14F)",
"smm1: PSOC: 0.7"
The playbook that shows the above output is this:
- debug:
msg: "{{ smm_output }}"
when: "('primary' in default_hostname or 'Primary' in default_hostname)"
tags: ['ic', 'smm']
I tried with "{{ smm_output.stdout_lines }}" but says there's not such dict object
Any clues?
You are registering the output of a looping task. Quoting the documentation:
When you register a variable in a task with a loop, the registered variable contains a value for each item in the loop. The data structure placed in the variable during the loop will contain a results attribute, that is a list of all responses from the module. For a more in-depth example of how this works, see the Loops section on using register with a loop.
To debug each stdout_lines of your respective results in smm_output you can use the following task:
- name: debug result
debug:
var: item.stdout_lines
loop: "{{ smm_output.results }}"
Ref: https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#registering-variables
Related
I have an output of a playbook and I want to debug a message based on a condition of the output. I need the key and value pairs of the item to match a when statement then I will print out the actual data.
ok: [pynet-sw5] => {
"loop_iterate": {
"changed": false,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "1.1.1.1",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"count": null,
"destination": "1.1.1.1",
"dev_os": "eos",
"hostname": "arista5.twb-tech.com",
"optional_args": null,
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"ping_timeout": null,
"provider": {
"dev_os": "eos",
"hostname": "arista5.twb-tech.com",
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"timeout": 60,
"username": "xxx"
},
"size": null,
"source": null,
"timeout": 60,
"ttl": null,
"username": "pyclass",
"vrf": null
}
},
"item": "1.1.1.1",
"results": {
"success": {
"packet_loss": 0,
"probes_sent": 5,
When I put the below statement it returns with item is not defined error.
- debug:
msg: "{{item[1].item}} is pingable from {{ansible_host}} with {{item[1].results.success.packet_loss}} out of 5 packets"
when: "item[0].key == 'packet_loss'"
with_sublements:
- "{{loop_iterate.results.results.success}}"
- "{{loop_iterate.results}}"
so is there a way of combining with_dict with with_items ? I want to use
- "{{loop_iterate.results.results.success}}" as with_dict iteration while using - "{{loop_iterate.results}}" as with_items
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?
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.
Below is the playbook i have created. I am not getting the way to store and display the output od the shell command and pass the same output to other play having different hosts.
---
- hosts: localhost
tasks:
- name: "check the connectivity with username for all the LLC servers from hosts.new file"
shell: ssh dp794d#{{ item }} "date"
register: result
with_lines: cat "/home/capio/ansible/pmossWipm/day2/logs/ipAddress.txt"
- debug: var=result
Now how can i display the result of register variable "result". I tried using the debug, but it didn't worked.
Below is the output of var=result
TASK [debug] *******************************************************************
ok: [localhost] => {
"result": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "ssh dp794d#130.6.50.131 \"date\"",
"delta": "0:00:00.237866",
"end": "2017-05-09 08:59:13.918581",
"invocation": {
"module_args": {
"_raw_params": "ssh dp794d#130.6.50.131 \"date\"",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
},
"module_name": "command"
},
"item": "130.6.50.131",
"rc": 0,
"start": "2017-05-09 08:59:13.680715",
"stderr": " _________________________________________________________________\n\n This system is restricted to ABC authorized users for business\n purposes. Unauthorized access is a violation of the law. This\n service may be monitored for administrative and security reasons.\n By proceeding, you consent to this monitoring.\n _________________________________________________________________\n\n ,
"stdout": "Tue May 9 08:59:13 EDT 2017",
"stdout_lines": [
"Tue May 9 08:59:13 EDT 2017"
],
"warnings": []
},
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "ssh dp794d#130.6.50.132 \"date\"",
"delta": "0:00:00.245660",
"end": "2017-05-09 08:59:14.430728",
"invocation": {
"module_args": {
"_raw_params": "ssh dp794d#130.6.50.132 \"date\"",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
},
"module_name": "command"
},
"item": "130.6.50.132",
"rc": 0,
"start": "2017-05-09 08:59:14.185068",
"stderr": " _________________________________________________________________\n\n This system is restricted to ABC authorized users for business\n purposes. Unauthorized access is a violation of the law. This\n service may be monitored for administrative and security reasons.\n By proceeding, you consent to this monitoring.\n _________________________________________________________________\n\n [,
"stdout": "Tue May 9 08:59:14 EDT 2017",
"stdout_lines": [
"Tue May 9 08:59:14 EDT 2017"
],
"warnings": []
}
]
}
}
You can store result to file as follows:
- copy:
content: '{{ result.results | map(attribute="stdout") | list | join("\n") }}'
dest: /tmp/out.txt
I have a sample playbook In which, I am matching host from two ansible variable using with_nested. These two variable in json format. Records are matching correctly. But due to changes in ansible 2.x its showing both matching and unmatching records in register variable.
---
- hosts: 127.0.0.1
connection: local
tasks:
- shell: "echo {{ item[0] }}"
with_nested:
- [{"host": "host1","description": "This is host1 server"}, {"host": "host2","description": "This is host2 server"}]
- [{"host_name": "host1"},{"host_name": "host2"},{"host_name": "host3"},{"host_name":"host4"}]
register: all_hosts
when: item[0].host == item[1].host_name
- debug: var=all_hosts.results
Output of all_hosts
"all_hosts.results": [
{
"_ansible_no_log": false,
"changed": true,
"cmd": "echo {u'host': u'host1', u'description': u'This is host1 server'}",
"delta": "0:00:00.005456",
"end": "2016-04-07 02:34:37.151824",
"invocation": {
"module_args": {
"_raw_params": "echo {u'host': u'host1', u'description': u'This is host1 server'}",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
},
"module_name": "command"
},
"item": [
{
"description": "This is host1 server",
"host": "host1"
},
{
"host_name": "host1"
}
],
"rc": 0,
"start": "2016-04-07 02:34:37.146368",
"stderr": "",
"stdout": "{uhost: uhost1, udescription: uThis is host1 server}",
"stdout_lines": [
"{uhost: uhost1, udescription: uThis is host1 server}"
],
"warnings": []
},
{
"_ansible_no_log": false,
"changed": false,
"item": [
{
"description": "This is host1 server",
"host": "host1"
},
{
"host_name": "host2"
}
],
"skip_reason": "Conditional check failed",
"skipped": true
},
{
"_ansible_no_log": false,
"changed": false,
"item": [
{
"description": "This is host1 server",
"host": "host1"
},
{
"host_name": "host3"
}
],
"skip_reason": "Conditional check failed",
"skipped": true
},
{
"_ansible_no_log": false,
"changed": false,
"item": [
{
"description": "This is host1 server",
"host": "host1"
},
{
"host_name": "host4"
}
],
"skip_reason": "Conditional check failed",
"skipped": true
},
{
"_ansible_no_log": false,
"changed": false,
"item": [
{
"description": "This is host2 server",
"host": "host2"
},
{
"host_name": "host1"
}
],
"skip_reason": "Conditional check failed",
"skipped": true
},
{
"_ansible_no_log": false,
"changed": true,
"cmd": "echo {u'host': u'host2', u'description': u'This is host2 server'}",
"delta": "0:00:00.005470",
"end": "2016-04-07 02:34:37.310095",
"invocation": {
"module_args": {
"_raw_params": "echo {u'host': u'host2', u'description': u'This is host2 server'}",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
},
"module_name": "command"
},
"item": [
{
"description": "This is host2 server",
"host": "host2"
},
{
"host_name": "host2"
}
],
"rc": 0,
"start": "2016-04-07 02:34:37.304625",
"stderr": "",
"stdout": "{uhost: uhost2, udescription: uThis is host2 server}",
"stdout_lines": [
"{uhost: uhost2, udescription: uThis is host2 server}"
],
"warnings": []
},
{
"_ansible_no_log": false,
"changed": false,
"item": [
{
"description": "This is host2 server",
"host": "host2"
},
{
"host_name": "host3"
}
],
"skip_reason": "Conditional check failed",
"skipped": true
},
{
"_ansible_no_log": false,
"changed": false,
"item": [
{
"description": "This is host2 server",
"host": "host2"
},
{
"host_name": "host4"
}
],
"skip_reason": "Conditional check failed",
"skipped": true
}
]
So there is two matching records are there. Is there any ways to get count of these matching records?
Something
- debug: msg="Task if matching record count more than one"
when: all_hosts.changed | length > 0
Do you really need the count or want to check if there is at least one matching record? How about:
- debug: msg="Task if matching record count more than one"
when: all_hosts.changed
If I have these 2 task
- name: Replace ServerIP in config_file on OTHER NODES
set_fact:
variable: "{{hostvars.localhost.new_ips.results}}"
- name: Display variable
debug: var=variable
The result of which are:
TASK: [Display variable] *********************************************************
ok: [vm2] => {
"variable": [
{
"changed": true,
"cmd": "echo \"11.11.4.74\"",
"delta": "0:00:00.002244",
"end": "2014-08-26 02:34:22.880447",
"invocation": {
"module_args": "echo \"11.11.4.74\"",
"module_name": "shell"
},
"item": "74",
"rc": 0,
"start": "2014-08-26 02:34:22.878203",
"stderr": "",
"stdout": "11.11.4.74"
},
{
"changed": true,
"cmd": "echo \"11.11.4.138\"",
"delta": "0:00:00.002156",
"end": "2014-08-26 02:34:22.958337",
"invocation": {
"module_args": "echo \"11.11.4.138\"",
"module_name": "shell"
},
"item": "138",
"rc": 0,
"start": "2014-08-26 02:34:22.956181",
"stderr": "",
"stdout": "11.11.4.138"
}
]
}
ok: [vm1] => {
"variable": [
{
"changed": true,
"cmd": "echo \"11.11.4.74\"",
"delta": "0:00:00.002244",
"end": "2014-08-26 02:34:22.880447",
"invocation": {
"module_args": "echo \"11.11.4.74\"",
"module_name": "shell"
},
"item": "74",
"rc": 0,
"start": "2014-08-26 02:34:22.878203",
"stderr": "",
"stdout": "11.11.4.74"
},
{
"changed": true,
"cmd": "echo \"11.11.4.138\"",
"delta": "0:00:00.002156",
"end": "2014-08-26 02:34:22.958337",
"invocation": {
"module_args": "echo \"11.11.4.138\"",
"module_name": "shell"
},
"item": "138",
"rc": 0,
"start": "2014-08-26 02:34:22.956181",
"stderr": "",
"stdout": "11.11.4.138"
}
]
}
Then how can I access the stdout part of variable only. Please note, I just require the stdout part of this variable i.e 11.11.4.74 and 11.11.4.138 (in a loop preferably)
You can either access it individually
{{ variable[0].stdout }}
and
{{ variable[1].stdout }}
OR use loop
- debug: var=item.stdout
with_items: variable