How to get the status of the each task in include task --playbook? - ansible

I am executing below as ansible playbook in loop with_together but need to know the status of the each task which is defined switch-host-config.yaml, but when i print register variable "sw_output" its not showing the task result it shows the with_together defined list...
is there any method or way to identify the task status in defined switch-host-config.yaml playbook.
- hosts: "{{ data_sw_ip1 }}"
connection: local
gather_facts: False
tasks:
- name: sw-host task
include_tasks: switch-host-config.yaml
vars:
- nic1_swport: "{{ item.0 }}"
- nic2_swport: "{{ item.1 }}"
- id_host: "{{ item.2}}"
register: sw_output
with_together:
- "{{ nic1_swport1 }}"
- "{{ nic2_swport }}"
- "{{ id_host }}"
ignore_errors: yes
- debug:
msg: "{{ sw_output }}"

Related

Ansible - loop over multiple items in stdout_lines

I am performing a grep with multiple items.
---
- hosts: my_host
gather_facts: false
vars:
my_list:
- whatever
- something
tasks:
- name: grep for item in search path
shell: "grep -rIL {{ item }} /tmp"
register: the_grep
loop: "{{ my_list }}"
- debug:
msg: "{{ item.stdout_lines }}"
loop: "{{ the_grep.results }}"
Depending on the result, multiple files could match.
msg:
- /tmp/something.conf
- /tmp/folder/file.txt
Q: How would I configure Ansible to loop over the items in stdout_lines?
The use case I'm solving is to delete .ini sections based on the item, but in this case, Ansible doesn't loop over the stdout_lines.
- name: remove stanza from ini file
ini_file:
path: "{{ item.stdout_lines }}"
section: "{{ item.item }}"
mode: '0600'
state: absent
loop: "{{ the_grep.results }}"
when: item.stdout_lines | length > 0
It seems that this doesn't work, but configuring item.stdout_lines[0] gives the partially expected result, since Ansible will use only the first item in that list. But ofc, not the 2nd and so on.
Perhaps there's a prettier answer, but solved it by using with_nested and creating a json_query:
- name: remove stanza from ini file
ini_file:
path: "{{ item.0 }}"
section: "{{ item.1.item }}"
mode: '0600'
state: absent
with_nested:
- "{{ the_grep | json_query('results[].stdout_lines[]') }}"
- "{{ the_grep.results }}"

Loop through the children host group ansible is failing

My inventory file is having below host groups:
[uat1]
123.11.23.22 ansible_user="xxx"
[OS_uat2]
123.45.6.7 ansible_user="yyy"
[uat1_childs:children]
uat1
OS_uat2
I am having the vars file which is having param for below hosts. I am running a playbook to run a shell command. I am passing some parameters with the playbook. I am passing deployment_environment as uat1_childs. This is giving me error. Playbook is:
- name: play to ping test
gather_facts: false
hosts: "{{ deployment_environment }}"
ignore_unreachable: yes
vars_files:
- r_params.yml
vars:
package: "{{ package }}"
tasks:
- set_fact:
env_param: "{{ deployment_environment }}"
- name: ping test
ping:
data: pong
- name: Deploy Services on "{{ deployment_environment }}"
shell: cd "{{ env_select[env_param].script_path }}"; sh "{{ env_select[env_param].script_path }}/deploy.sh" "param1" "param2" "{{ env_select[env_param].repo }}" "{{ artifact_version }}" "{{ env_select[env_param].ENV }}" "{{ arti_username }}" "{{ arti_pass }}" "{{ deployer }}" "{{ package }}" "{{ env_select[env_param].deployment_path }}"
when: (package == "abc")
with_items: "{{ groups[{{ 'deployment_environment' }}] }}"
This is giving me error as:
fatal: [123.11.23.22]: FAILED! =>
{
"msg": "'dict object' has no attribute 'deployment_environment'"
}
fatal: [123.45.6.7]: FAILED! =>
{
"msg": "'dict object' has no attribute 'deployment_environment'"
}
I tried removing apostrophe in with items, still it is giving me error. Cant identify how to run the task in all children host group.

Ansible: How to filter dict2items and run playbook only for the matched values

