如何在YAML中用变量作键?Ansible生成Docker节点标签遇阻
解决Ansible Docker节点标签动态索引键未替换的问题
嘿,我知道你遇到的问题了——想用loop的索引作为Docker节点标签的键,但写的代码里{{ idx }}没被解析,直接当成字符串输出了对吧?这其实是YAML字典键的变量插值语法没搞对导致的。
问题根源
当你直接在YAML字典里写"{{ idx }}": "true"时,Ansible并不会把{{ idx }}当成变量解析,而是把整个字符串当作标签的键。要让变量成为字典的键,得用动态生成字典的方式才行。
两种可行的解决方案
方案1:用字典字面量动态生成标签
直接在labels参数里传入一个用变量作为键的字典,语法上要把整个字典用双引号包起来,让Ansible正确解析:
- name: Assigning labels hosts: localhost connection: local gather_facts: no tasks: - name: Assign labels to target machines docker_node: hostname: "{{ item }}" labels: "{{ { idx: 'true' } }}" with_items: "{{ groups['target-machines'] }}" loop_control: index_var: idx
方案2:借助dict过滤器生成字典
如果你更习惯用Ansible过滤器的写法,也可以用dict过滤器来构造这个标签字典,效果是一样的:
- name: Assigning labels hosts: localhost connection: local gather_facts: no tasks: - name: Assign labels to target machines docker_node: hostname: "{{ item }}" labels: "{{ dict([(idx, 'true')]) }}" with_items: "{{ groups['target-machines'] }}" loop_control: index_var: idx
额外小提示:让索引从1开始计数
默认情况下index_var的索引是从0开始的,如果你的需求是标签从1开始(比如第一个节点对应键1,第二个对应键2),只需要给idx加1就行:
# 方案1的修改版 labels: "{{ { idx + 1: 'true' } }}" # 方案2的修改版 labels: "{{ dict([(idx + 1, 'true')]) }}"
验证效果
修改后再执行剧本,你去看docker node inspect的结果就会符合预期了:
第一个节点:
"Spec": { "Labels": { "1": "true" }, "Role": "manager", "Availability": "active" }第二个节点:
"Spec": { "Labels": { "2": "true" }, "Role": "manager", "Availability": "active" }
内容的提问来源于stack exchange,提问作者Naman Arora
相关产品推荐
相关产品推荐

