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

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?

Related

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

Ansible: how to print var name while looping?

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

How to run mutiple include tasks asynchronously in ansible?

I use 'include' and 'with_items' to looping over a block of tasks:
---
- name: main file
gather_facts: false
hosts: localhost
vars:
list1:
- { name: 'testuser1', groups: 'wheel', time: 10 }
- { name: 'testuser2', groups: 'root', time: 3 }
tasks:
- name: multiple tasks
include: multiple.yml item={{item}}
with_items: "{{ list1 }}"
and the multiple.yml is:
---
- name: time before
shell: date +"%H:%M:%S"
- name: run
shell: sleep {{ item.time }}
- name: time after
shell: date +"%H:%M:%S"
The task works well. However, the multiple.yml for each loop are executed serialisely:
TASK [time before] ******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "date +\"%H:%M:%S\"", "delta": "0:00:00.013440", "end": "2018-11-25 15:56:04.595098", "rc": 0, "start": "2018-11-25 15:56:04.581658", "stderr": "", "stderr_lines": [], "stdout": "15:56:04", "stdout_lines": ["15:56:04"]}
TASK [run] ******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "sleep 10", "delta": "0:00:10.013043", "end": "2018-11-25 15:56:14.859720", "rc": 0, "start": "2018-11-25 15:56:04.846677", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
TASK [time after] *******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "date +\"%H:%M:%S\"", "delta": "0:00:00.012656", "end": "2018-11-25 15:56:15.153993", "rc": 0, "start": "2018-11-25 15:56:15.141337", "stderr": "", "stderr_lines": [], "stdout": "15:56:15", "stdout_lines": ["15:56:15"]}
TASK [time before] ******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "date +\"%H:%M:%S\"", "delta": "0:00:01.014217", "end": "2018-11-25 15:56:16.448480", "rc": 0, "start": "2018-11-25 15:56:15.434263", "stderr": "", "stderr_lines": [], "stdout": "15:56:15", "stdout_lines": ["15:56:15"]}
TASK [run] ******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "sleep 3", "delta": "0:00:03.012509", "end": "2018-11-25 15:56:19.711891", "rc": 0, "start": "2018-11-25 15:56:16.699382", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
TASK [time after] *******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "date +\"%H:%M:%S\"", "delta": "0:00:01.013766", "end": "2018-11-25 15:56:20.973979", "rc": 0, "start": "2018-11-25 15:56:19.960213", "stderr": "", "stderr_lines": [], "stdout": "15:56:19", "stdout_lines": ["15:56:19"]}
I want to execute the multiple.yml of each loop asynchronously, so I tried to use async and poll in main file:
---
- name: main file
gather_facts: false
hosts: localhost
vars:
list1:
- { name: 'testuser1', groups: 'wheel', time: 10 }
- { name: 'testuser2', groups: 'root', time: 3 }
tasks:
- name: multiple tasks
include: multiple.yml item={{item}}
async: 20
poll: 0
with_items: "{{ list1 }}"
The expected result is:
TASK [time before] ******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "date +\"%H:%M:%S\"", "delta": "0:00:00.013440", "end": "2018-11-25 15:56:04.595098", "rc": 0, "start": "2018-11-25 15:56:04.581658", "stderr": "", "stderr_lines": [], "stdout": "15:56:04", "stdout_lines": ["15:56:04"]}
TASK [run] ******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "sleep 10", "delta": "0:00:10.013043", "end": "2018-11-25 15:56:14.859720", "rc": 0, "start": "2018-11-25 15:56:04.846677", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
TASK [time after] *******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "date +\"%H:%M:%S\"", "delta": "0:00:00.012656", "end": "2018-11-25 15:56:15.153993", "rc": 0, "start": "2018-11-25 15:56:15.141337", "stderr": "", "stderr_lines": [], "stdout": "15:56:15", "stdout_lines": ["15:56:15"]}
TASK [time before] ******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "date +\"%H:%M:%S\"", "delta": "0:00:01.014217", "end": "2018-11-25 15:56:16.448480", "rc": 0, "start": "2018-11-25 15:56:15.434263", "stderr": "", "stderr_lines": [], "stdout": "15:56:15", "stdout_lines": ["15:56:04"]}
TASK [run] ******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "sleep 3", "delta": "0:00:03.012509", "end": "2018-11-25 15:56:19.711891", "rc": 0, "start": "2018-11-25 15:56:16.699382", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
TASK [time after] *******************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "date +\"%H:%M:%S\"", "delta": "0:00:01.013766", "end": "2018-11-25 15:56:20.973979", "rc": 0, "start": "2018-11-25 15:56:19.960213", "stderr": "", "stderr_lines": [], "stdout": "15:56:19", "stdout_lines": ["15:56:08"]}
But the result of running new main.yml is the same as before, and the multiple.yml of the two loops is not executed asynchronously. I don't kown what the problem is. Is there any advice?
That is a known issue and is marked as an "improvement," rather than a bug. Feel free to drop a comment or +1 or whatever into the issue, but I would not expect it to be resolved in the near future since that issue has been open since 2017.
Separately, it may interest you to know that the "inline variable" syntax has been deprecated in favor of using vars:, but even in that case you don't need to because with_items: automatically exposes item and thus it is implicitly in vars: for you. The deprecation is in the "Note" in the manual

how to get ec2 instances public dns name by ansible playbook

