Ansible to print the variable value having another variable inside it - ansible

In a.yml file, I have stored data like below
---
Server:
"Node1" : ["Node1", "Owner1", "ID1"]
"Node2" : ["Node2", "Owner2", "ID2"]
Now, in xyz.yml playbook, I tried to debug a variable as below and I am passing the Node_Name in commandline (ansible-playbook xyz.yml -e "Node_Name=Node1")
---
- name: "Print Variable value"
hosts: all
gather_facts: no
vars:
Node_Name: Node
ID_Name: "{{ Server.{{ Node_Name }}[2] }}"
tasks:
- name: "Print the id"
debug:
msg:
- "The id is {{ ID_Name }}"
But this is failing with error - Template error while templating string :expected name or number
Can someone please help to fix this and let me know how can I get the ID printed as output. Here expected output is ID1

You never nest {{...}} markers.
Recall that to access a nested variable. the syntax Server.Node1 is exactly equivalent to Server["Node1"]. The second syntax allows us to make use of variables (and string interpolation) on the key, so we can write:
Server[Node_Name]
In other words:
- name: "Print Variable value"
hosts: all
gather_facts: no
vars:
Node_Name: Node
ID_Name: "{{ Server[Node_Name][2] }}"
tasks:
- name: "Print the id"
debug:
msg:
- "The id is {{ ID_Name }}"

Related

Ansible: Output of 'loop' with 'register' module

I'm trying to get the output of my Ansible script using register module but the loop I'm using is probably causing some issue.
Whats a default way of using register module with loop?
Code:
---
- name:
hosts:
gather_facts:
tasks:
- name: Execute file
ansible.builtin.shell:
environment:
"setting environment"
register: output
loop:
"value"
- debug:
vars: output.std_lines
Whats a default way of using register module with loop?
It is just registering the result.
The only difference will be, that a single task will provide you just with an dictionary result (or output in your example) and registering in a loop will provide with a list result.results (or output.results in your example). To access the .stdout_lines you will need to loop over the result set .results too.
You may have a look into the following example playbook which will show some aspects of Registering variables, Loops, data structures, dicts and lists and type debugging.
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- name: Create STDOUT output (single)
command: 'echo "1"'
register: result
- name: Show full result (single)
debug:
var: result
- name: Show '.stdout' (single)
debug:
msg: "The result in '.stdout': {{ result.stdout }} is of type {{ result.stdout | type_debug }}"
- name: Create STDOUT output (loop)
command: 'echo "{{ item }}"'
register: result
loop: [1, 2, 3]
loop_control:
label: "{{ item }}"
- name: Show full result (loop)
debug:
var: result
- name: Show '.stdout' (loop)
debug:
msg: "The result in '.stdout': {{ item.stdout }} is of type {{ item.stdout | type_debug }}"
loop: "{{ result.results }}"
loop_control:
label: "{{ item.item }}"
By running it and going through the output you can get familiar with the differences in your tasks.
Further Q&A
Register Variables in Loop in an Ansible Playbook
Ansible: loop, register, and stdout
Register variables in loop in Ansible playbook
... and many more here on SO.

finding and setting new var from ansible_net_config

I'm trying to come up with a way to find a piece of text in a very long string. I'm using the ios_facts module to grab a Cisco config. I'm looking for the text below and want to set it as a new var. The 'ip nbar protocol-pack' portion will never change but the value after that will vary from node to node.
{{ ansible_net_config }} =
o ip source-route\n!\n!\nip nbar protocol-pack bootflash:pp-adv-isr4000-169.1-34-47.0.0.pack \n!\n!\n!\n!\nip nb
the value of ansible_net_config is much longer. I trimmed it down for sanity sake.
This is what I want the var set to:
ip nbar protocol-pack bootflash:pp-adv-isr4000-169.1-34-47.0.0.pack
Here is the code I'm working with. I don't know if I should keep trying regex_search or try json_query or something I'm not yet aware of.
---
- name: Cisco NBAR Test
connection: ansible.netcommon.network_cli
hosts: all
tasks:
- name: collect facts
cisco.ios.ios_facts:
gather_subset:
- config
- name: set vars
set_fact: config={{ ansible_net_config | regex_search('ip nbar protocol-pack') }}
#set_fact: config={{ ansible_net_config | community.general.json_query('*') }}
- name: show output
debug:
var: config
Any idea on how to do this?
Thanks,
I'd write the regexp like this:
set_fact: config="{{ ansible_net_config | regex_search('.*ip nbar protocol-pack.*') | trim }}"
- name: test
hosts: localhost
tasks:
- name: set vars
set_fact: config="o ip source-route\n!\n!\nip nbar protocol-pack bootflash:pp-adv-isr4000-169.1-34-47.0.0.pack \n!\n!\n!\n!\nip nb"
- name: regex vars
set_fact: result="{{ config | regex_search('.*ip nbar protocol-pack.*') | trim }}"
- name: show
debug:
var: result
result:
TASK [show] ***********************************************************************************************************************************************************************
ok: [localhost] => {
"result": "ip nbar protocol-pack bootflash:pp-adv-isr4000-169.1-34-47.0.0.pack"
}

