how to avoid variable replacement with ansible - ansible

I am having a playbook like
- name: Set Config Knox - knox-config
uri:
url: "http://{{ ansible_fqdn }}:8080/api/v1/clusters/{{ cluster_name }}"
method: PUT
force_basic_auth: yes
user: "{{ ambari_admin_user }}"
password: "{{ ambari_admin_password }}"
body: "{{ lookup('template','templates/knox/knox-config.json') }}"
body_format: json
In general this works fine. But now I have in the knox-config.json itself content which container {{}}. Now it tries to replace it with variables, that doesn't exists.
Any idea how to avoid the variable replacement in the uri module of ansible?

you are using the lookup plugin with template, so i suppose this invokes the jinja2 templating engine and this is why the replacement its done.
To make jinja "ignore" the {{ and }}, you need to somehow replace them with {{ '{{' }} and {{ '}}' }} respectively.
hope it helps.

Related

Ansbile issue replacing variables

I am new to ansible and I am using variables to use awx polls, the case is that when I want to use these variables in the get_url task
- name: Download Artifact
get_url: "{{ url_artifact }}"
dest: "/tmp/artifacts/{{ app_name }}"
username: "{{ username }}"
password: "{{ password }}"
When I launch an ansible-playbook from my local I get this error
The offending line appears to be:
get_url: "{{ url_artifact }}"
dest: "/tmp/artifacts/{{ app_name }}"
^ 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 }}"
Does anyone know what can be due?
I think the problem is with the missing url key (docs)
Try the following
- name: Download Artifact
get_url:
url: "{{ url_artifact }}"
dest: "/tmp/artifacts/{{ app_name }}"
username: "{{ username }}"
password: "{{ password }}"

How to use ansible when condition when string contains '#'

I am writing playbook to check user principal in kerberos servers. If principal exists it should skip task and if not it should create user principal. I am not sure how to use string with when condition I am trying below but getting errors
"ERROR! Syntax Error while loading YAML.
expected <block end>, but found '<scalar>'
The error appears to be in '/home/revyas/RHELProjects/Atlas/eda-datalake/playbooks/provision-emr.yml': line 42, column 31, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
stat:
path: "{{ user_dir }}"/"{{ keytab_name }}"
^ 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 }}"
Playbook:
- name: Check if user principals exist
command: 'kadmin -w "{{ emr_kdc_admin_password }}" -p kadmin/admin listprincs'
register: user_princs
delegate_to : "{{ emr_kerberos_master }}"
tags: "emr_acct"
- name: Create user kerberos principal if not exist
command: 'kadmin -w {{ emr_kdc_admin_password }} -p kadmin/admin addprinc -randkey {{ kerberos_username }}#{{ emr_kerberos_realm }}'
when: "{{ kerberos_username }}#{{ emr_kerberos_realm }}" not in user_princs.stdout
delegate_to: "{{ emr_kerberos_master }}"
tags: "emr_acct"
User principal from kdc have format given below:
emr-test1-aren-reetika#abd.xyz.com
emr-test-aren#bd.xyz.com
emr-test-integration-test#bd.xyz.com
For the first cited issue, yaml doesn't behave like python or shell which automatically concatenate string literals together
You'll want:
stat:
path: "{{ user_dir }}/{{ keytab_name }}"
And the second error is because yaml believes the leading " is the start of a YAML literal, but in fact it's the start of a Jinja2 literal, thus:
when: '"{{ kerberos_username }}#{{ emr_kerberos_realm }}" not in user_princs.stdout'
Or you can use any of the scalar folding syntaxes, if you prefer that:
when: >-
"{{ kerberos_username }}#{{ emr_kerberos_realm }}"
not in user_princs.stdout
when: "{{ kerberos_username }}#{{ emr_kerberos_realm }}" not in user_princs.stdout
change to
when: "{{ kerberos_username }}\\#{{ emr_kerberos_realm }}" not in user_princs.stdout

Ansible: How to loop set_fact varaibles

