ansible模板中的循环字典

ansible模板中的循环字典,ansible,jinja2,ansible-template,Ansible,Jinja2,Ansible Template,我试图使用jinja2在ansible模板中循环使用字典来创建大量数据源,但收到以下错误[{'msg':“AnsibleUndefinedVariable:一个或多个未定义的变量:'dict object'没有属性'value','failed':True} 当运行调试任务时,它确实会返回正确的值,因此我觉得我的问题在于模板本身,但我一直无法找出我做错了什么 Ansible任务 - name: debug dictionary debug: msg="{{ item.value.db_url

我试图使用jinja2在ansible模板中循环使用字典来创建大量数据源,但收到以下错误
[{'msg':“AnsibleUndefinedVariable:一个或多个未定义的变量:'dict object'没有属性'value','failed':True}

当运行调试任务时,它确实会返回正确的值,因此我觉得我的问题在于模板本身,但我一直无法找出我做错了什么

Ansible任务

- name: debug dictionary
  debug: msg="{{ item.value.db_url }}"
  with_dict: databases

- name: copy tomcat config files
  template: src="{{ item.src }}" dest="{{ item.dest }}"
  with_items:
    - { src: 'context.xml.j2', dest: '/opt/tomcat/conf/context.xml'}
  notify: restart tomcat
  with_dict: databases
Ansible词典

databases:
  db1:
    db_resource: jdbc/db1
    db_maxidle: 50
    db_maxconn: 350
    db_maxwait: 10000
    db_user: dbuser
    db_pass: "{{ dbpass }}"
    db_url: jdbc:postgresql://server:5432/dbname
    db_driver: org.postgresql.Driver
Jinja2模板

{% for items in databases %}
    <resource name="{{ item.value.db_resource }}" auth="container" type="javax.sql.datasource"  maxtotal="{{ item.value.db_maxconn }}" maxidle="{{ item.value.db_maxidle }}" maxwaitmillis="{{ item.value.db_maxwait }}" username="{{ item.value.db_user }}" password="{{ item.value.db_pass }}" driverclassname="{{ item.value.db_driver }}" url="{{ item.value.db_url }}" />
{% endfor %}

在Jinja中,当
databases
是一个字典时,数据库中项目的
将(与Python一样)迭代字典的键,而不是它的键/值对。因此,在您的模板中,
item.value
(我假设它是
items.value
)应该是
数据库[items]
,为了获得与键
items

相关的值,您可以通过修改jinja2模板和任务来实现您的目标,如下所示:

{% for dict_item in quotes %}
  {% for item in dict_item.values() %}
.. {{ item.symbol }}
.. {{ item.price }}
  {% endfor %}
{% endfor %}
Jinja2模板:

<resource name="{{ databases[item].db_resource }}" auth="container" type="javax.sql.datasource"  maxtotal="{{ databases[item].db_maxconn }}" maxidle="{{ databases[item].db_maxidle }}" maxwaitmillis="{{ databases[item].db_maxwait }}" username="{{ databases[item].db_user }}" password="{{ databases[item].db_pass }}" driverclassname="{{ databases[item].db_driver }}" url="{{ databases[item].db_url }}" />
- name: debug dictionary
  debug: msg="{{ databases[item].db_url }}"
  with_items: "{{ databases | list }}"

- name: copy tomcat config files
  template: src="{{ item.src }}" dest="{{ item.dest }}"
  with_items:
    - { src: 'context.xml.j2', dest: '/opt/tomcat/conf/context.xml'}
  notify: restart tomcat
  with_items: "{{ databases | list }}"

希望这对您有所帮助,请根据您的要求调整您的任务

我今天发现,使用dict.values()循环每个dict元素的值,而不是它的键。因此,您应该能够在模板中使用类似的内容

{% for item in databases.values() %}
    <resource name="{{ item.db_resource }}" auth="container" type="javax.sql.datasource"  maxtotal="{{ item.db_maxconn }}" maxidle="{{ item.db_maxidle }}" maxwaitmillis="{{ item.db_maxwait }}" username="{{ item.db_user }}" password="{{ item.db_pass }}" driverclassname="{{ item.db_driver }}" url="{{ item.db_url }}" />
{% endfor %}
{%用于数据库中的项。值()%}
{%endfor%}

我知道这是事实之后的事情,但也许其他人可以利用这个额外的发现来搜索这个答案。

迈克,你的答案今天帮我省了很多搜索时间

在我的例子中,我使用了一个dict列表,所以我必须有两个if语句,类似这样:

{% for dict_item in quotes %}
  {% for item in dict_item.values() %}
.. {{ item.symbol }}
.. {{ item.price }}
  {% endfor %}
{% endfor %}

谢谢大家!

为什么你的第二个任务同时使用
,尤其是当它似乎没有使用后者时?如果这真的有效,我会非常惊讶。嗯,最初我在这个任务中使用with_项有多个文件。我删除了它,但仍然遇到相同的问题。不过把它们分开是有道理的,谢谢。这似乎取得了进展。我得到一个或多个未定义的变量:dict对象现在没有元素,但值显示在错误输出中。所有变量在输出中都有值。有什么想法吗?请详细说明你的答案是如何添加到其他答案中的,也许可以尝试在代码中添加一些注释。