Ansible:根据列表从文件中提取 json 对象

标签 ansible

我有一个像这样的 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",
  }
}

然后我有另一个 json 文件,其中包含帐户所需的默认访问权限(这是一个模板文件)

{
    "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"
            ]
        }]
    }
}

然后在剧本中,我想说: 如果 service_accounts 文件中存在服务帐户,则从 key_gen_auths 中提取该对象(如果存在)(如果 key_gen_auths 中不存在则忽略)。我已经研究了几个选项,例如 selectattr、combine、difference,但我并没有比我真正开始时更进一步,并且想知道如果我能找到正确的语法,我是否可以使用 when 语句更好,任何帮助将不胜感激。

- 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


最佳答案

您无需查找即可读取文件

  vars_files:
    - acct_list.json
    - key_auths.json
  vars:
    project_id: 123

给予

  service_accounts:
    gke-node: Default GKE nodes service account
    gke-proxy: GKE proxy account
    sql-automation: Automation Service account for Cloud SQL Instances
    syncdata: Data sync between environments

  key_gen_auths:
    gke-node:
    - members:
      - serviceAccount:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3f5b5a4f535046525a514b125e4a4b50525e4b5650517f0e0d0c11565e5211584c5a4d49565c5a5e5c5c504a514b115c5052" rel="noreferrer noopener nofollow">[email protected]</a>
      role: roles/iam.serviceAccountUser
    sql-automation:
    - members:
      - serviceAccount:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ef8b8a9f838096828a819bc28e9a9b80828e9b868081afdedddcc1868e82c1889c8a9d99868c8a8e8c8c809a819bc18c8082" rel="noreferrer noopener nofollow">[email protected]</a>
      role: roles/iam.serviceAccountUser
    worker:
    - members:
      - serviceAccount:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8eeaeffaeffefce1f8e7fde7e1e0e7e0e9cebfbcbda0e7efe3a0e9fdebfcf8e7edebefedede1fbe0faa0ede1e3" rel="noreferrer noopener nofollow">[email protected]</a>
      role: roles/iam.serviceAccountKeyAdmin

问:“如果 service_accounts 中存在服务帐户,请从 key_gen_auths 中提取该对象。”

A:从字典中获取键的列表。然后这些列表的交集给出了现有的服务帐户

  service_accounts_list: "{{ service_accounts.keys()|list }}"
  key_gen_auths_list: "{{ key_gen_auths.keys()|list }}"
  service_account_exists: "{{ service_accounts_list|intersect(key_gen_auths_list) }}"

给予

  service_accounts_list: [sql-automation, gke-proxy, gke-node, syncdata]
  key_gen_auths_list: [worker, gke-node, sql-automation]
  service_account_exists: [sql-automation, gke-node]

使用现有帐户列表提取对象并创建字典

  access_file: "{{ dict(service_account_exists|
                        zip(service_account_exists|map('extract', key_gen_auths))) }}"

给予

  access_file:
    gke-node:
    - members:
      - serviceAccount:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0a6e6f7a666573676f647e276b7f7e65676b7e6365644a3b383924636b67246d796f787c63696f6b6969657f647e24696567" rel="noreferrer noopener nofollow">[email protected]</a>
      role: roles/iam.serviceAccountUser
    sql-automation:
    - members:
      - serviceAccount:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="89edecf9e5e6f0e4ece7fda4e8fcfde6e4e8fde0e6e7c9b8bbbaa7e0e8e4a7eefaecfbffe0eaece8eaeae6fce7fda7eae6e4" rel="noreferrer noopener nofollow">[email protected]</a>
      role: roles/iam.serviceAccountUser

用于测试的完整剧本示例

- hosts: localhost

  vars_files:
    - acct_list.json
    - key_auths.json

  vars:

    project_id: 123
    service_accounts_list: "{{ service_accounts.keys()|list }}"
    key_gen_auths_list: "{{ key_gen_auths.keys()|list }}"
    service_account_exists: "{{ service_accounts_list|intersect(key_gen_auths_list) }}"
    access_file: "{{ dict(service_account_exists|
                          zip(service_account_exists|map('extract', key_gen_auths))) }}"
  tasks:

    - debug:
        var: service_accounts
    - debug:
        var: key_gen_auths

#  If the service account exists in service_accounts
#  extract those objects from key_gen_auths

    - debug:
        var: service_accounts_list|to_yaml
    - debug:
        var: key_gen_auths_list|to_yaml
    - debug:
        var: service_account_exists|to_yaml
    - debug:
        var: access_file

关于Ansible:根据列表从文件中提取 json 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74719768/

相关文章:

python - Ansible 在远程服务器上找不到自定义 python 模块

loops - 使用具有大型 YAML var 的循环时 Ansible 性能降低

python - 是否可以创建一个完全独立的 Python 包?

variables - 在Ansible中使用动态键名设置事实

ansible - 如何在执行剧本时在命令行中添加多个 list 文件

python - 在 testinfra 中使用 Ansible 变量

python - 我怎么知道要安装哪个版本的 pip 包?

python - 如何从 ansible-playbook 获取更多可用的错误消息?

ansible - 如何读取其他主机的变量? (不是事实)

ubuntu - 是否可以将 Ansible authorized_key exclusive 与多个 key 一起使用?