i have a ansible-playbook that generates all elements output from remote server, and being saved into variables using set_fact.
i want to try and write each output into separate files using copy module with loop.
set_fact works to store the content but i am struggling to get them specified under copy module using loop.
- name: Playbook to get element details from server
uri:
url: https://10.10.10.19/rest/v1.1/nucli?SetType={{ item }}
body_format: raw
method: GET
headers:
Content-Type: application/xml
Accept: application/xml
Authorization: Bearer password
return_content: yes
register: fileout
with_items:
- My_var1
- My_var2
- My_var3
- My_var4
- set_fact:
My_var1: "{{ fileout.results[0].content }}"
My_var2: "{{ fileout.results[1].content }}"
My_var3: "{{ fileout.results[2].content }}"
My_var4: "{{ fileout.results[3].content }}"
- copy:
content: {{ item }}
dest: "/users/ansible/vars/{{ item }}.txt"
delegate_to: localhost
loop:
- My_var1
- My_var2
- My_var3
- My_var4
Playbook execution:
all steps executed successfully. but in copy module content: {{ item }} is not using set_fact variables, instead they are just copying string My_var1... etc.
Could anyone help me how to use loop for set_fact variable names? So that i can store the content that i have saved from set_fact (example - My_var1: "{{ fileout.results[0].content }}" )
Thanks in advance.

Ansible condition on dictionary item

I have one dictionary list defined:
members_list:
any:
name: any
username: any
anyone:
name:
username: anyone
In my Ansible playbook, I am running multiple docker containers:
docker_container:
name: "{{ item.key }}"
when: "{{ item.key }} != any"
with_dict: "{{ members_list }}"
But I am getting following error:
The conditional check '{{ item.key }} != any' failed. The
error was: error while evaluating conditional ({{ item.key
}} != any): 'any' is undefined
When I run the playbook without when conditional operator it works fine.
Thanks in advance.
You need to quote the word any, because otherwise it is interpreted as a variable reference. Also, you don't need Jinja templating markers in a when expression (the expression is already evaluated as a jinja expression):
- docker_container:
name: "{{ item.key }}"
when: "item.key != 'any'"
with_dict: "{{ members_list }}"
I find nested quotes like this can be confusing, and often opt for one
of YAMLs alternative quoting mechanisms, e.g.:
- docker_container:
name: "{{ item.key }}"
when: >-
item.key != 'any'
with_dict: "{{ members_list }}"
This is identical to the previous version; I just find it easier to
read and understand.

Use Dict in Vars with Templates in Ansible

I'm trying to use templates with different sets of variables for each itteration of a determined set of tasks. For example, in one of the tasks I'd like to set specific values for postgres:
- name: Define values for postgres-ds
template:
src: postgres-ds.xml.j2
dest: /opt/ear_{{ instance_control.value }}/postgres-ds.xml
vars: "{{ postgres_desenv }}"
notify: Restart Service
In role/vars/main.yaml, I defined:
postgres_desenv:
var1: somevalue
var2: someothervalue
...
Still, I get the following error:
fatal: [rmt]: FAILED! => {
"failed": true,
"reason": "Vars in a Task must be specified as a dictionary, or a list of dictionaries
...
When I try to use the same variable in another context, it works fine:
- debug:
msg: "{{ item.key }} - {{ item.value }}"
with_dict: "{{ postgres_desenv }}"
I tried following the answers to this question but I'm still stuck.
My next step is to use a variable to call the variable inside vars, something like:
- name: Define values for postgres-ds
template:
src: postgres-ds.xml.j2
dest: /opt/ear_{{ instance_control.value }}/postgres-ds.xml
vars: postgres_{{ another_var }}
notify: Restart Service
You can do something like this:
- name: Define values for postgres-ds
template:
src: postgres-ds.xml.j2
dest: /opt/ear_{{ instance_control.value }}/postgres-ds.xml
vars:
settings: "{{ postgres_desenv }}"
notify: Restart Service
Then within the template you could refer to, e.g.,
{{ settings.var1 }}
In my case, following the answer above, all i had to do is using {{ item.value.(mydictkey) }} and that's it
In my case i defined a global variable like so:
vars:
vhosts:
web1
port: 8080
dir: /mywebsite
web2:
...
Then in the task I used:
- name: Render template
template:
src: "../templates/httpd.vhost.conf.j2" # Local template
dest: "/etc/httpd/conf.d/{{ item.key }}.conf" # Remote destination
owner: root
group: root
mode: 644
with_dict: "{{ vhosts }}"
In the template I used:
<VirtualHost *:{{ item.value.port }}>
DocumentRoot /var/www/{{ item.value.dir }}
</VirtualHost>
If postgres_desenv is defined in vars/main.yml that will be loaded automatically and be available to the role and rest of the playbook. Why do you have to specify that again using "vars" option in the template module task?

Resources