Error when set variable with condition - Ansible Playbook on Linux - ansible

Getting error when using an if/else condition to set a variable in a playbook on Red Hat.
I tried a few different permutations of quotes, brackets etc.
Executed as "ansible-playbook -e env=dev playbook.yaml"
Set Vars:
vars:
certenv: "{{ '-eng.dev.' if {{env}} == 'eng' else '.dev.' if {{env}} == 'dev' else '.uat.' if {{env}} == 'stg' else '.prd.' if {{env}} == 'prd' }}"
Task
- name: Update server.xml Cert
lineinfile:
dest: "{{tomcat}}/conf/server.xml"
regexp: '^(.*)certificateFile(.*)$'
line: 'certificateFile="{{tomcat}}/webapps/{{appwar}}/certificates/app{{certenv}}domain.cer"'
Error
fatal: [localhost]: FAILED! => {"msg": "An unhandled exception occurred while templating '{{ '-eng.dev.' if {{env}} == 'eng' else '.dev.' if {{env}} == 'dev' else '.uat.' if {{env}} == 'stg' else '.prd.' if {{env}} == 'prd' }}'.
Error was a <class 'ansible.errors.AnsibleError'>, original message: template error while templating string: expected token ':', got '}'. String: {{ '-eng.dev.' if {{env}} == 'eng' else '.dev.' if {{env}} == 'dev' else '.uat.' if {{env}} == 'stg' else '.prd.' if {{env}} == 'prd' }}"}
Expecting the certenv variable to be set as ".dev." for example.

As per comments: Modify your variable to
certenv: "{{ '-eng.dev.' if env == 'eng' else '.dev.' if env == 'dev' else '.uat.' if env == 'stg' else '.prd.' if env == 'prd' }}"
and run your playbook with:
ansible-playbook myplaybook.yml -e "env=dev".

For jinja2, the syntax is:
vars:
certenv: "{% if env == 'eng' %}-eng.dev.{% elif env == 'dev' %}.dev.{% elif env == 'stg' %}.uat.{% elif env == 'prd' %}.prd.{% endif %}"
You do not need to put the variables in {{...}} because they are inside the jinja2 markers {%...%}.
You can also make it more readable:
vars:
certenv:
"{% if env == 'eng' %}
-eng.dev.
{% elif env == 'dev' %}
.dev.
{% elif env == 'stg' %}
.uat.
{% elif env == 'prd' %}
.prd.
{% endif %}"

An option would be to use selectattr and map. The play below
vars:
cert_options:
eng: "-eng.dev."
dev: ".dev."
stg: ".uat."
prd: ".prd."
env: "stg"
tasks:
- set_fact:
certenv: "{{ cert_options|dict2items|selectattr('key', 'match', env)|map(attribute='value')|list }}"
- debug:
var: item
loop: "{{ certenv }}"
gives:
"item": ".uat."
This hint might help to solve the problem.
The fixed syntax of the code is below. (not tested)
- name: Update server.xml Cert
lineinfile:
dest: "{{ tomcat }}/conf/server.xml"
regexp: "^(.*)certificateFile(.*)$"
line: "certificateFile={{ tomcat }}/webapps/{{ appwar }}/certificates/app{{ certenv }}domain.cer"

Related

ansible jinja2 template delimiters failed if using 'when'

I have this code, where the first task fails and the second task produces the following warning:
[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: {{ VRF }} == 17
I am assuming this warning and the failure of the first task are happening for the same reason. From what I understand, the variables are different types. How do I fix this?
---
- name: PE_CE
hosts: localhost
tasks:
- include_vars: /opt/netsec/ansible/orchestration/capabilities/PE_CE/PE_CE_1.yml
- name: Build PE config Cisco
template:
src=/opt/netsec/ansible/orchestration/cisco_templates/PE_CE_CISCO_config_PE.j2
dest=/opt/netsec/ansible/orchestration/config_outputs/new/{{PE_HOSTNAME}}
when: "{{ PX_HOSTNAME }} == None"
- name: Build CE config Cisco
template:
src=/opt/netsec/ansible/orchestration/cisco_templates/PE_CE_CISCO_config_CE.j2
dest=/opt/netsec/ansible/orchestration/config_outputs/new/{{CE_HOSTNAME}}
when: "{{ VRF }} == 17"
What I really want to do is when: "{{ VRF }} == 17" and "{{ PX_HOSTNAME }} == None", or something like {{ PX_HOSTNAME }}|length < 1"
You do not need {{ and }} with when. Do it like this:
when: PX_HOSTNAME == "None" and when: VRF == "17"
Here is some documentation
when: PX_HOSTNAME == "None" will check if PX_HOSTNAME contains the string "None".
If you want to run the task if it is empty, do when: not PX_HOSTNAME or if you want to run the task it it is not empty, do when: PX_HOSTNAME.
You can use the length as well: when: PX_HOSTNAME|length > 0

Conditional ansible to set variable

Tried all luck but doesnot work. I would require to set the environment variable check with a condition and then run a play or task on the main.yml while doing includes and using 2 tasks.
main.yml
- include: createnonprod.yml
when: "{{ environment }}" == 'dev' or "{{ environment }}" == 'qa' or "
{{ environment }}" == 'preprod'
- include: createprod.yml
when: "{{ environment }}" == 'prod'
The environment is set on groups_vars variable file "all"
environment:
"{{ lookup('env','ENVIRONMENT') }}"
But this logic to check fails
(Or)
I need to run this logic so that it calls the task with a condition to check the variable
create.yml
- name: Install all users from IAM of the AWS Account.
shell: "{{ scriptdir }}/install.sh -i {{ iamgroup }},{{ sudogroup }} -s {{ sudogroup }}"
when: "{{ environment }}" == 'dev' or "{{ environment }}" == 'qa' or "{{ environment }}" == 'preprod'
- name: Install all users from IAM of the AWS Account.
shell: "{{ scriptdir }}/install.sh -i {{ iamgroup }},{{ sudogroup }} -s {{ sudogroup }}"
when: "{{ environment }}" == 'prod'
Please help me with a logic that works. I get this error:
fatal: [localhost]: FAILED! => {"failed": true, "reason": "ERROR!
Syntax Error while loading YAML.\n\n\nThe error appears to have been in
'/tmp/ansible/roles/provision/users/tasks/create.yml': line 18, column
22, but may\nbe elsewhere in the file depending on the exact syntax
problem.\n\nThe offending line appears to be:\n\n when:\n - {{
env_type }} == 'dev'\n ^ here\nWe could be wrong,
but this one looks like it might be an issue with\nmissing quotes.
Always quote template expression brackets when they\nstart a value. For
instance:\n\n with_items:\n - {{ foo }}\n\nShould be written
as:\n\n with_items:\n - \"{{ foo }}\"\n"}
The When Statement
The when clause, which contains a raw Jinja2 expression without
double curly braces
when: environment == 'dev' or environment == 'qa' or environment == 'preprod'
when: environment == 'prod'
What if you try this way.
Define a variable to handle the lookup of your environment:
vars:
env_value: "{{ lookup('env', 'ENVIRONMENT') }}"
and then use this variable in the when condition:
when: env_value == "dev"
Simple example:
- hosts: "localhost"
vars:
env_value: "{{ lookup('env', 'ENVIRONMENT') }}"
tasks:
- shell: echo "I've got {{ env_value }} and am not afraid to use it!"
when: env_value == "prd"
Example in your code:
- name: Install all users from IAM of the AWS Account.
shell: "{{ scriptdir }}/install.sh -i {{ iamgroup }},{{ sudogroup }} -s {{ sudogroup }}"
when: env_value == 'dev' or env_value == 'qa' or env_value == 'preprod'
Please, also look at this link about Ansible environment variable name being reserved.

Set Ansible role defaults conditionally

Pseudocode:
If env is de, set variable name to hello else if env is prod, set variable name to bye.
I tried https://serverfault.com/questions/715769/ansible-change-default-value-according-to-a-condition
- name: setting variable
set_fact: name="hello"
when: "{{ env }}" == "de"
- name: setting variable
set_fact: name="bye"
when: "{{ env }}" == "prod"
ERROR! The default/main.yml file for role 'trial' must contain a
dictionary of variables
As per my requirement, it needs to be done in role.So it is done as follows:
name: "{% if env == 'de' %}hello{% elif env == 'prod' %}bye{% endif %}"

Escape Forward Slash in When Condition

I'm trying to do an Ansible "when compare string not equals"
like this :
when: "{{ result.stdout }} != '/var'"
How do I escape the / in '/var' because it's throwing a :
The error was: template error while templating string: unexpected '/'.
I have tried escaping the / with a \ but it throws the error :
ERROR! Syntax Error while loading YAML.
The offending line appears to be:
shell: rsync -a /var/ "{{ result.stdout }}"
when: "{{ result.stdout }} != '\/var'"
^ here
I have tried creating a variable in defaults :
defaults -> main.yml
var_partition: /var
tasks -> main.yml
when: "{{ result.stdout }} != {{ var_partition }}"
but it throws the error :
"The conditional check '{{ result.stdout }} != {{ var_partition }}' failed.
The error was: template error while templating string: unexpected '/'.
String: {% if /disk1 != /var %}
This works :
when: "{{ result.stdout != '/var' }}"
I replaced slashes with dashes and got rid of this error:
vars:
- local_var_name: "{{ var_name | regex_replace('/', '-') }}"
tasks:
some_task:
...
when: local_var_name
You should not use braces in when statement:
... the when clause, which contains a raw Jinja2 expression without double curly braces ...
In your example, simply use:
when: result.stdout != '/var'

how to use variable in "when" statement in ansible?

I am trying to use a variable in when statement in ansible ,
my code snippet looks like this :
- name: git repo for non prod env
git:
repo=http://url/repo.git
dest=/opt/dest
version={{ bld_env }}
when: ( "{{ bld_env }}" == "rc" ) or ( "{{ bld_env }}" == "sandbox" ) or ( "{{ bld_env }}" == "dev" ) or ( "{{ bld_env }}" == "qa" )
This is not working and gives an a error as :
The offending line appears to be:
version={{ bld_env }}
when: "{{ bld_env }}" == "rc"
^ 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 }}"
Let me know where I am wrong.
I think you don't have to use "{{ bld_env }}" == "rc".
Just compare variable to value bld_env == "rc" and so on as it is written in documentation

Resources