Ansible:根据服务账号列表提取指定JSON对象
问题:从两个JSON文件中筛选匹配的服务账号权限
现有文件内容
1. 服务账号列表 acct_list.json
存储需要管理的服务账号清单:
{ "service_accounts": { "sql-automation": "Automation Service account for Cloud SQL Instances", "gke-proxy": "GKE proxy account", "gke-node": "Default GKE nodes service account", "syncdata": "Data sync between environments" } }
2. 权限模板 key_auths.json
定义部分服务账号的默认权限,其中{{ project_id }}为需替换的变量:
{ "key_gen_auths": { "worker": [{ "role": "roles/iam.serviceAccountKeyAdmin", "members": [ "serviceAccount:dataprovisioning@{{ project_id }}.iam.gserviceaccount.com" ] }], "gke-node": [{ "role": "roles/iam.serviceAccountUser", "members": [ "serviceAccount:deployment-automation@{{ project_id }}.iam.gserviceaccount.com" ] }], "sql-automation": [{ "role": "roles/iam.serviceAccountUser", "members": [ "serviceAccount:deployment-automation@{{ project_id }}.iam.gserviceaccount.com" ] }] } }
需求说明
筛选出同时存在于acct_list.json的service_accounts中,且在key_auths.json的key_gen_auths有对应权限配置的服务账号及其权限对象,不匹配项直接忽略。
用户原尝试代码
原代码无法实现需求,问题在于遍历keyauth_default.key_gen_auths时拿到的是权限对象值而非账号名称,导致条件判断失效:
- name: Play for reading json hosts: localhost vars: project_id: 123 tasks: - name: acct_list set_fact: acct_list: "{{ lookup('template', 'acct_list.json') }}" - name: key_auth_default set_fact: keyauth_default: "{{ lookup('template', 'key_auths.json') }}" - name: set_fact: access_file: "{{ item }}" with_items: "{{ keyauth_default.key_gen_auths }}" when: item in acct_list.service_accounts - debug: var: access_file
正确实现方案
修正后的Playbook需先将模板渲染后的字符串转为JSON字典,再通过键的交集筛选匹配项:
- name: 筛选匹配的服务账号权限 hosts: localhost vars: project_id: 123 tasks: # 1. 渲染模板并转为可操作的JSON字典 - name: 加载服务账号列表 set_fact: acct_list: "{{ lookup('template', 'acct_list.json') | from_json }}" - name: 加载权限模板并转为可操作的JSON字典 set_fact: keyauth_default: "{{ lookup('template', 'key_auths.json') | from_json }}" # 2. 计算两个字典键的交集,得到同时存在的服务账号名称 - name: 获取匹配的账号名称列表 set_fact: matched_accounts: "{{ acct_list.service_accounts.keys() | intersect(keyauth_default.key_gen_auths.keys()) }}" # 3. 循环合并匹配的账号权限到最终字典 - name: 生成筛选后的权限配置 set_fact: filtered_auths: "{{ filtered_auths | default({}) | combine({ item: keyauth_default.key_gen_auths[item] }) }}" loop: "{{ matched_accounts }}" # 4. 输出最终结果 - name: 打印筛选后的权限配置 debug: var: filtered_auths
代码说明
from_json:将lookup返回的字符串转为字典对象,原代码缺少此步骤导致无法正确访问字典键值。intersect:计算两个键列表的交集,精准定位同时存在的服务账号。combine:循环将匹配的账号权限合并到最终结果字典中。
运行后会得到如下结果:
filtered_auths: gke-node: - members: - serviceAccount:deployment-automation@123.iam.gserviceaccount.com role: roles/iam.serviceAccountUser sql-automation: - members: - serviceAccount:deployment-automation@123.iam.gserviceaccount.com role: roles/iam.serviceAccountUser
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

