gpt4 book ai didi

Ansible - 在 hosts.yml 和 group_vars 之间拆分 YAML 格式的变量列表

转载 作者:行者123 更新时间:2023-12-04 09:36:22 25 4
gpt4 key购买 nike

我有以下目录结构:

├── ansible.cfg
├── hosts.yml
├── playbook.yml
├── group_vars
| ├── all.yml
│ └── vm_dns.yml
└── roles
└── pihole
├── handlers
│ └── main.yml
└── tasks
└── main.yml

ansible.cfg 中,我只有:

[defaults]
inventory = ./hosts.yml

group_vars/all.yml 中,我有一些通用设置:

---
aptcachetime: 3600
locale: "en_GB.UTF-8"
timezone: "Europe/Paris"

然后在 hosts.yml 中设置我的 PiHole 虚拟机:

---
all:
vars:
ansible_python_interpreter: /usr/bin/python3
vm_dns:
vars:
dns_server: true
hosts:
vmb-dns:
pihole:
dns:
- "185.228.168.10"
- "185.228.169.11"
network:
ipv4: "192.168.2.4/24"
interface: eth0
vmk-dns:
pihole:
dns:
- "185.228.168.10"
- "185.228.169.11"
network:
ipv4: "192.168.3.4/24"
interface: eth0

此时,我没有尝试将任何变量移动到 group_vars,一切正常。
现在,我觉得可以通过将对 所有 vm_dns 主机相同的设置分解为一个 group_vars 文件来使主机文件更具可读性。所以我从 hosts.yml 中删除了所有 dnsinterface 行,并将它们放在group_vars/vm_dns.yml 文件,像这样:

---
pihole:
dns:
- "185.228.168.10"
- "185.228.169.11"
network:
interface: eth0

此时,hosts.yml 包含:

---
all:
vars:
ansible_python_interpreter: /usr/bin/python3
vm_dns:
vars:
dns_server: true
hosts:
vmb-dns:
pihole:
network:
ipv4: "192.168.2.4/24"
vmk-dns:
pihole:
network:
ipv4: "192.168.3.4/24"

但是当我现在运行剧本时,一旦它尝试执行使用从 hosts.yml 移动到 group_vars/vm_dns.yml 的变量之一的任务>,Ansible 失败并显示 AnsibleUndefinedVariable: dict object has no attribute ...

我不太确定我是否只是误解了“Ansible 方式”,或者我正在尝试做什么(本质上是将同一列表的不同部分分成 hostsgroup_vars,我想)不仅仅是可行的。我以为 "flattening" that Ansible does本来应该处理这个问题,但似乎 Ansible 根本没有合并 group_vars/vm_dns.yml 中定义的变量。

我已经阅读了 the subject 上的文档, 并找到了一些 almost-related posts , 但没有发现以这种方式展示跨主机和 group_vars 使用的 YAML 格式列表。

编辑:与此问题实际相关的其他 SO 或 Github 问题
In Ansible, how to combine variables from separate files into one array?
https://github.com/ansible/ansible/issues/58120
https://docs.ansible.com/ansible/latest/reference_appendices/config.html#default-hash-behaviour

最佳答案

由于您在主机级别的 list 中保留了 pihole var 的定义,因此默认情况下这个定义会赢得游戏并替换先前在组级别的定义。查看variable precedence documentation .因此,如果您稍后尝试访问例如pihole.dnspihole.network.interface,映射不再存在,ansible 会引发上述错误。

这是 ansible 中的默认行为:按优先顺序用最新的变量替换先前的变量。但是您可以通过设置 hash_behaviour=merge 来更改字典的这种行为。在 ansible.cfg 中。

我对这个设置的个人实验并不十分令人满意:它在我自己的剧本/角色中表现正确,这些剧本/角色是专门为此制作的,但在包含第三方贡献(剧本片段、角色、自定义模块)时开始引发难以追踪的错误....)。所以我绝对不推荐它。而且,这个配置已经deprecated in ansible 2.10因此将在 ansible 2.14 中删除。如果你仍然想使用它,你应该尽可能地限制设置的范围,当然不要在全局级别设置它(即肯定不在 /etc/ansible/ansible.cfg 中)

我现在在全局范围内使用什么来解决这类问题:

  1. 为每个主机/组/任何仅包含特定信息的变量定义变量。在你的情况下为你主持
    ---
    pihole_host:
    network:
    ipv4: "192.168.2.4/24"
  2. 在某处定义这些设置的默认值。在您的情况下,您的团队。
    ---
    pihole_defaults:
    dns:
    - "185.228.168.10"
    - "185.228.169.11"
    network:
    interface: eth0
    (请注意,您可以利用上述变量的优先顺序在不同级别定义这些默认值)
  3. 在全局级别(我通常将其放在 group_vars/all.yml 中),定义您的 var,它将是 default 和 specific 的组合,确保它始终默认为空
    ---
    # Calculate pihole from group defaults and host specific
    pihole: >-
    {{
    (pihole_defaults | default({}))
    | combine((pihole_host | default({})), recursive=true)
    }}

关于Ansible - 在 hosts.yml 和 group_vars 之间拆分 YAML 格式的变量列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62566312/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com