Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case statement for setting var in Ansible/Jinja2

I'm using Ansible with Jinja2 templates, and this is a scenario that I can't find a solution for in Ansible's documentation or googling around for Jinja2 examples. Here's the logic that I want to achieve in Ansible:

if {{ existing_ansible_var }} == "string1"
  new_ansible_var = "a"
else if {{ existing_ansible_var }} == "string2"
  new_ansible_var = "b"
<...>
else
  new_ansible_var = ""

I could probably do this by combining several techniques, the variable assignment from here: Set variable in jinja, the conditional comparison here: http://jinja.pocoo.org/docs/dev/templates/#if-expression, and the defaulting filter here: https://docs.ansible.com/playbooks_filters.html#defaulting-undefined-variables ,

...but I feel like that's overkill. Is there a simpler way to do this?

like image 559
s g Avatar asked Jun 04 '15 06:06

s g


People also ask

How do I add VARS to Ansible playbook?

The include_vars module can be used in a playbook or role to load variables from a file. Simply set the value of include_vars to a local file to load the variables it contains: --- # ./hello_world. yml - name: print greeting hosts: "*" tasks: - include_vars: name_vars.

What is j2 Jinja2 used for in Ansible?

Ansible uses Jinja2 templating to enable dynamic expressions and access to variables and facts.

What is Jinja2 template in Ansible?

Jinja2 templates are simple template files that store variables that can change from time to time. When Playbooks are executed, these variables get replaced by actual values defined in Ansible Playbooks. This way, templating offers an efficient and flexible solution to create or alter configuration file with ease.


2 Answers

If you just want to output a value in your template depending on the value of existing_ansible_var you simply could use a dict and feed it with existing_ansible_var.

{{ {"string1": "a", "string2": "b"}[existing_ansible_var] | default("") }}

You can define a new variable the same way:

{% set new_ansible_var = {"string1": "a", "string2": "b"}[existing_ansible_var] | default("") -%}

In case existing_ansible_var might not necessarily be defined, you need to catch this with a default() which does not exist in your dict:

{"string1": "a", "string2": "b"}[existing_ansible_var | default("this key does not exist in the dict")] | default("")

You as well can define it in the playbook and later then use new_ansible_var in the template:

vars: 
   myDict:
     string1: a
     string2: b
   new_ansible_var: '{{myDict[existing_ansible_var | default("this key does not exist in the dict")] | default("") }}'
like image 101
udondan Avatar answered Sep 17 '22 21:09

udondan


Something like this would work, but it's ugly. And as @podarok mentioned in his answer, it's likely unnecessary depending on exactly what you're attempting to do:

- name: set default
  set_fact: new_ansible_var= ""

- name: set to 'a'
  set_fact: new_ansible_var= "a"
  when: "{{ existing_ansible_var }} == string1"

- name: set to 'b'
  set_fact: new_ansible_var= "b"
  when: "{{ existing_ansible_var }} == string2"

etc.

like image 38
Bruce P Avatar answered Sep 18 '22 21:09

Bruce P