Ansible 2.13.1中如何为嵌套字典列表的members.name添加前缀
为嵌套字典列表指定字段添加前缀的Ansible实现(2.13.1版本)
需求说明
需要对如下嵌套结构中,每个pool条目下members列表内所有元素的name字段添加ANSIBLE-前缀:
原始数据
pool: - name: "OPENSTACK_POC_POOL_KEYSTONE_SERVICE" port: 5000 members: - name: "OPENSTACK_ECPOCMCTL01_OPENS_KEYSTONE_CONTAINER_097AD5B5" host: 10.5.1.2 - name: "OPENSTACK_ECPOCMCTL02_OPENS_KEYSTONE_CONTAINER" host: 10.5.3.3 - name: "OPENSTACK_ECPOCMCTL03_OPENS_KEYSTONE_CONTAINER" host: 10.3.1.7 state: present - name: "OPENSTACK_POC_POOL_CINDER_API" port: 8776 members: - name: "OPENSTACK_ECPOCMCTL01_OPENS" host: 10.5.2.9 - name: "OPENSTACK_ECPOCMCTL02_OPENS" host: 10.3.2.168 - name: "OPENSTACK_ECPOCMCTL03_OPENS" host: 10.3.1.6 state: present
期望结果
pool: - name: "OPENSTACK_POC_POOL_KEYSTONE_SERVICE" port: 5000 members: - name: "ANSIBLE-OPENSTACK_ECPOCMCTL01_OPENS_KEYSTONE_CONTAINER_097AD5B5" host: 10.5.1.2 - name: "ANSIBLE-OPENSTACK_ECPOCMCTL02_OPENS_KEYSTONE_CONTAINER" host: 10.5.3.3 - name: "ANSIBLE-OPENSTACK_ECPOCMCTL03_OPENS_KEYSTONE_CONTAINER" host: 10.3.1.7 state: present - name: "OPENSTACK_POC_POOL_CINDER_API" port: 8776 members: - name: "ANSIBLE-OPENSTACK_ECPOCMCTL01_OPENS" host: 10.5.2.9 - name: "ANSIBLE-OPENSTACK_ECPOCMCTL02_OPENS" host: 10.3.2.168 - name: "ANSIBLE-OPENSTACK_ECPOCMCTL03_OPENS" host: 10.3.1.6 state: present
问题分析
你之前尝试的方法存在以下问题:
- 使用
combine直接处理members列表时,会将列表合并为单个字典,完全错误地处理了嵌套结构 with_subelements的循环中每次重新赋值data2,没有累积结果,且丢失了原字段以外的信息regex_replace的用法错误,捕获组未正确定义,无法实现前缀添加
正确实现方案
基于Ansible 2.13.1版本,使用Jinja2模板遍历处理每个member,保留原结构所有字段的同时添加前缀:
- name: 初始化处理后的pool变量 set_fact: processed_pool: [] - name: 遍历处理每个pool条目 set_fact: processed_pool: "{{ processed_pool + [ current_pool | combine({'members': updated_members}) ] }}" vars: current_pool: "{{ item }}" # 生成添加前缀后的members列表 updated_members: >- {% set temp_list = [] %} {% for member in current_pool.members %} {% set updated_member = member | combine({'name': 'ANSIBLE-' ~ member.name}) %} {% do temp_list.append(updated_member) %} {% endfor %} {{ temp_list }} loop: "{{ original_pool }}" - name: 输出处理后的结果 debug: var: processed_pool
代码说明
- 先初始化空列表
processed_pool用于存储最终结果 - 循环遍历原始
pool的每个条目:- 对当前条目中的
members列表逐个处理,用combine给name字段添加ANSIBLE-前缀 - 将处理后的
members列表替换原条目对应的字段,再将整个条目添加到processed_pool中
- 对当前条目中的
- 最后通过
debug输出处理后的完整结构
该方案会完整保留原始数据的所有字段(如port、state等),仅修改members内的name字段,完全符合需求。
内容的提问来源于stack exchange,提问作者Yativ
相关产品推荐
相关产品推荐