I am playing with ansible to automate ec2 instances. I created ec2 instance and then m trying to get its public dns name via ec2_remote_facts module. but it is giving variable not defined in output.
playbook:
- hosts: localhost
connection: local
tasks:
- name: ec2 instance facts
ec2_remote_facts:
region: ap-southeast-2
filters:
instance-state-name: running
register: ec2
- debug: var=ec2.instances.public_name
Output:PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [create ec2 instance] *****************************************************
ok: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"ec2.instances.public_name": "VARIABLE IS NOT DEFINED!"
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
Output for ec2.instances.
ok: [localhost] => {
"ec2.instances": [
{
"ami_launch_index": "0",
"architecture": "x86_64",
"client_token": "",
"ebs_optimized": false,
"groups": [
{
"id": "sg-6c016a08",
"name": "default"
}
],
"hypervisor": "xen",
"id": "i-915b1813",
"image_id": "ami-fedafc9d",
"instance_profile": null,
"interfaces": [
{
"id": "eni-96de4acf",
"mac_address": "0a:14:ac:64:c4:13"
}
],
"kernel": null,
"key_name": "ansible.key",
"launch_time": "2016-08-29T07:32:10.000Z",
"monitoring_state": "disabled",
"persistent": false,
"placement": {
"tenancy": "default",
"zone": "ap-southeast-2c"
},
"private_dns_name": "ip-xx-xx-xx-107.ap-southeast-2.compute.internal",
"private_ip_address": "xx.xx.xx.107",
"public_dns_name": "ec2-xx-xxx-xx-80.ap-southeast-2.compute.amazonaws.com",
"ramdisk": null,
"region": "ap-southeast-2",
"requester_id": null,
"root_device_type": "ebs",
"source_destination_check": "true",
"spot_instance_request_id": null,
"state": "running",
"tags": {
"Name": "Demo"
},
"virtualization_type": "hvm",
"vpc_id": "vpc-abcaf4ce"
}
]
}
what i m missing here?
Thanks
Benjo
If you look closely to ec2.instances you may note that:
it is a list, so you either access items by index ec2.instances[0] or iterate over them with with_items: structure.
there is no public_name attribute, only public_dns_name.

How to filter unmatched value from ansible variable

I have recently upgraded ansible version from 1.7 to 2.0. After upgrade with_nested loop unable to register only matching records in ansible variable. The same is working in ansible 1.7.2
Here is example playbook:
---
- 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
Output:
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [127.0.0.1]
TASK [command] *****************************************************************
changed: [127.0.0.1] => (item=[{u'host': u'host1', u'description': u'This is host1 server'}, {u'host_name': u'host1'}])
skipping: [127.0.0.1] => (item=[{u'host': u'host1', u'description': u'This is host1 server'}, {u'host_name': u'host2'}])
skipping: [127.0.0.1] => (item=[{u'host': u'host1', u'description': u'This is host1 server'}, {u'host_name': u'host3'}])
skipping: [127.0.0.1] => (item=[{u'host': u'host1', u'description': u'This is host1 server'}, {u'host_name': u'host4'}])
skipping: [127.0.0.1] => (item=[{u'host': u'host2', u'description': u'This is host2 server'}, {u'host_name': u'host1'}])
changed: [127.0.0.1] => (item=[{u'host': u'host2', u'description': u'This is host2 server'}, {u'host_name': u'host2'}])
skipping: [127.0.0.1] => (item=[{u'host': u'host2', u'description': u'This is host2 server'}, {u'host_name': u'host3'}])
skipping: [127.0.0.1] => (item=[{u'host': u'host2', u'description': u'This is host2 server'}, {u'host_name': u'host4'}])
TASK [debug] *******************************************************************
ok: [127.0.0.1] => {
"all_hosts": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_no_log": false,
"changed": true,
"cmd": "echo {u'host': u'host1', u'description': u'This is host1 server'}",
"delta": "0:00:00.005613",
"end": "2016-04-05 04:09:05.269437",
"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-05 04:09:05.263824",
"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.005463",
"end": "2016-04-05 04:09:05.425793",
"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-05 04:09:05.420330",
"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
}
]
}
}
PLAY RECAP *********************************************************************
127.0.0.1 : ok=3 changed=1 unreachable=0 failed=0
In my all_hosts its also giving me unmatched record with skip message "skip_reason": "Conditional check failed". I don't want to include unmatched records in all_hosts variable.
Expected Output:
TASK [debug] *******************************************************************
ok: [127.0.0.1] => {
"all_hosts": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_no_log": false,
"changed": true,
"cmd": "echo {u'host': u'host1', u'description': u'This is host1 server'}",
"delta": "0:00:00.005613",
"end": "2016-04-05 04:09:05.269437",
"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-05 04:09:05.263824",
"stderr": "",
"stdout": "{uhost: uhost1, udescription: uThis is host1 server}",
"stdout_lines": [
"{uhost: uhost1, udescription: uThis is host1 server}"
],
"warnings": []
},
{
"_ansible_no_log": false,
"changed": true,
"cmd": "echo {u'host': u'host2', u'description': u'This is host2 server'}",
"delta": "0:00:00.005463",
"end": "2016-04-05 04:09:05.425793",
"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-05 04:09:05.420330",
"stderr": "",
"stdout": "{uhost: uhost2, udescription: uThis is host2 server}",
"stdout_lines": [
"{uhost: uhost2, udescription: uThis is host2 server}"
],
"warnings": []
}
]
}
}
PLAY RECAP *********************************************************************
127.0.0.1 : ok=3 changed=1 unreachable=0 failed=0
I am able to filter value using item|changed like below
- debug: var={{ item }}
with_items: all_hosts.results
when: item|changed
But is there any way to exclude these value from variable (all_hosts) itself? As its unnecessary increasing the iteration.
Any suggestion?
Unfortunately, that is the intended behavior. Lot of people have complained about this but avoiding the second loop is not possible.
Registered Variables
Note
If a task fails or is skipped, the variable still is registered
with a failure or skipped status, the only way to avoid registering a
variable is using tags.

Resources