【问题标题】:In Ansible is there a way to use with_items and host variables at the same time?在 Ansible 中有没有办法同时使用 with_items 和主机变量?
【发布时间】:2016-09-14 03:10:07
【问题描述】:

所以我想在 3 台主机上运行剧本。每个主机需要 3 个文件(都具有相同的名称)。

文件将是

  • lacpbond.100
  • lacpbond.200
  • lacpbond.300

每个文件都有一个基于 vars/ 文件的唯一 IP 地址。

任务看起来像这样->

- name: configure subinterface bonds
  template: src="ifcfg-lacpbondsub.j2" dest=/etc/sysconfig/network-scripts/ifcfg-lacpbond.{{item.vlan}}
  with_items:
    - { vlan: "100" }
    - { vlan: "200" }
    - { vlan: "300" }
  tags:
    - bonding

所以变量看起来像这样->

  server01:
    loopbacks:
      ipv4: "10.0.0.100"
    SVIS:
      100:
        ipv4: "192.168.0.1"
        prefix: "28"
      200:
        ipv4: "192.168.1.1"
        prefix: "28"
      300:
        ipv4: "192.168.2.1"
        prefix: "28"

现在问题来了。我不确定如何同时使用 with_items 和 vars,所以我可以使用 with_items 来推迟使用哪个变量....这将大大简化剧本的复杂性

这里是模板文件->

{% set host = interfaces[ansible_hostname] -%}
{% set VLAN = item.vlan -%}

DEVICE=lacpbond.{{item.vlan}}
IPADDR={{host.SVIS.{{item.vlan}}.ipv4}}
ONBOOT=yes
BOOTPROTO=none
VLAN=yes

因此,如果我不在另一个 {{}} 中使用 {{}},上述方法显然有效。但是你可以看到我在尝试什么。我可以单独使用 item.X,也可以使用 vars/ 中的任何内容。但我不知道该怎么做 host.SVIS[VLAN].ipv4....

这可能吗?否则我将需要 3 个任务和 3 个模板......如果我需要更多文件,这不是可扩展的......

【问题讨论】:

  • 我在这里很困惑,因为您要求{{host.SVIS...,但您将主机设置为interfaces[ansible_hostname],所以它只是一个字符串,而不是字典。
  • 我不这么认为。例如,如果我的模板只是这个-> `{{item.vlan}}, {{host.SVIS.100.ipv4}} 它会生成-> 100, 192.168.0.1 但是如果我尝试{{host.SVIS[item.vlan].ipv4}} {{interfaces[ansible_hostname].SVIS[item.vlan].ipv4}} 它同样会失败-> `failed: [server01] (item={u'vlan ': u'100'}) => {"failed": true, "item": {"vlan": "100"}, "msg": "AnsibleUndefinedVariable: 'dict object' 没有属性 u'100'"当我将项目变量与该文件夹中的变量结合起来时,它只会被破坏......我正在尝试使用 with_items 从 /vars 中选择项目

标签: python ansible


【解决方案1】:

您的问题有点不清楚(部分原因是我在评论中指出的问题),但如果我理解您的要求,您可以执行以下操作:

IPADDR={{host.SVIS[item.vlan].ipv4}}

请参阅 Jinja 文档的 Variables 部分,其中说:

以下几行做同样的事情:

{{ foo.bar }} 
{{ foo['bar'] }}

更新

您收到该错误(“AnsibleUndefinedVariable: 'dict object' has no attribute u'100'”),因为字典中的键是整数,但 with_items 循环中 vlan 键的值是字符串。即host.SVIS[100]存在,但hosts.SVIS['100']不存在。

鉴于此剧本:

- hosts: localhost
  vars:
    interfaces:
      server01:
          loopbacks:
            ipv4: "10.0.0.100"
          SVIS:
            100:
              ipv4: "192.168.0.1"
              prefix: "28"
            200:
              ipv4: "192.168.1.1"
              prefix: "28"
            300:
              ipv4: "192.168.2.1"
              prefix: "28"
    ansible_hostname: server01
  tasks:
    - name: configure subinterface bonds
      template:
        src: "ifcfg-lacpbondsub.j2"
        dest: ./ifcfg-lacpbond.{{item.vlan}}
      with_items:
        - { vlan: 100 }
        - { vlan: 200 }
        - { vlan: 300 }
      tags:
        - bonding

还有这个模板:

{% set host = interfaces[ansible_hostname] -%}

DEVICE=lacpbond.{{item.vlan}}
IPADDR={{host.SVIS[item.vlan].ipv4}}
ONBOOT=yes
BOOTPROTO=none
VLAN=yes
Raw

我得到三个文件:

$ ls ifcfg-lacpbond.*
ifcfg-lacpbond.100  ifcfg-lacpbond.200  ifcfg-lacpbond.300

每个的内容看起来像:

DEVICE=lacpbond.100
IPADDR=192.168.0.1
ONBOOT=yes
BOOTPROTO=none
VLAN=yes

【讨论】:

  • 试过了,它不起作用:(看看我对你上面评论的评论回复
  • 查看我的更新,它解释了错误的根源。
  • 非常感谢,很有意义。我想我认为这些数字是字符串,因为有 yml 格式的子变量......我猜我很傻
猜你喜欢
  • 2015-06-06
  • 1970-01-01
  • 2015-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多