'How to prevent Jinja2 substitution in Ansible playbook?

In my playbook, a JSON file is included using the include_vars module. The content of the JSON file is as given below:

{
  "Component1": {
    "parameter1" : "value1",
    "parameter2" : "value2"
  },

  "Component2": {
    "parameter1" : "{{ NET_SEG_VLAN }}",
    "parameter2": "value2"       
  }
}

After the JSON file is included in the playbook, I am using uri module to sent an http request as given below:

- name: Configure Component2 variables using REST API
  uri:
      url: "http://0.0.0.0:5000/vse/api/v1.0/config/working/Component2/configvars/"
      method: POST
      return_content: yes
      HEADER_x-auth-token: "{{ login_resp.json.token }}"
      HEADER_Content-Type: "application/json"
      body:  "{{ Component2 }}"
      body_format: json

As it can be seen, the body of the http request is send with the JSON data Component2. However, Jinja2 tries to substitute the {{ NET_SEG_VLAN }} in the JSON file and throws and undefined error. The intention is not to substitute anything inside the JSON file using Jinja2 and send the body as it is in http request.

How to prevent the Jinja2 substitution for the variables included from the JSON file?



Solution 1:[1]

You should able to escape the variable even with {{'{{NET_SEG_VLAN}}'}} to tell jinja not to template anything inside that block.

Solution 2:[2]

You should be able to escape the variable with {% raw %} and {% endraw %} to tell Jinja not to template anything inside that block.

Solution 3:[3]

!unsafe

From documentation at https://docs.ansible.com/ansible/2.10/user_guide/playbooks_advanced_syntax.html#unsafe-or-raw-strings:

When handling values returned by lookup plugins, Ansible uses a data type called unsafe to block templating. Marking data as unsafe prevents malicious users from abusing Jinja2 templates to execute arbitrary code on target machines. The Ansible implementation ensures that unsafe values are never templated. It is more comprehensive than escaping Jinja2 with {% raw %} ... {% endraw %} tags.

You can use the same unsafe data type in variables you define, to prevent templating errors and information disclosure. You can mark values supplied by vars_prompts as unsafe. You can also use unsafe in playbooks. The most common use cases include passwords that allow special characters like { or %, and JSON arguments that look like templates but should not be templated.

I am using it all the time, like this:

# Load JSON content, as a raw string with !unsafe
- tags: ["always"]
  set_fact:
    dashboard_content: !unsafe "{{ lookup('file', './dash.json') | to_json }}"

# Build dictionnary via template
- tags: ["always"]
  set_fact:
    cc: "{{ lookup('template', './templates/cm_dashboard.yaml.j2') | from_yaml }}"

## cm_dashboard.yaml.j2 content:
hello: {{ cc_dashboard_content }}

# Now, "cc" is a dict variable, with "hello" field protected!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 β.εηοιτ.βε
Solution 2 ydaetskcoR
Solution 3 β.εηοιτ.βε