using ansible variable in task conditonal

When I use an Ansible variable in the failed_when conditional, Ansible complains and fails by telling me that I cannot use Jinja2 expressions with failed_when.
Below snippet does not work:
vars:
var1: "var"
tasks:
- name: "sth"
raw: "anothersth"
register: status
failed_when: var1 in status.stdout
I want to use a regex in the above example and use variable var1 within a regex. This also fails.
I want to fail the task if var1 is repeated in the beginning and at the end of the stdout_lines. I was thinking something like this:
failed_when: regex("^{{var1}}/.*/{{var1}}$") in status.stdout
I wonder whether there is a way to achieve what I intend to do?
===============================================================
Exact play and the description:
Let me explain what I am trying to do:
run a command with "raw" module and register the stdout_lines.
iterate over a list of items, where list is a fact of current ansible host
use failed_when to search a pattern in the registered stdout and fail the task if it is not found
peers_underlay is a list defined in the host file:
peers_underlay:
- ip: "172.16.1.2"
- ip: "172.16.1.6"
This is the play:
- hosts: leaf-2, spine-1
gather_facts: no
tags: [ verify ]
vars:
bgp_underlay: "show ip bgp summary"
tasks:
- name: "underlay bgp test"
raw: "{{ bgp_underlay }}"
register: underlay_status
with_items: "{{ peers_underlay }}"
failed_when: not regex(".*/{{ item['ip'] }}/.*/Estab/.*") in underlay_status.stdout_lines
Q: "Fail the task if var1 is repeated in the beginning and at the end."
A: It's possible to test strings. For example, use regex
- hosts: localhost
vars:
my_stdout1: 'ABC dlkjfsldkfjsldkfj ABC'
my_stdout2: 'alkdjflaksdjflakdjflaksjdflaksdjflasj'
var1: 'ABC'
my_regex: '^{{ var1 }}(.*){{ var1 }}$'
tasks:
- debug:
msg: my_regex match my_stdout1
when: my_stdout1 is regex(my_regex)
- debug:
msg: my_regex match my_stdout2
when: my_stdout2 is regex(my_regex)
gives
"msg": "my_regex match my_stdout1"
The particular task sequence would be
vars:
var1: "var"
my_regex: '^{{ var1 }}(.*){{ var1 }}$'
tasks:
- name: "sth"
raw: "anothersth"
register: status
failed_when: status.stdout is regex(my_regex)

How i can variable dict key in variable file in ansible

in host file i have host vars:
XX.XX.XXX.XXX:
role: value1
then in group vars there is:
my_dict:
value1: [1,2,3]
value2: [3,4,5]
in playbook i'm trying to reach the result_list:
- name: test
hosts: win
gather_facts: no
tasks:
- name: pong
win_ping:
- debug:
msg: "{{my_dict.value1}}"
# this message is ok
- debug:
msg: "{{my_dict.role}}"
#this fails
How can i get ther result value (list) threw the host variable role?
my fail, bad searching: answer
and code will be:
- debug:
msg: "{{dds_hosts[role]}}"

Ansible : evaluate variable inside a variable with register

I have a task where i need to evaluate a variable attribute , where the name is already a vaiable.
here is the scenario :
i'm executing a shell command ( docker ps ) and i'm registering the output in a variable , where the name is already dynamic:
- name : Display running containers for {{apiType}}
shell: docker ps
register: docker_containers_{{apiType}}
when:
- '"containers" in type'
no i want to display the content of that ouput and not only the string itself , so i need to do something like this:
- name: Display running containers for {{apiType}}
debug:
msg: {{docker_containers_{{apiType}}.stdout}}
when:
- '"containers" in type'
of course , this : {{docker_containers_{{apiType}}.stdout}}
is syntaxically refused
i ve tried this : {{docker_containers_[apiType].stdout}}
but it fails.
Suggestions?
This is a FAQ. You can build a string and use that to index the hostvars for your current host:
- name: Display running containers for {{apiType}}
debug:
msg: "{{ hostvars[inventory_hostname]['docker_containers_' + apiType].stdout}}"
when:
- '"containers" in type'
...this assumes that your docker_containers_... variable is a host fact, rather than, say, something set via group_vars or a vars stanza in your playbook.
Here's a runnable example:
- hosts: localhost
gather_facts: false
vars:
apiType: foo
tasks:
- set_fact:
docker_containers_foo:
stdout: "this is foo"
- set_fact:
docker_containers_bar:
stdout: "this is bar"
- name: Display running containers for {{apiType}}
debug:
msg: "{{ hostvars[inventory_hostname]['docker_containers_' + apiType].stdout}}"

Resources