regex_replace by a var content in jinja template - ansible

I have a jinja template and i want to replace a string by the content of a variable
exemple :
ansible_hostname: 'host-to'
item.suffixe: 'cool'
the result will be : host-cool-to
I did this :
{{ ansible_hostname | regex_replace('-to', '-{{ item.suffixe }}-to') }}
of course the '-{{ item.suffixe }}-to' was not interpreted and the result is :
host-{{ item.suffixe }}-to
Is it possible to use a variable in regex_replace ? How ? in the ansible exemple they don't show anythings like this

Q: "Is it possible to use a variable in regex_replace ?"
A: Yes. It's possible. It's easier to put the parameters into variables. For example
- debug:
msg: "{{ hostname | regex_replace(regex, replace) }}"
vars:
hostname: host-to
suffix: cool
regex: '-to'
replace: '-{{ suffix }}-to'
gives
msg: host-cool-to

Related

Dynamic variable name in Jinja for loop [duplicate]

I have vars where I put something like this:
vars/main.yml
hello_port: 80
world_port: 81
in my ansbile file I load the vars with
vars_files:
- ./vars/main.yml
This is how I initialize m_name:
- name: set_fact
set_fact:
m_name:
- 'hello'
- 'world'
and after that I have task with iterate using with_items:
- debug:
msg: "{{ (item + '_port') }}"
with_items: "{{ m_name }}"
But I've got as output
hello_port
world_port
not their values.
OK I find that if I use debug var it is working. But If I want to put this expression "{{ (item + '_port') }}" for an example in shell task it does not evaluate it. Is there a way to evaluate the dynamically created variables name - to get the value?
https://docs.ansible.com/ansible/2.5/plugins/lookup/vars.html
- name: Show value of 'variablename'
debug: msg="{{ lookup('vars', 'variabl' + myvar)}}"
vars:
variablename: hello
myvar: ename
{{ hostvars[inventory_hostname][item + '_port'] }}
http://docs.ansible.com/ansible/latest/faq.html#how-do-i-access-a-variable-name-programmatically
I think you are searching for:
{{ vars[item ~ '_port'] }}
I guess best way is to use varnames_lookup
- name: List variables that start with qz_
debug: msg="{{ lookup('varnames', '^qz_.+')}}"
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/varnames_lookup.html

Ansible - combining string with an existing variable to register into another variable

I want to combine a fact set with set_facts with a string variable and register it as a new variable.
I think, we cannot register a new variable in an Ansible playbook. So can I use set_facts again to combine a previous set_fact with an existing variable?
I am not sure about the syntax here.
Here is an example:
- vars:
list_1: usera,userb,userc
- set_fact:
list_2: "userd,usere,userf"
Now I want to combine both of the string with comma in between and get a variable value like this:
final_list: usera,userb,userc,userd,usere,userf
set_fact:
final_list: "{{ list_1 }},{{ list_2 }}"
or use the string concatenation operator
set_fact:
final_list: "{{ list1 ~ ',' ~ list_2 }}"

Ansible conditional template variable substitution

I am trying to create configuration files from a template with include variables based on the fourth character of {{ ansible_hostname }}.
What works:
playbook:
---
- hosts: spock
roles:
- templaterole
role:
---
- name: testing autofs template on spock
template:
src=autofs
dest=/tmp/autofs
with_items:
- "{{ var_a }}"
when: ('{{ ansible_hostname }}' == "spock")
vars/main.yml:
var_a:
-
var_1: 'this is var_a1'
var_2: 'this is var_a2'
var_b:
-
var_1: 'this is var_b1'
var_2: 'this is var_b2'
template:
{{ item.var_1 }}
#
{{ item.var_2 }}
#
This works as expected and the output produces a /tmp/autofs file on the spock host that looks like:
this is var_a1
#
this is var_a2
#
Now, if I try to write the file based on trying to pull out the 4th character of the {{ ansible_hostname }}, the play does not get a match on the conditional and does not write the file. I'm trying this conditional in my role:
---
- name: testing autofs template on spock
template:
src=autofs
dest=/tmp/autofs
with_items:
- "{{ var_a }}"
when: ('{{ ansible_hostname }} | cut -c4' == "c") or
('{{ ansible_hostname }} | cut -c4' == "k")
the play skips this task due to not matching on the conditional. Ultimately i want to be able to pull any 4th character of our hostnames as this will always be predictable (can only be one of 4 known characters which defines my environment and lets me define the correct template variables based on these diff production environments.)
Can anyone help me to redefine my when statement such that i can do or conditionals and pull characters out of defined ansible variables like ansible_hostname?
Don't use curly brackets inside when statement, it's already a Jinja2 statement.
And in Jinja2 statements you use | to apply filter, but there is no cut filter available.
Your statement should be as simple as:
when: ansible_hostname[3] in 'ck'

How can I use default with variable in Ansible?

I know that I can use a simple hardcoded string in default but I am trying to do this:
myvar: "{{ lookup('env','var1') | default("{{var2}}",true) }}"
But it adds that as a string instead of evaluating it.
Once you opened a Jinja2 expression with {{ you don't need to open it again (especially quoted) and you can refer to the variables by their names:
myvar: "{{ lookup('env','var1') | default(var2, true) }}"

How can I use jinja2 to join with quotes in Ansible?

I have an ansible list value:
hosts = ["site1", "site2", "site3"]
if I try this:
hosts | join(", ")
I get:
site1, site2, site3
But I want to get:
"site1", "site2", "site3"
Why not simply join it with the quotes?
"{{ hosts | join('", "') }}"
Ansible has a to_json, to_nice_json, or a to_yaml in it's filters:
{{ some_variable | to_json }}
{{ some_variable | to_yaml }}
Useful if you are outputting a JSON/YAML or even (it's a bit cheeky, but JSON mostly works) a python config file (ie Django settings).
For reference: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#filters-for-formatting-data
The previous answer leaves "" if the list is empty. There is another approach that may be more robust, e.g. for assigning the joined list as a string to a different variable (example with single quotes):
{{ hosts | map("regex_replace","(.+)","\'\\1\'") | join(',')}}
From a json file file_name.json array like this
"hosts": [
"site1",
"site2",
"site3"
]
Set_fact from a json file
- name: Set variables from parameters file
set_fact:
vars_from_json: "{{ lookup('file', 'file_name.json') | from_json }}"
Use join with double quote and comma, and wrap all around in double quote
- name: Create host list
set_fact:
host_list: "{{ '\"' + vars_from_json.hosts | join('\"'', ''\"') + '\"' }}"

Resources