转义或区分Ansible和<service>中的jinja模板变量。

时间:2017-06-28 10:09:11

标签: ansible jinja2 prometheus ansible-template

历史:

过去几个月我们一直在使用Ansible来部署我们的服务和配置文件,我们一直在使用Ansible变量。 变量放在我们的(config_name).yml.j2文件中,这使我们可以轻松地进行更改,而无需对所有配置进行硬编码。

例如在Ansibles group_vars中我们可能有:

metric_port_var: "9100"

并且(config_name).yml.j2会稍微包含一行:

EXPOSE_METRIC_PORT={{ metric_port_var}}

部署配置时,框中的配置现在为:

EXPOSE_METRIC_PORT=9100

问题:

现在我们正在为AlertManager / Prometheus部署配置。 出现的问题是AlertManager还在我们尝试部署的自己的配置文件中使用jinja模板变量。这些其他jinja模板将来自包装盒上的其他配置文件。

这意味着我们的(config_name).yml.j2理论上包含大括号变量的混合,其中一些可能属于Ansible,而其他可能属于另一个文件。

我们不能再使用Ansible的“模板”模块来部署我们的配置,因为在group_vars中找不到变量时会抛出错误,而特定变量应该来自AlertManager。

我们需要一种方法来混合jinja模板或逃避一些花括号而不是其他花括号。现在我们回到硬编码配置并让AlertManager使用所有变量。

3 个答案:

答案 0 :(得分:3)

  

AlertManager还在其自己的配置文件中使用jinja模板变量

alertmanager使用Go模板。

请参阅Jinja文档的escaping部分:

key={{ '{{' }}the_var{{ '}}' }}

将呈现为:

key={{the_var}}

答案 1 :(得分:3)

这对我来说很好用:

template.j2:

foo {{ ansible_var }}
bar {{ '{{' }} other_var {{ '}}' }}
zzz {%raw%}{{ another_var }}{%endraw%}

输出:

foo val
bar {{ other_var }}
zzz {{ another_var }}

答案 2 :(得分:0)

Brian-Brazil是对的。 (按照预期,谷歌他的名字)

我们在这里使用这种技术并且在我们的Ansible模板中有.j2.j2文件,这些文件转换为在容器启动时解析的docker中的.j2文件。
以下是一个更具体的用例示例。 alertmanager确实使用了Go模板,但是当我在jinja模板中混合使用时,这看起来可能会让人感到困惑。我同意。

假设您有一个名为alertmanager.yml.j2的文件,其中以下行是摘录。

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 %}

你的Ansible任务看起来像这样。

- name: copy helper scripts
  template: src={{ item }}.j2 dest={{ container_dir }}/{{ item }} mode=0755
  with_items:
    - alertmanager.yml