ansible: reference to a variable from the same list - list

i have a list like this (shortend for the example)
vars:
cli:
terraform:
bin_name: "terraform"
source_url: "https://releases.hashicorp.com.."
bin_to_copy: "/tmp/{{ bin_name }}"
why is it not possible to access {{ bin_name }} name later? I tried w/ cli.bin_name; item.bin_name; item.key.b....
error is always: FAILED! => {"msg": "'bin_name' is undefined"}

It's not possible. See Can't reference a dict key inside the same dict #50280.
FWIW. Take the common values out of the dictionary. For example
vars:
my_bin_name: "terraform"
cli:
terraform:
bin_name: "{{ my_bin_name }}"
source_url: "https://releases.hashicorp.com.."
bin_to_copy: "/tmp/{{ my_bin_name }}"

Related

Ansible building dynamic lists

I'm struggling with syntax to build and add to list dynamically. Would like to do it in an ansible line without going to a jinja2 template. I've been messing around while but the below is where I started. The error is in the line to set the fact.
- name: Assign data to the correct list based on the meta value.
set_fact:
"{{ next_reference.list_name }}": "{{ next_reference.list_name|default([]) + [ input_data ] }}"
loop: "{{ reference_list }}"
loop_control:
loop_var: next_reference
when: input_data.meta == next_reference.meta
reference_list:
- meta: "test1"
list_name: "test1_list"
- meta: "test2"
list_name: "test2_list"
- meta: "test3"
list_name: "test3_list"
input_data_list:
- meta: "anp"
value1: "one"
value2: "two"
Thanks for any assistance may have to go the jinja2 route in the meantime.
Without Jinja, it's not possible to indirectly declare or modify variables in Ansible. Instead, an appropriate data structure might serve the purpose, e.g.
t:
t1: "{{ test1_list|default([]) }} + {{ input_data }}"
t2: "{{ test2_list|default([]) }} + {{ input_data }}"
t3: "{{ test3_list|default([]) }} + {{ input_data }}"
Thanks for the reply. This issue was a reminder that jinja2 and ansible are simple tools not programming languages so the key is to think simplistically.
If you want to change data in a list of dictionaries. The best way to do it is trawl through the current list and pull out the data from the dictionary you want to create a new dictionary put the new data in it or amend it. Stick this new dictionary in a list.
Use rejectattr to remove the dictionary from the current list. Use a simple jinja2 template to recombine the new and old list.

Unable to use regex or search on ansible task for a string search

Team,
I have this task below where I want to create a condition and based on that I want to run other tasks. so as first step, creating condition task itself is failing because am not able to figure out the syntax.. ran several iterations and also check online here https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html
Any hint, am new.
- name: Identify device naming convention[nvme*] using REGEX
debug:
msg: "Found Block Device {{ item.0.device }}"
loop: "{{ local_volume_mount_disks|subelements('partitions') }}"
#when: "{{ item.0.device }}" is regex("nvme2\w+"). #<<<FAILED
when: "{{ item.0.device }}" is search("nvme")
register: nv_device_type
tags: tag_to_create_with_values, tag_to_delete
- name: Output device from REGEX results
debug:
var: nv_device_type
ignore_errors: no
output
ERROR! Syntax Error while loading YAML.
expected <block end>, but found '<scalar>'
The error appears to be in '/ansible-managed/jenkins-slave/slave0/workspace/nvdc/run_ansible_playbook#2/k8s/baremetal/roles/local_volume_mount/tasks/main.yml': line 45, column 33, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
#when: "{{ item.0.device }}" is regex("nvme2\w+")
when: "{{ item.0.device }}" is search("nvme")
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
my values are below
local_volume_mount_disks:
- device: /dev/nvme2n1
partitions:
- number: 1
Just figured out after several iterations..
- name: Identify device naming convention[nvme*] using REGEX
debug:
msg: "Found Block Device {{ item.0.device }}"
loop: "{{ local_volume_mount_disks|subelements('partitions') }}"
when: '"{{item.0.device }}" is search("nvme")'
register: nv_device_type
output
ok: [node1] => (item=[{'device': '/dev/nvmedn1', 'partitions': [{'number': 1, 'start': '0%', 'end': '100%'}]}, {'number': 1, 'start': '0%', 'end': '100%'}]) => {
"msg": "Found Block Device /dev/nvmedn1"
}

Ansible regex filters

I need to extract some text from a variable in ansible.
- name: Find modules
shell: find "{{ role_path }}/files/{{ flavor_modules }}/modules.d/" -name "*.yml"
register: modules_list
- debug:
msg: "aca {{ item }}"
with_items: "{{ modules_list }}"
So modules list returns something like this: /etc/ansible/roles/filebeat/files/something/modules.d/haproxy.yml
I need to register or create a new variable that looks like this: haproxy.yml
I been trying with some regex expressions with no luck.

Ansible. Find mac address and put in into variable

tasks:
- name: Find mac-address
ios_command:
provider: "{{ cli }}"
commands:
- show mac add | i d83b
register: sh_mac_res
sh_mac_res is variable contain string like this:
"22 18a9.0530.d83b DYNAMIC Fa0/17"
How can I put 18a9.0530.d83b into a variable?
set_facts:
mac_address: {{ sh_mac_res.stdout }}.........????
What should I use? regex_search or something else?
Use Python split() function and select the second element of the resulting list:
- set_fact:
mac_address: "{{ sh_mac_res.stdout.split()[1] }}"

Ansible loop over multiple dictionaries/lists

In my playbook, I'd like to loop over two dictionaries (or one dictionary and one list). One is a list (or dictionary) of Domains, the other one is a dictionary that includes the aws-regions with the corresponding server-IPs to use for the DNS-Entries for latency based routing. I want to set for each domain one DNS-record for each aws-region.
- name: set DNS records for Domains
route53:
zone: "{{ item[0].key }}"
record: "{{ item[0].key }}"
value: "{{ item[1].value.server_ip }}"
region: "{{ item[1].key }}"
identifier: "{{ item[1].key }}"
with_nested:
- "{{ domain_dict }}"
- "{{ aws_dict }}"
With two lists, the example works fine. How do I get it to work using at least one dictionary?
domain_dict: (could be a list as well)
domain_dict:
mytest1.example:
mytest2.example:
mytest3.example:
aws_dict:
aws_dict:
us-east-1:
# some other region-related stuff like ami-id,...
server_ip: 1.2.3.4
us-west-1:
# some other region-related stuff
server_ip: 1.2.3.5
us-west-2:
# some other region-related stuff
server_ip: 1.2.3.6
#all other aws-regions
A custom lookup_plugin is your best bet. Otherwise it'll be an ugly sequence of set_fact.
PS:
While you ordinarily shouldn’t have to, should you wish to write your own ways to loop over arbitrary datastructures, you can read Developing Plugins for some starter information. Each of the above features are implemented as plugins in ansible, so there are many implementations to reference