You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 05:50:24