I have a dict playbook which looks like this:
x_php_versions_installed:
ea-php71:
- ea-php71-php-bcmath
- ea-php71-php-xmlrpc
- ea-php71-php-zip
- pecl-memcached
- pecl-imagick
ea-php72:
- ea-php72-php-cli
- ea-php72-php-common
- ea-php72-php-curl
- pecl-imagick
I would like to filter them, to write me each item.value which contains 'ea' string but not everything else. My task looks like this:
- name: Write out only the ea packages
debug:
msg: '{{ item.value }}'
when: item.value | selectattr(item.value, 'contains', 'ea')
loop: '{{ x_php_versions_installed | dict2items }}
But it does not work, because it will list all of the packages, not only the ea ones. The expected answer should look like this:
...
"msg": [
"ea-php71-php-bcmath",
"ea-php71-php-xmlrpc",
"ea-php71-php-zip"
]
...
"msg": [
"ea-php72-php-cli",
"ea-php72-php-common",
"ea-php72-php-curl"
]
...
Another possibility is to filter out the 'pecl' string, it will gave me the same result and it also works fine.
Q: "Filter item.value which contains ea string."
A: The task below does the job
- debug:
msg: "{{ item.value|select('match','^ea-(.*)$')|list }}"
loop: "{{ x_php_versions_installed|dict2items }}"
gives (abridged)
msg:
- ea-php71-php-bcmath
- ea-php71-php-xmlrpc
- ea-php71-php-zip
msg:
- ea-php72-php-cli
- ea-php72-php-common
- ea-php72-php-curl
Note: The test match by default "succeeds if it finds the pattern at the beginning of the string". The task below gives the same result
- debug:
msg: "{{ item.value|select('match', 'ea-')|list }}"
loop: "{{ x_php_versions_installed|dict2items }}"
Q: "Filter out the pecl string."
A: Change the filter to reject and fit the regex. For example, the task below gives the same result
- debug:
msg: "{{ item.value|reject('match','^pecl-(.*)$')|list }}"
loop: "{{ x_php_versions_installed|dict2items }}"
Notes:
Select the lists without iteration. Declare the variables
x_php_versions_installed_keys: "{{ x_php_versions_installed.keys()|list }}"
x_php_versions_installed_ea_vals: "{{ x_php_versions_installed|dict2items|
map(attribute='value')|
map('select', 'match', 'ea-')|list }}"
x_php_versions_installed_ea: "{{ dict(x_php_versions_installed_keys|
zip(x_php_versions_installed_ea_vals)) }}"
gives
x_php_versions_installed_ea:
ea-php71:
- ea-php71-php-bcmath
- ea-php71-php-xmlrpc
- ea-php71-php-zip
ea-php72:
- ea-php72-php-cli
- ea-php72-php-common
- ea-php72-php-curl
Example of a complete playbook for testing
- hosts: localhost
vars:
x_php_versions_installed:
ea-php71:
- ea-php71-php-bcmath
- ea-php71-php-xmlrpc
- ea-php71-php-zip
- pecl-memcached
- pecl-imagick
ea-php72:
- ea-php72-php-cli
- ea-php72-php-common
- ea-php72-php-curl
- pecl-imagick
x_php_versions_installed_keys: "{{ x_php_versions_installed.keys()|list }}"
x_php_versions_installed_ea_vals: "{{ x_php_versions_installed|dict2items|
map(attribute='value')|
map('select', 'match', 'ea-')|list }}"
x_php_versions_installed_ea: "{{ dict(x_php_versions_installed_keys|
zip(x_php_versions_installed_ea_vals)) }}"
tasks:
- debug:
msg: "{{ item.value|select('match','^ea-(.*)$')|list }}"
loop: "{{ x_php_versions_installed|dict2items }}"
- debug:
msg: "{{ item.value|select('match', 'ea-')|list }}"
loop: "{{ x_php_versions_installed|dict2items }}"
- debug:
msg: "{{ item.value|reject('match','^pecl-(.*)$')|list }}"
loop: "{{ x_php_versions_installed|dict2items }}"
- debug:
msg: "{{ item.value|reject('match','pecl-')|list }}"
loop: "{{ x_php_versions_installed|dict2items }}"
- debug:
var: x_php_versions_installed_ea

How to extract the output from stdout.lines in ansible

---
- name: Mikrotik info
hosts: mikrotik
connection: network_cli
remote_user: root
gather_facts: false
tasks:
- name: show info
routeros_command:
commands: /system routerboard print
register: rb_info
- name: Debug info
debug:
msg: "{{ rb_info.stdout_lines }}"
Output:
routerboard: yes
model: 751G-2HnD
serial-number: 3A6502B2A2E7
firmware-type: ar7240
factory-firmware: 3.0
current-firmware: 6.42.3
upgrade-firmware: 6.43.4
I need to filter it for "upgrade-firmware" string and get output like this:
upgrade-firmware: 6.43.4
I should use regex_replace? Or I can use grep or something like that?
Any thoughts are greatly appreciated.
Thank you
(update)
Use from_yaml and combine a dictionary. For example
- set_fact:
minfo: "{{ minfo|default({})|combine(item|from_yaml) }}"
loop: "{{ rb_info.stdout_lines }}"
- debug:
var: minfo['upgrade-firmware']
give
minfo['upgrade-firmware']: 6.43.4
(for the record)
Robust solution is to write the data to template and include_vars. The tasks below
- tempfile:
register: tempfile
- template:
src: minfo.j2
dest: "{{ tempfile.path }}"
- include_vars:
file: "{{ tempfile.path }}"
name: minfo
- debug:
var: minfo
with the template
shell> cat minfo.j2
{% for item in rb_info.stdout_lines %}
{{ item }}
{% endfor %}
should give
"minfo": {
"current-firmware": "6.42.3",
"factory-firmware": 3.0,
"firmware-type": "ar7240",
"model": "751G-2HnD",
"routerboard": true,
"serial-number": "3A6502B2A2E7",
"upgrade-firmware": "6.43.4"
}
The tasks below creates variable upgrade_firmware
- set_fact:
upgrade_firmware: "{{ item.split(':').1|trim }}"
loop: "{{ rb_info.stdout_lines|map('quote')|map('trim')|list }}"
when: item is search('^upgrade-firmware')
- debug:
var: upgrade_firmware
It is possible to put all the parameters into the dictionary
- set_fact:
minfo: "{{ minfo|default({})|
combine({item.split(':').0: item.split(':').1|trim}) }}"
loop: "{{ rb_info.stdout_lines|map('quote')|map('trim')|list }}"
- debug:
var: minfo['upgrade-firmware']

