Ansible: how to print var name while looping? - ansible

I have this inside setup/tasks/apps.yml:
- name: Mac App Store | Install apps.
shell: mas list | grep {{ item.id }} || mas install {{ item.id }}
with_items: "{{ mac_store_apps }}"
register: result
changed_when: result.stdout.find('Installed') != -1
I know I can use:
loop_control:
label: '{{ item.name }}'
But I want to print something like:
Attempting to Install {{ item.name }}
before each execution. How can that be done?

There is no way to generate output before each iteration of your loop; Ansible only produces output when a task (or an iteration of a looping task) is complete. If you are concerned that package installation can take a while and you want to provide some feedback, you could just print out a notice in advance, as in:
- debug:
msg: "Note: package installation may take several minutes to complete"
You can sort of get what you want by placing your install task in a separate file, and then calling include_tasks in a loop. For example, if we have the following playbook:
---
- hosts: localhost
gather_facts: false
vars:
mac_store_apps:
- name: foo
- name: bar
- name: baz
- name: qux
tasks:
- name: "Mac App Store | Install apps."
include_tasks: ./install.yml
with_items: "{{ mac_store_apps }}"
- debug:
var: all_results
And the following tasks in install.yml:
---
- name: "Mac App Store | Install {{ item.name }}"
shell: "true"
register: result
- name: Store result
set_fact:
all_results: "{{ all_results|default([]) + [{'item': item, 'result': result}] }}"
We will see as output:
PLAY [localhost] ******************************************************************************
TASK [Mac App Store | Install apps.] **********************************************************
included: /home/lars/tmp/ansible/install.yml for localhost => (item={u'name': u'foo'})
included: /home/lars/tmp/ansible/install.yml for localhost => (item={u'name': u'bar'})
included: /home/lars/tmp/ansible/install.yml for localhost => (item={u'name': u'baz'})
included: /home/lars/tmp/ansible/install.yml for localhost => (item={u'name': u'qux'})
TASK [Mac App Store | Install foo] ************************************************************
changed: [localhost]
TASK [Store result] ***************************************************************************
ok: [localhost]
TASK [Mac App Store | Install bar] ************************************************************
changed: [localhost]
TASK [Store result] ***************************************************************************
ok: [localhost]
TASK [Mac App Store | Install baz] ************************************************************
changed: [localhost]
TASK [Store result] ***************************************************************************
ok: [localhost]
TASK [Mac App Store | Install qux] ************************************************************
changed: [localhost]
TASK [Store result] ***************************************************************************
ok: [localhost]
TASK [debug] **********************************************************************************
ok: [localhost] => {
"all_results": [
{
"item": {
"name": "foo"
},
"result": {
"changed": true,
"cmd": "true",
"delta": "0:00:00.002398",
"end": "2019-04-23 11:19:25.146497",
"failed": false,
"rc": 0,
"start": "2019-04-23 11:19:25.144099",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
},
{
"item": {
"name": "bar"
},
"result": {
"changed": true,
"cmd": "true",
"delta": "0:00:00.002245",
"end": "2019-04-23 11:19:25.285859",
"failed": false,
"rc": 0,
"start": "2019-04-23 11:19:25.283614",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
},
{
"item": {
"name": "baz"
},
"result": {
"changed": true,
"cmd": "true",
"delta": "0:00:00.002406",
"end": "2019-04-23 11:19:25.426909",
"failed": false,
"rc": 0,
"start": "2019-04-23 11:19:25.424503",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
},
{
"item": {
"name": "qux"
},
"result": {
"changed": true,
"cmd": "true",
"delta": "0:00:00.002232",
"end": "2019-04-23 11:19:25.574214",
"failed": false,
"rc": 0,
"start": "2019-04-23 11:19:25.571982",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
}
]
}
PLAY RECAP ************************************************************************************
localhost : ok=13 changed=4 unreachable=0 failed=0

Related

Ansible - How to print out this list of dictionaries

I have this output from Windows auditpol.
I have difficulty to figure out how to print a certain output from the var query.
- name: check audit
win_command: auditpol /get /subcategory:{{ item }}
with_items:
- '"{{policy}}"'
register:
query
- debug: var=query.results
ok: [ipcprdixn201] => {
"query.results": [
{
"ansible_loop_var": "item",
"changed": true,
"cmd": "auditpol /get /subcategory:\"Other System Events\"",
"delta": "0:00:00.171888",
"end": "2022-11-24 06:04:11.903563",
"failed": false,
"item": "\"Other System Events\"",
"rc": 0,
"start": "2022-11-24 06:04:11.731675",
"stderr": "",
"stderr_lines": [],
"stdout": "System audit policy\r\r\nCategory/Subcategory Setting\r\nSystem\r\n Other System Events No Auditing\r\r\n",
"stdout_lines": [
"System audit policy",
"",
"Category/Subcategory Setting",
"System",
" Other System Events No Auditing",
""
]
}
]
}
- debug: msg="{{ query.results | type_debug }}"
ok: [ipcprdixn201] => {
"msg": "dict"
}
- debug: msg="{{ query | type_debug }}"
ok: [ipcprdixn201] => {
"msg": "list"
}
How do I print out one of the list, i.e. stdout_lines?
Thank you.
Reference: https://pythonexamples.org/python-list-of-dictionaries/
- debug: var=query.results[0]['stdout_lines']
ok: [ipcprdixn201] => {
"query.results[0]['stdout_lines']": [
"System audit policy",
"",
"Category/Subcategory Setting",
"System",
" Other System Events No Auditing",
""
]
}

How to check the size of a file list

With Ansible, I need to check if files in directory are bigger than 50M.
I do a set_fact with result of ls and then I loop to stat all files. This works, but I am not able to parse the result to create a fail condition when files are bigger than 50M.
I do this :
- shell: ls -1 "{{ logs_directory }}"*.log
register: list_logs
- set_fact:
list_logs: "{{ list_logs.stdout_lines }}"
- debug:
msg: "{{ list_logs}}"
- name: Get size
stat:
path: "{{ item }}"
with_items: "{{ list_logs }}"
register: size_log
- name: debug
fail:
msg: "Problem with log size > 50M"
when: 'size_log.stat.size / 1024 / 1024 | int > 50'
It works if I have only 1 file, but with multiple servers and multiple files, it doesn't work... How to parse the size_log_result?
Here an example of output size_log :
ok: [192.168.1.2] => {
"msg": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"path": "/var/logs/admin.log"
}
},
"item": "/var/logs/admin.log",
"stat": {
"size": 21711,
}
},
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"path": "/var/logs/database.log"
}
},
"item": "/var/logs/database.log",
"stat": {
"size": 11162,
}
}
]
}
}
ok: [192.168.1.5] => {
"msg": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"path": "/var/logs/database.log"
}
},
"item": "/var/logs/database.log",
"stat": {
"size": 128453958,
}
}
]
}
}
It looks to me like you are reinventing the wheel here, when the find module seems to answer you use case perfectly already.
Given:
- hosts: localhost
gather_facts: no
tasks:
####
## You do not need this task, it is just to create a file
## big enough for demonstration purpose
####
- community.general.filesize:
path: /var/log/heavy.log
size: 51m
- find:
paths: /var/log
patterns: '*.log'
size: 51m
register: _logs
- fail:
msg: >-
Due to file(s): {{
_logs.files | map(attribute='path') | join(', ')
}}
when: _logs.files | length > 0
This will yield:
TASK [community.general.filesize] *********************************
ok: [localhost]
TASK [find] *******************************************************
ok: [localhost]
TASK [fail] *******************************************************
fatal: [localhost]: FAILED! => changed=false
msg: 'Due to file(s): /var/log/heavy.log'

