当清单主机名位于变量树的顶部时,Ansible Jinja2问题遍历列表

时间:2019-05-07 18:18:53

标签: ansible yaml jinja2

inventory_hostname在变量树的顶部时,我遇到了Jinja2遍历列表列表的问题。

我的YAML(group_vars / all / main.yaml):

router1:
  interfaces:
  - { name: ge-0/0/0, ipv4_address: 192.168.0.11, ipv4_mask: '24' }
  - { name: ge-0/0/1, ipv4_address: 192.168.1.11, ipv4_mask: '24' }
router2:
  interfaces:
  - { name: ge-0/0/0, ipv4_address: 192.168.0.12, ipv4_mask: '24' }
  - { name: ge-0/0/1, ipv4_address: 192.168.1.12, ipv4_mask: '24' }

以下Jinja2模板失败:

{% for interface in [inventory_hostname].interfaces %}
interface {{ interface.name }}
   ...
!
{% endfor %}

我不明白为什么?

我设法使其适用于以下设备,但看起来很丑:

{% for interface in hostvars[inventory_hostname][inventory_hostname].interfaces %}
interface {{ interface.name }}
   ...
!
{% endfor %}

为什么第一个模板不起作用?

2 个答案:

答案 0 :(得分:0)

拥有两个参数文件的正确解决方案,每个组一个:

(group_vars / router1.yaml):

interfaces:
- { name: ge-0/0/0, ipv4_address: 192.168.0.11, ipv4_mask: '24' }
- { name: ge-0/0/1, ipv4_address: 192.168.1.11, ipv4_mask: '24' }

(group_vars / router2.yaml):

interfaces:
- { name: ge-0/0/0, ipv4_address: 192.168.0.12, ipv4_mask: '24' }
- { name: ge-0/0/1, ipv4_address: 192.168.1.12, ipv4_mask: '24' }

在jinja2模板中像下面的示例一样使用它们:

{% for interface in interfaces %}
interface {{ interface.name }}
   ...
!
{% endfor %}

答案 1 :(得分:0)

此语法无效:

{% for interface in [inventory_hostname].interfaces %}

您使用[...] ...之类的括号...

  • 要为列表编制索引,例如my_var[0]my_var[1]
  • 要访问字典值,例如my_var['name']my_var['size']
  • 要创建一个列表,例如[1, 2, 3, 4, 5]

但是您不能像尝试使用它们那样使用它们。


有两种方法可以解决此问题。我认为最优雅的解决方案是将设置从group_vars/all中移出,而是创建:

  • host_vars/router1.yml,其中包含以下内容:

    interfaces:
    - { name: ge-0/0/0, ipv4_address: 192.168.0.11, ipv4_mask: '24' }
    - { name: ge-0/0/1, ipv4_address: 192.168.1.11, ipv4_mask: '24' }
    
  • host_vars/router2.yml,其中包含以下内容:

    interfaces:
    - { name: ge-0/0/0, ipv4_address: 192.168.0.12, ipv4_mask: '24' }
    - { name: ge-0/0/1, ipv4_address: 192.168.1.12, ipv4_mask: '24' }
    

有了这个,您的模板就变成:

{% for interface in interfaces %}

它将为任务当前所针对的主机使用正确的值。


如果您确实需要保留当前配置,则可以使用vars查找,如下所示:

{% for interface in lookup('vars', inventory_hostname).interfaces %}

...但是我真的认为,如果您重组数据,您会发现事情更易于管理。