【问题标题】:Ansible group variable conflictAnsible 组变量冲突
【发布时间】:2020-01-23 02:40:16
【问题描述】:

我遇到了Ansible group vars priority 中描述的问题(功能?),大概是因为我的库存结构不正确。

这个想法是有两个任务,适用于清单中定义的所有“路由器”或“防火墙”。这部分工作正常——Ansible 正确解析库存并区分两者。

问题是由于解析库存的方式,它为每个客户组使用相同的 ansible_user 和 ansible_password。根据文档,这显然是有道理的:

当相同父/子级别的组合并时,就完成了 按字母顺序,最后加载的组会覆盖前一个 团体。例如,a_group 将与 b_group 合并,并且 匹配的 b_group 变量将覆盖 a_group 中的变量。

谁能建议我应该如何纠正这个问题?如果我将“路由器”和“防火墙”子组更改为唯一的,例如 custA_routers、custB_routers,那么它的行为与预期一样。但是,我认为我必须编写针对每个子组的任务。请注意,所有主机都是唯一的 IP 地址。

剧本:

---
- name: Check routers
  hosts: routers
  tasks:
    - name: Do stuff.
      <commands>
- name: Check firewalls
  hosts: firewalls
  tasks:
    - name: Do stuff.
      <commands>

库存:

all:
  vars:
    ansible_connection: network_cli
    ansible_network_os: ios
  children:
    customerOne:
      vars:
        ansible_user: userOne
        ansible_password: <vaulted pass>
      children:
        routers:
          hosts:
            x.x.x.x
            y.y.y.y
        firewalls:
          vars:
            ansible_network_os: asa
          hosts:
            z.z.z.z
    customerTwo:
      vars:
        ansible_user: userTwo
        ansible_password: <vaulted pass>
      children:
        routers:
          hosts:
            x.x.x.x
            y.y.y.y
        firewalls:
          vars:
            ansible_network_os: asa
          hosts:
            z.z.z.z

【问题讨论】:

    标签: ansible ansible-inventory


    【解决方案1】:

    可以简化库存

    all:
      vars:
        ansible_connection: network_cli
        ansible_network_os: ios
      children:
        routers:
          hosts:
            x.x.x.x
            y.y.y.y
        firewalls:
          vars:
            ansible_network_os: asa
          hosts:
            z.z.z.z
    

    并将身份验证数据放入单独的变量中。把它放在最合适的地方。这可能是清单中的“all: vars:”部分、剧本中的“vars:”部分、“group_vars/all”目录...

    auth:
      customerOne:
        ansible_user: userOne
        ansible_password: <vaulted pass>
      customerTwo:
        ansible_user: userTwo
        ansible_password: <vaulted pass>
    

    在playbook顶部添加play,根据外部变量customer赋值变量

    - name: Read variables
      gather_facts: false
      hosts: routers
      tasks:
        - set_fact:
            ansible_user: "{{ auth[customer].ansible_user }}"
            ansible_password: "{{ auth[customer].ansible_password }}"
          run_once: true
    
    - name: Check routers
      hosts: routers
      tasks:
        - name: Do stuff.
          <commands>
    

    运行剧本并指定客户

    ansible-playbook playbook.yml -e "customer=customerTwo"
    

    【讨论】:

    • 感谢弗拉基米尔的解释——我只是希望库存做它不能做的事情吗?这会起作用,但它会让我运行 20 个左右的剧本实例来覆盖所有客户。从技术上讲,这很容易放入一个 shell 脚本中,但并不完全优雅。
    • 是的。 Inventory 做不到,但 Ansible 非常灵活。如何实现这一点有几十种变体。我会用字典去找一个拱形文件。将字典包含在一个简短的剧本中,并将import_playbook 放在其他剧本的顶部。如果您有问题,请打开新问题。
    • 太好了,我想这会让我再次走上正轨。谢谢!
    【解决方案2】:

    我认为根据您的需要创建两个单独的清单(customerOneInventory.yaml 和 customerTwo.yaml 或 router.yaml 和 firewalls.yaml..)是理想的。您只需指定在 ansible playbook 运行期间所需的清单文件。

    ansible-playbook heat-check-playbook.yaml -i customerOneInventory.yaml

    【讨论】:

    • 所以基本上我需要在组变量“冲突”时维护单独的库存?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 2019-05-25
    • 2014-10-21
    相关资源
    最近更新 更多