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

referencing variables from defaults/main.yml in ansible role

我的角色设置如下

roles/test/task/main.yml

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

roles/test/template/test.j2

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

roles/test/vars/main.yml

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

        - name: StarWars
          var1: han
          var2: solo

roles/test/defaults/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 是扁平的“键:值”对,我可以让它从 [=45 中提取值=]/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 }}"

给予

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

错误:combine 需要字典

如果你 运行 Ansible 2.9 或更早版本的代码你会看到错误

{"msg": "|combine expects dictionaries, got ({'var2': 'skywalker'}, {'name': 'TheSimpsons', 'var1': 'homer', 'var2': 'simpson'})"}

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

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

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

答:你在合并字典。 YAML 中的字典(映射)是一组 无序 的 key/value 节点对。参见 Mapping. The sorting is up to you. See