在 ansible 角色中引用 defaults/main.yml 中的变量

2024-04-18

我的角色设置如下

角色/测试/任务/main.yml

- name: Generate people files
  template: src=test.j2 dest=/tmp/{{ item.name }}.cfg
  loop: "{{people}}"

角色/测试/模板/test.j2

First Var: {{ item.var1 }}
Second Var: {{ item.var2 }}

角色/测试/vars/main.yml

---
people:
        - name: TheSimpsons
          var1: homer
          var2: simpson

        - name: StarWars
          var1: han
          var2: solo

角色/测试/默认/main.yml

people:
   - var2: skywalker

我的剧本

 - hosts: localhost
   roles:
    - test

当我运行我的剧本时,一切都按预期进行。我在 /tmp 中得到两个带有正确文本的新文件。但是,如果我从 vars/main.yml 文件中删除此 var2 行...

          var2: solo

我希望 defaults/main.yml 中的 var2 值显示在输出中,但我得到的只是这个错误

failed: [localhost] (item={u'var1': u'han', u'name': u'StarWars'}) => {
    "changed": false,
    "item": {
        "name": "StarWars",
        "var1": "han"
    },
    "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'var2'"
}

我尝试过大约 10 种不同的方式格式化 defaults/main.yml,但每次都会出现相同的错误。

如果我设置一个不循环的测试,并且 defaults/main.yml 和 vars/main.yml 是平面“键:值”对,我可以让它从 defaults/main/yml 中提取值就好了。

关于循环的一些事情我只是不明白。我究竟做错了什么?


关于如何组合列表项有更多选项。例如,重命名默认值,例如

people_defaults:
   - var2: skywalker

也重命名变量并创建列表

people_vars:
  - name: TheSimpsons
    var1: homer
    var2: simpson
  - name: StarWars
    var1: than
people: "{{ people_defaults|product(people_vars)|map('combine')|list }}"

gives

people:
  - name: TheSimpsons
    var1: homer
    var2: simpson
  - name: StarWars
    var1: han
    var2: skywalker

角色详情

shell> tree roles/test/
roles/test/
├── defaults
│   └── main.yml
├── tasks
│   └── main.yml
└── vars
    └── main.yml

3 directories, 3 files
shell> cat roles/test/defaults/main.yml 
people_defaults:
  - var2: skywalker
shell> cat roles/test/vars/main.yml 
people_vars:
  - name: TheSimpsons
    var1: homer
    var2: simpson
  - name: StarWars
    var1: han
people: "{{ people_defaults|product(people_vars)|map('combine')|list }}"
shell> cat roles/test/tasks/main.yml 
- debug:
    var: people

错误:组合需要字典

如果您在 Ansible 2.9 或更早版本上运行代码,您将看到错误

{"msg": "|combine 需要字典,得到 ({'var2': 'skywalker'}, {'name': '辛普森一家', 'var1': '荷马', 'var2': '辛普森'})"}

通过将元组映射到列表来解决该问题。此修复是向上兼容的。

people: "{{ people_defaults|product(people_vars)|map('list')|map('combine')|list }}"

Q: “列表的组合不会保留变量的层次结构。”

答:你正在合并字典。 YAML 中的字典(映射)是无序的键/值节点对的集合。看Mapping https://yaml.org/spec/1.2.2/#3211-nodes。排序由你决定。看Ansible 列表未排序 https://stackoverflow.com/questions/64247873/ansible-list-not-ordered/64248023#64248023.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 ansible 角色中引用 defaults/main.yml 中的变量 的相关文章

随机推荐