History:
We've been using Ansible to deploy our services and config files over the last few months and we've been making use of the Ansible variables. The variables get placed in our (config_name).yml.j2 files which allows us to easily make changes without having to hard code all of the config.
For example in Ansibles group_vars we may have:
metric_port_var: "9100"
And the (config_name).yml.j2 will contain a line somewhat:
EXPOSE_METRIC_PORT={{ metric_port_var}}
When the config is deployed the config on the box is now:
EXPOSE_METRIC_PORT=9100
Problem:
Now we're deploying configuration for AlertManager/Prometheus. The issue that has arisen is that AlertManager is also using jinja template variables in it's own configuration file that we are trying to deploy. These other jinja templates will come from other config files on the box.
This means our (config_name).yml.j2 will in theory contain a mix of curly brace variables where some might belong to Ansible and others will belong to this other file.
We can no longer use Ansible's "Template" module to deploy our config due to an error being thrown when a variable isn't found in group_vars, as instead the particular variable should come from AlertManager.
We need a way of either mixing the jinja templates or escaping some curly braces but not others. For now we're back to hard coding our config and letting AlertManager use all the variables.
This works fine for me:
template.j2:
foo {{ ansible_var }}
bar {{ '{{' }} other_var {{ '}}' }}
zzz {%raw%}{{ another_var }}{%endraw%}
output:
foo val
bar {{ other_var }}
zzz {{ another_var }}
AlertManager is also using jinja template variables in it's own configuration file
The alertmanager uses Go templates.
See the escaping section of the Jinja docs:
key={{ '{{' }}the_var{{ '}}' }}
Will be rendered as:
key={{the_var}}
Brian-Brazil is correct. (As to be expected, google his name)
We use this technique a lot here and have .j2.j2 files in our Ansible templates that translate to .j2 files in dockers who are parsed on container start.
Here is an example more specific to your use-case.
The alertmanager indeed uses Go templates but this might look confusing on first sight when mixed in a jinja template, I agree.
Say you have a file called alertmanager.yml.j2 of which the following lines are an extract.
receivers:
- name: '{{ name_of_receiver_group }}'
opsgenie_configs:
- api_key: 123-123-123-123-123
send_resolved: false
{% raw %}
# protecting the go templates inside the raw section.
details: { details: "{{ .CommonAnnotations.SortedPairs.Values | join \" \" }}" }
{% endraw %}
You'll have an Ansible task that looks similar like this.
- name: copy helper scripts
template: src={{ item }}.j2 dest={{ container_dir }}/{{ item }} mode=0755
with_items:
- alertmanager.yml
来源:https://stackoverflow.com/questions/44799543/escape-or-differentiate-between-jinja-template-variables-in-ansible-and-service