Ansible with_dict 模板使用 [英] Ansible with_dict template use
问题描述
我有以下任务:
- 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屋!