How to run ansible playbook in active/passive cluster setup?

I have a need to run ansible on a bunch of servers which are active/passive clusters. So, I have an inventory file like
[QA:children]
QA_01_CLUSTER
[QA_01_CLUSTER]
ip-10-361-412-14
ip-10-361-412-30
So serv1qa01 and serv2qa01 could be active/passive in that cluster or the other way around.
I am trying to write a playbook where it will look at which server is secondary, execute the tasks before executing them on the primary.
I have an api running on these servers which returns whether the server is primary or secondary.
I tried something like this
---
- hosts: all
serial: 1
tasks:
- name: run curl command to determine primary/secondary
command: /tmp/status.sh
register: apis_op
- name: run curl command to determine primary/secondary
debug: var=apis_op.stdout_lines
- name: If node is primary add to primary
add_host:
name: "{{ ansible_hostname }}"
groups: temp_primary
when: apis_op.stdout == "primary"
- name: run curl command to determine primary/secondary
debug: var=groups
- name: If node is secondary add to secondary
add_host:
name: "{{ ansible_hostname }}"
groups: temp_secondary
when: apis_op.stdout == "secondary"
- name: run curl command to determine primary/secondary
debug: var=groups
- hosts: temp_secondary
tasks:
- name: Run schell script
command: /tmp/testthis.sh
become: yes
become_user: root
- hosts: temp_primary
tasks:
- name: Run schell script
command: /tmp/testthis.sh
become: yes
become_user: root
Here's the entire output with the -v option.
PLAY [all] **********************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
[WARNING]: Platform linux on host ip-10-361-412-14 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [ip-10-361-412-14]
TASK [run curl command to determine primary/secondary] **************************************************************************************************************************************************************************************
changed: [ip-10-361-412-14] => {"changed": true, "cmd": ["/tmp/status.sh"], "delta": "0:00:00.038672", "end": "2021-03-29 21:29:15.693979", "rc": 0, "start": "2021-03-29 21:29:15.655307", "stderr": "", "stderr_lines": [], "stdout": "\"secondary\"", "stdout_lines": ["\"secondary\""]}
TASK [run curl command to determine primary/secondary] **************************************************************************************************************************************************************************************
ok: [ip-10-361-412-14] => {
"apis_op.stdout_lines": [
"\"secondary\""
]
}
TASK [If node is primary add to primary] ****************************************************************************************************************************************************************************************************
changed: [ip-10-361-412-14] => {"add_host": {"groups": ["temp_primary"], "host_name": "ip-10-361-412-14", "host_vars": {"when": "apis_op.stdout == \"primary\""}}, "changed": true}
TASK [run curl command to determine primary/secondary] **************************************************************************************************************************************************************************************
ok: [ip-10-361-412-14] => {
"groups": {
"all": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"hack": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"temp_primary": [
"ip-10-361-412-14"
],
"ungrouped": []
}
}
TASK [If node is secondary add to secondary] ************************************************************************************************************************************************************************************************
changed: [ip-10-361-412-14] => {"add_host": {"groups": ["temp_secondary"], "host_name": "ip-10-361-412-14", "host_vars": {"when": "apis_op.stdout == \"secondary\""}}, "changed": true}
TASK [run curl command to determine primary/secondary] **************************************************************************************************************************************************************************************
ok: [ip-10-361-412-14] => {
"groups": {
"all": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"hack": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"temp_primary": [
"ip-10-361-412-14"
],
"temp_secondary": [
"ip-10-361-412-14"
],
"ungrouped": []
}
}
PLAY [all] **********************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
[WARNING]: Platform linux on host ip-10-361-412-30 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [ip-10-361-412-30]
TASK [run curl command to determine primary/secondary] **************************************************************************************************************************************************************************************
changed: [ip-10-361-412-30] => {"changed": true, "cmd": ["/tmp/status.sh"], "delta": "0:00:00.038760", "end": "2021-03-29 21:29:17.776237", "rc": 0, "start": "2021-03-29 21:29:17.737477", "stderr": "", "stderr_lines": [], "stdout": "\"primary\"", "stdout_lines": ["\"primary\""]}
TASK [run curl command to determine primary/secondary] **************************************************************************************************************************************************************************************
ok: [ip-10-361-412-30] => {
"apis_op.stdout_lines": [
"\"primary\""
]
}
TASK [If node is primary add to primary] ****************************************************************************************************************************************************************************************************
changed: [ip-10-361-412-30] => {"add_host": {"groups": ["temp_primary"], "host_name": "ip-10-361-412-30", "host_vars": {"when": "apis_op.stdout == \"primary\""}}, "changed": true}
TASK [run curl command to determine primary/secondary] **************************************************************************************************************************************************************************************
ok: [ip-10-361-412-30] => {
"groups": {
"all": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"hack": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"temp_primary": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"temp_secondary": [
"ip-10-361-412-14"
],
"ungrouped": []
}
}
TASK [If node is secondary add to secondary] ************************************************************************************************************************************************************************************************
changed: [ip-10-361-412-30] => {"add_host": {"groups": ["temp_secondary"], "host_name": "ip-10-361-412-30", "host_vars": {"when": "apis_op.stdout == \"secondary\""}}, "changed": true}
TASK [run curl command to determine primary/secondary] **************************************************************************************************************************************************************************************
ok: [ip-10-361-412-30] => {
"groups": {
"all": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"hack": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"temp_primary": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"temp_secondary": [
"ip-10-361-412-14",
"ip-10-361-412-30"
],
"ungrouped": []
}
}
PLAY [temp_secondary] ***********************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [ip-10-361-412-14]
ok: [ip-10-361-412-30]
TASK [Run schell script] ********************************************************************************************************************************************************************************************************************
changed: [ip-10-361-412-14] => {"changed": true, "cmd": ["/tmp/testthis.sh"], "delta": "0:00:00.040347", "end": "2021-03-29 21:29:20.079991", "rc": 0, "start": "2021-03-29 21:29:20.039644", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
changed: [ip-10-361-412-30] => {"changed": true, "cmd": ["/tmp/testthis.sh"], "delta": "0:00:00.040470", "end": "2021-03-29 21:29:20.117223", "rc": 0, "start": "2021-03-29 21:29:20.076753", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
PLAY [temp_primary] *************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [ip-10-361-412-14]
ok: [ip-10-361-412-30]
TASK [Run schell script] ********************************************************************************************************************************************************************************************************************
changed: [ip-10-361-412-14] => {"changed": true, "cmd": ["/tmp/testthis.sh"], "delta": "0:00:00.041023", "end": "2021-03-29 21:29:22.107751", "rc": 0, "start": "2021-03-29 21:29:22.066728", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
changed: [ip-10-361-412-30] => {"changed": true, "cmd": ["/tmp/testthis.sh"], "delta": "0:00:00.041487", "end": "2021-03-29 21:29:22.145928", "rc": 0, "start": "2021-03-29 21:29:22.104441", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************
ip-10-361-412-14 : ok=11 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ip-10-361-412-30 : ok=11 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
I have simplified the playbook above but basically I want to run the tasks on secondary before running it on primary for HA reasons.
But this is not working. It's running the playbook in parallel and basically executing tasks on both the hosts at the same time.
How can I force it to run on secondary first before running on primary? I tried to get creative with the serial module or the inventory but is there a dynamic way of doing this?

Ansible task is run regardless of condition

If I store a string into an ansible register, and then have other tasks run only when that register contains a certain value, they are always run, regardless of the value in the register.
Why is ansible running tasks when a conditional should fail?
This is a simple example. It should only debug once (as test_foo.stdout == "Foo") but instead it will print both debug statements:
- name: foo
command: "echo \"Foo\""
register: test_foo
tags: [ 'foo-test' ]
- debug:
var: test_foo
when: test_foo.stdout == "Foo",
tags: [ 'foo-test' ]
- debug:
var: test_foo
when: test_foo.stdout == "Bar",
tags: [ 'foo-test' ]
Just to note, this also happens when another command call is triggered with the same conditional, not just debug calls. It will always execute both tasks.
Here's the output:
TASK [test : foo] ***********************************************************************************************************************************************************************************
changed: [localServer -> localhost] => {"changed": true, "cmd": ["echo", "Foo"], "delta": "0:00:01.002745", "end": "2020-11-17 11:22:25.733089", "rc": 0, "start": "2020-11-17 11:22:24.730344", "stderr": "", "stderr_lines": [], "stdout": "Foo", "stdout_lines": ["Foo"]}
TASK [test : debug] *********************************************************************************************************************************************************************************
ok: [localServer] => {
"test_foo": {
"changed": true,
"cmd": [
"echo",
"Foo"
],
"delta": "0:00:01.002745",
"end": "2020-11-17 11:22:25.733089",
"failed": false,
"rc": 0,
"start": "2020-11-17 11:22:24.730344",
"stderr": "",
"stderr_lines": [],
"stdout": "Foo",
"stdout_lines": [
"Foo"
]
}
}
TASK [test : debug] *********************************************************************************************************************************************************************************
ok: [localServer] => {
"test_foo": {
"changed": true,
"cmd": [
"echo",
"Foo"
],
"delta": "0:00:01.002745",
"end": "2020-11-17 11:22:25.733089",
"failed": false,
"rc": 0,
"start": "2020-11-17 11:22:24.730344",
"stderr": "",
"stderr_lines": [],
"stdout": "Foo",
"stdout_lines": [
"Foo"
]
}
}
And just in case this something weirdly version specific, I'm on Ubuntu 20.04 and this is my version:
$ ansible --version
ansible 2.9.6
config file = /path/to/project/orchestration/ansible.cfg
configured module search path = ['/home/myUser/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
executable location = /usr/bin/ansible
python version = 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0]
The problem is the trailing comma. The task below works as expected and gives "msg: false"
- debug:
msg: '{{ "A" == "B" }}'
The trailing comma creates a tuple
- debug:
msg: '{{ "A" == "B", }}'
- debug:
msg: "{{ (false,)|type_debug }}"
gives
msg: (False,)
msg: tuple
Non-empty variables, including tuples, evaluate to true
- debug:
msg: OK
when: (A,)
gives
msg: OK
See CONDITIONAL_BARE_VARS
I have just copied your code into my lab VM and I noticed you are using a comma at the end of the "when" statement (Which I have never seen). I have removed them and get expected output.
When variable is Foo:
PLAY [localhost] ***************************************************************************************************************
TASK [foo] *********************************************************************************************************************
changed: [localhost]
TASK [debug] *******************************************************************************************************************
ok: [localhost] => {
"test_foo": {
"changed": true,
"cmd": [
"echo",
"Foo"
],
"delta": "0:00:00.006168",
"end": "2020-11-17 12:50:11.863107",
"failed": false,
"rc": 0,
"start": "2020-11-17 12:50:11.856939",
"stderr": "",
"stderr_lines": [],
"stdout": "Foo",
"stdout_lines": [
"Foo"
]
}
}
TASK [debug] *******************************************************************************************************************
skipping: [localhost]
PLAY RECAP *********************************************************************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
When variable is Bar:
PLAY [localhost] ***************************************************************************************************************
TASK [foo] *********************************************************************************************************************
changed: [localhost]
TASK [debug] *******************************************************************************************************************
skipping: [localhost]
TASK [debug] *******************************************************************************************************************
ok: [localhost] => {
"test_foo": {
"changed": true,
"cmd": [
"echo",
"Bar"
],
"delta": "0:00:00.006077",
"end": "2020-11-17 12:53:24.142058",
"failed": false,
"rc": 0,
"start": "2020-11-17 12:53:24.135981",
"stderr": "",
"stderr_lines": [],
"stdout": "Bar",
"stdout_lines": [
"Bar"
]
}
}
PLAY RECAP *********************************************************************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
My ansible version is:
ansible 2.7.10
python version = 2.7.5

Fetch doesn't transfer when i use variable

fetch module does not transfer file when i use variable and getting message as "msg": "the remote file does not exist, not transferring, ignored". But file exits in the source directory. Please suggest if anything wrong in this.
ansible 2.1.0.0
---
- hosts: host_A
become_user: yes
gather_facts: no
tasks:
- name: list files
shell: ls -1 /root/stuff/install.1_comiskey-v01
register: dumpfiles
-debug: var=dumpfiles
- name: fetch files
fetch: src={{item}} dest=/tmp/fetched/ flat=yes
with_items: ('{{dumpfiles.stdout_lines}}')
register: test
- debug: var=test
Output:
TASK [fetch files]
*************************************************************
ok: [10.1.31.82] => (item=('[u'/root/stuff/install.1_comiskey-v01',u'/root/stuff/install.1_comiskey-v02']'))
TASK [debug] *******************************************************************
ok: [10.1.31.82] => {
"test": {
"changed": false,
"msg": "All items completed",
"results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"changed": false,
"file": "('[u'/root/stuff/install.1_comiskey-v01', u'/root/stuff/install.1_comiskey-v02']')",
"invocation": {
"module_args": {
"dest": "/tmp/fetched/",
"flat": "yes",
"src": "('[u'/root/stuff/install.1_comiskey-v01', u'/root/stuff/install.1_comiskey-v02']')"
},
"module_name": "fetch"
},
"item": "('[u'/root/stuff/install.1_comiskey-v01', u'/root/stuff/install.1_comiskey-v02']')",
"msg": "the remote file does not exist, not transferring, ignored"
}
]
}
}
Remove parentheses from with_items. You can note that item variable is not correct on your debug output.

Resources