3

历史:

在过去的几个月里,我们一直在使用 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 使用所有变量。

4

3 回答 3

7

这对我来说很好:

模板.j2:

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

输出:

foo val
bar {{ other_var }}
zzz {{ another_var }}
于 2017-06-28T13:51:43.070 回答
5

AlertManager 也在它自己的配置文件中使用了 jinja 模板变量

alertmanager 使用 Go 模板。

请参阅 Jinja 文档的转义部分:

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

将呈现为:

key={{the_var}}
于 2017-06-28T10:30:59.893 回答
0

布赖恩-巴西是正确的。(不出所料,谷歌他的名字)

我们在这里大量使用这种技术,并且在我们的 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
于 2017-06-28T11:55:59.513 回答