Here is my problem I need to use one variable 'target_host' and then append '_host' to it's value to get another variable name whose value I need. If you look at my playbook. Task nbr 1,2,3 fetch the value of variable however nbr 4 is not able to do what I expect. Is there any other way to achieve the same in ansible?
---
- name: "Play to for dynamic groups"
hosts: local
vars:
- target_host: smtp
- smtp_host: smtp.max.com
tasks:
- name: testing
debug: msg={{ target_host }}
- name: testing
debug: msg={{ smtp_host }}
- name: testing
debug: msg={{ target_host }}_host
- name: testing
debug: msg={{ {{ target_host }}_host }}
Output:
TASK: [testing] ***************************************************************
ok: [127.0.0.1] => {
"msg": "smtp"
}
TASK: [testing] ***************************************************************
ok: [127.0.0.1] => {
"msg": "smtp.max.com"
}
TASK: [testing] ***************************************************************
ok: [127.0.0.1] => {
"msg": "smtp_host"
}
TASK: [testing] ***************************************************************
ok: [127.0.0.1] => {
"msg": "{{{{target_host}}_host}}"
}
Seems to me you can just use the
var
option instead ofmsg
:Gives:
You need to put quotes around it:
-- edit --
My bad. Didn't read carefully enough.
This (AFAIK) isn't possible. The primary limitation that stops us doing this (no matter how you spin it), is 'variable expansion' in ansible is a single pass process and what you want requires multiple-passes.
Only [seriously hacky] ways I can think of are:
template
and execute it.lookup('template', ...)
filter. Unfortunately I have no experience with Jinja2 templates so not quite sure if this is even an option.I'm currently using the array-like syntax of Jinja 2. I don't think this is a great solution, but I've yet to find something better.
Let me give an example with one of my abstracted tasks. See my variable configuration and example task below:
In the above example I'm using the
with_items
Ansible loop, which runs the task for each item and makes the{{ item }}
variable available accordingly.This results in creating 3 Docker containers each with the proper container name based on the items list, and the proper image retrieved from the external variables I've configured.
Even though this example uses
with_items
, it is of course adaptable to your problem with use of your own variables.Although this works perfectly fine in this situation, I'm afraid this requires the variables you'd like to access to be part of some parent variable (
containers
in this example). Therefore I'd recommend to split variables with a.
to construct a hierarchy, and not with a_
.A variable like
a.b.c
whereb
is dynamic, would be accessible usinga[b].c
.A variable like
a.b
whereb
is dynamic, would be accessible usinga[b]
.A solution you would use might look like (untested):
Note that the variables are configured slightly differently, because it's structure is hierarchical.
You have two ways to choose:
1. General using.
2. Using fact
You can nest your lookups like so:
If you have a variable like
vars: myvar: xxx xxx_var: anothervalue
the working Ansible syntax:
- debug: msg={{ vars[myvar + '_var'] }}
will give you the analogue of:
- debug: msg={{ xxx_var }}