Nested variable in Ansible - ansible

I have a variable client: client1 and I want to use it to fetch multiple facts into a template like below.
"{{ hostvars[{{ client }}][ansible_default_ipv4][address] }}"
"{{ hostvars[{{ client }}][ansible_hostname] }}"
"{{ hostvars[{{ client }}][ansible_fqdn] }}"
I have tried removing the braces, using a dictionary[key] in place of client but couldn't figure out. What is the right usage here?

The right answer is: "{{ hostvars[client]['ansible_default_ipv4']['address'] }}"

Related

Use variables inside variable file in Ansible

I've an Ansible vars_file like:
jmeter:
version: "5.3"
name: "apache-jmeter-{{ jmeter.version }}"
archive: "{{ jmeter.name }}.zip"
url: "https://archive.apache.org/dist/jmeter/binaries/{{ jmeter.archive }}"
Is it the way to go? I'm getting error. Anyone has suggestions?
You need to flatten that, as jmeter is not defined yet when you are trying to use it.
jmeter_version: "5.3"
jmeter_name: "apache-jmeter-{{ jmeter_version }}"
jmeter_archive: "{{ jmeter_name }}.zip"
jmeter_url: "https://archive.apache.org/dist/jmeter/binaries/{{ jmeter_archive }}"

Using a job identifier to group ansible tasks into logical task group

I'm new to ansible but trying to progress and learn.
I'm running a number of API calls to configure a web proxy tool.
The flow is essentially, make a GET request to see if the object exists, if does not exist, follow up with a POST request to create the object. Pretty standard.
This procedure repeats itself multiple times as the product can have a number of instances of the same type of configuration. So I would like to make the GET/POST routine as generic repeatable as possible, by associating an id.
The playbook is:
set_fact:
'vh_task_id': 01
- name: check virtual host exists
uri:
method: GET
url: "{{ admin_api_url }}/hosts?vHost={{ public_virtual_host|urlencode() }}"
return_content: yes
headers:
X-XSRF-Header: "Access"
user: "{{ admin_user }}"
password: "{{ admin_password }}"
status_code: 200
validate_certs: no
register: response
- name: set fact virtual host task id response '{{ public_virtual_host }}'
set_fact:
'response_{{ vh_task_id }}': "{{ response }}"
This all works fine, up to this point and response_{{ vh_task_id }} correctly contains the response body from the above set_fact, as I can see it, if I output it.
The issue now becomes when I want to query the JSON in response_{{ vh_task_id }} as the variable to query to get the id value.
The set_fact, is setting a literal value ofresponse_01 rather than seeing the concatenation as a registered variable.
Here is an example of how I was trying to do it:
set_fact:
'vh_id': "{{ hostvars[inventory_hostname].response_{{ vh_task_id }} | json_query('json.items[0].id') }}"
Many thanks for any help.
Try this:
set_fact:
'vh_id': "{{ hostvars[inventory_hostname].hostvar | json_query('json.items[0].id') }}"
vars:
hostvar: response_{{ vh_task_id }}
Also you don't need explicit quote ' for plain string as variable name. Like, you can change 'vh_id': to vh_id: if no other reason to keep the name with quotes.
Thanks for your time to come back, I tested this but, in the end, I have since learnt that using the with_items, gives me better results and it more repeatable

Write Host Variables to file in a loop with ansible

I am trying to build up a config file that contains the list of my inventory host servers and their fields eg. IP,FQDN etc.
Here is my part of inventory file :
ocp_cluster:
hosts:
anbootstrap.ocp.hattusas.tst:
fqdn: anbootstrap.ocp.hattusas.tst
ip: 10.72.217.92
anmaster1.ocp.hattusas.tst:
fqdn: anmaster1.ocp.hattusas.tst
ip: 10.72.217.93
anmaster2.ocp.hattusas.tst:
fqdn: anmaster2.ocp.hattusas.tst
ip: 10.72.217.94
anmaster3.ocp.hattusas.tst:
And here is my playbook:
- name: Adding OCP Clusters to DHCP configuration
debug:
"{{ hostvars[item][fqdn] }}"
loop: "{{ groups['ocp_cluster'] }}"
(I will use blockinfile soon)
When I ran my playbook I am getting undefined error fqdn. I tried using a for loop and it didn't help. Any suggestions?
Thanks a lot.
The fixed task is below
- debug:
msg: "{{ hostvars[item]['fqdn'] }}"
loop: "{{ groups['ocp_cluster'] }}"
Debug parameter msg was missing
fqdn is an attribute of a dictionary. It must be quoted in brackets. Similar to ocp_cluster.
It's possible to use the dot notation and simplify the references to the attributes of the dictionaries
- debug:
msg: "{{ hostvars[item].fqdn }}"
loop: "{{ groups.ocp_cluster }}"

Ansible loop returns outputs entire object

I am gathering information about AWS ec2 instances and then attempting to loop through them to output the instance_id property of the registered results.
When I run through the loop I get the expected results, but I also get the entire registered object outputted as well. It appears to flatten the object to a string and output it. What is the reason for the additional output and is there a better loop method I should use?
Thank you in advance!
---
- hosts: localhost
gather_facts: false
connection: local
tasks:
- name: get ec2 instance info
ec2_instance_info:
region: us-east-1
filters:
"tag:app": ansible
"tag:env": dev
register: ec2
- debug:
msg: "{{ item['instance_id'] }}"
loop: "{{ ec2['instances'] }}"
FIX
- debug:
msg: "{{ item['instance_id'] }}"
loop: "{{ ec2['instances'] }}"
loop_control:
label: "{{ item.instance_id }}"
I think I found your answer #duffney.
By the looks of things Was addressed as a bug/feature and amended
https://github.com/ansible/ansible/issues/35493
Does it help out what you are looking for?

Ansible hosts' inventory yml doesn't support repeated ip with_items

The following:
store_controller:
hosts:
SERVER:
ansible_host: "{{ STORE_CTL }}"
mgmt_ip: "{{ ansible_host }}"
global_mgmt:
hosts:
SERVER:
ansible_host: "{{ NOMAD_SERVER }}"
mgmt_ip: "{{ ansible_host }}"
node_exporter: ##if comment the part from here to end, it's ok####
hosts:
"{{ item }}":
ansible_host: "{{ item }}"
mgmt_ip: "{{ ansible_host }}"
with_items:
- "172.7.7.1"
- "172.7.7.9"
- "172.7.7.12"
But Ansible doesn't let me use 'with_items' here. It seems that ansible does not support iterator over hosts.
How can I define the hosts array in group node_exporter for my three IPs ?
All you need to define is this:
node_exporter:
hosts:
172.7.7.1:
172.7.7.9:
172.7.7.12:
vars:
mgmt_ip: "{{ inventory_hostname }}"
Explanation:
mgmt_ip defines only a template (string value) which will be resolved at the time it is used.
For each target machine inventory_hostname (thus mgmt_ip) will resolve to the IP address of currently executing host.
Using ansible_host to assign the same value as the inventory host name is an empty action, so you don't need that at all.
I don't think it brings any value/clarity to the code, but since you commented it was working for you, that's the way to achieve it with multiple hosts. All you achieve is creating an alias mgmt_ip to inventory_hostname.
Regarding the premise of the question:
with_items: for YAML is a dictionary key name (string value). It is Ansible that might or might not make use of it.
It makes use of it when it is specified in a task (there it has a semantic meaning).
Otherwise it either ignores it (never uses this key), or reports an error.
Looking quickly at your code, you have an indentation problem.
Try to add 2 spaces before "{{item}}:"

Resources