Ansible with_dict 模板使用 [英] Ansible with_dict template use

查看:24
本文介绍了Ansible with_dict 模板使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下任务:

- name: copy server.xml
  template: src=server.xml dest=/var/containers/{{ item.key }}/conf
  with_dict: containers

而且我还在 group_vars 中添加了容器字典

And I've also added the containers dictionary in my group_vars

containers:
  frontend:
    http_port: 8080
  backend:
    http_port: 8081

最后是 server.xml 中的相关片段

Finally here is the relevant snippet from server.xml

<Connector port="{{ http_port }}" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

我想要发生的是在模板模块中使用了相关的 http_port.但相反,我得到了错误:

What I want to happen is that the relevant http_port gets used in the template module. But instead I get and error:

fatal: [localhost] => {'msg': "AnsibleUndefinedVariable: 一个或多个未定义变量:'http_port' 未定义", 'failed': True}

fatal: [localhost] => {'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'http_port' is undefined", 'failed': True}

这可能吗?如何利用项目的值进行变量替换?

Is this possible? How do I leverage an item's values for variable substitution?

推荐答案

使用 {{ item.value.http_port }} 是正确的解决方案.

Using {{ item.value.http_port }} is exactly the right solution.

当您传递 with_dict 时,它会循环将容器字典中的每个项目作为 {{ item }} 传递的任务,其中该项目有一个键以及字典项目包含的任何值 -在您的情况下,键/值对的键是 http_port,值是这两个不同的整数 - 但是您可以传递非常复杂的嵌套字典,在那里使用 {{ item.value 访问事物变得更加重要.http_port }} 你想出的语法.

When you pass with_dict, it loops through the task passing each of the items in your containers dictionary as {{ item }}, where the item has a key and whatever values that dictionary item contains - in your case, key/value pairs where the keys are http_port and the values are those two different integers - but you can pass seriously complex nested dictionaries where it gets even more important to access things with the {{ item.value.http_port }} syntax you came up with.

当您使用更复杂的模板时要小心的是,当您有一些额外的变量要为一个主机(或容器,或其他)模板时,如何混合使用内容并设置默认值并使用 if 语句,但是不是另一个.

The thing to be wary of as you get to more complex template usage is how to mix stuff up and set defaults and use if-statements when you have some extra variables to template for one host (or container, or whatever) but not another.

要掌握它,请阅读 Jinja2,Ansible 解释模板的语言.一个很好的例子是在前端通过 SSL 提供文件,而不是后端.使用类似 {{ foo | 的语法default('bar') }} 以避免 Ansible 因您尝试使用未定义的变量和 if 语句而生气,以确保您只对您需要的东西进行模板化.

To get to grips on it, read up on Jinja2, the language Ansible interprets templates in. A good example would be something like serving files over SSL on your frontend here, but not the backend. Use syntax like {{ foo | default('bar') }} to avoid Ansible getting angry about you trying to use undefined variables, and if-statements so as to make sure you're only templating the stuff you need.

一个粗略的草图 - 假设你有:

A rough sketch - say you had:

containers:
  frontend:
    http_port: 8080
    https_port: 8443
    ssl_cert: ./files/keystore
    ssl_pass: "{{ vaulted_vars.ssl_pass }}" 
  backend:
    http_port: 8081

在这种情况下,假设您有一项任务需要在需要时将该密钥库复制到文件系统上,您可以使用以下内容:

In that case, imagining you'd had a task to copy that keystore over onto the filesystem when needed, you could use something along the lines of:

<Connector port="{{ item.value.http_port }}" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="{{ item.value.https_port | default('8443')" />
           {% if item.value.ssl_cert is defined %} 
           scheme="https" secure="true" SSLEnabled="true"
           keystoreFile="${user.home}/.keystore" keystorePass="{{ item.value.ssl_pass }}"
           clientAuth="false" sslProtocol="TLS"/>
           {% endif %}

快乐的模板!

这篇关于Ansible with_dict 模板使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