ansible sharing parameters between tasks

This may be an elementary question. I am using the following Ansible modules and was wanting to streamline my playbooks by reducing duplicate lines/variables.
https://github.com/HewlettPackard/hpe3par_ansible_module
I see that each task references a module that is using the same connection parameters. The variables are already defined in a parameters file but is there a way to move parameters to be more global so it doesn't have to be repeated in each task.
My playbook:
---
- name: Create 3PAR host and volume
hosts: localhost
tasks:
- name: Load Storage System Vars
include_vars: 'properties/storage_system_properties.yml'
- name: Load Host Vars
include_vars: 'properties/host_properties.yml'
- name: Create Host "{{ host_name }}"
hpe3par_host:
storage_system_ip="{{ storage_system_ip }}"
storage_system_username="{{ storage_system_username }}"
storage_system_password="{{ storage_system_password }}"
state=present
host_name="{{ host_name }}"
host_persona="{{ host_persona }}"
host_domain="{{ host_domain }}"
host_iscsi_names="{{ host_iscsi_names }}"
- name: Create Volume "{{ volume_name }}"
hpe3par_volume:
storage_system_ip="{{ storage_system_ip }}"
storage_system_username="{{ storage_system_username }}"
storage_system_password="{{ storage_system_password }}"
state=present
volume_name="{{ volume_name }}"
cpg="{{ cpg }}"
size="{{ size }}"
- name: Create VLUN
hpe3par_vlun:
storage_system_ip="{{ storage_system_ip }}"
storage_system_username="{{ storage_system_username }}"
storage_system_password="{{ storage_system_password }}"
state=export_volume_to_host
volume_name="{{ volume_name }}"
host_name="{{ host_name }}"
Desired playbook.
---
- name: Create 3PAR host and volume
hosts: localhost
vars_file:
- properties/storage_system_properties.yml
tasks:
- name: Load Host Vars
include_vars: 'properties/host_properties.yml'
- name: Create Host "{{ host_name }}"
hpe3par_host:
state=present
host_name="{{ host_name }}"
host_persona="{{ host_persona }}"
host_domain="{{ host_domain }}"
host_iscsi_names="{{ host_iscsi_names }}"
- name: Create Volume "{{ volume_name }}"
hpe3par_volume:
state=present
volume_name="{{ volume_name }}"
cpg="{{ cpg }}"
size="{{ size }}"
- name: Create VLUN
hpe3par_vlun:
state=export_volume_to_host
volume_name="{{ volume_name }}"
host_name="{{ host_name }}"
properties/storage_system_properties.yml
storage_system_ip: "192.168.1.10"
storage_system_username: "3paruser"
storage_system_password: "3parpass"
An option would be to use include_tasks. See example below.
> cat tasks-001.yml
- debug: msg="{{ var_001 }}-{{ var_002 }}-{{ var_003 }}"
> cat test-19.yml
- hosts: localhost
gather_facts: no
vars:
var_001: "001"
var_002: "002"
var_003: "003"
tasks:
- include_tasks: tasks-001.yml
- include_tasks: tasks-001.yml
vars:
var_003: "444"
- include_tasks: tasks-001.yml
vars:
var_003: "555"
- include_tasks: tasks-001.yml
vars:
var_001: "111"
var_002: "222"
- include_tasks: tasks-001.yml
vars:
var_001: "111"
var_002: "222"
var_003: "333"
- include_tasks: tasks-001.yml
> ansible-playbook test-19.yml | grep msg
"msg": "001-002-003"
"msg": "001-002-444"
"msg": "001-002-555"
"msg": "111-222-003"
"msg": "111-222-333"
"msg": "001-002-003"

Resources