Reputation: 91
I have a json file like so
{
"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",
}
}
Then I have another json file with the default access the accounts need (this is a template file)
{
"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"
]
}]
}
}
Then in the playbook, i would like to say: If the service account exists in the service_accounts file, extract that object from key_gen_auths if it exists there (if it doesnt exist in key_gen_auths ignore). Ive looked at several options, like selectattr, combine, difference, but im no further than when i started really, and wonder if im just better with a when statement if i can find the right syntax, any help would be appreciated.
- 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
Upvotes: 3
Views: 212
Reputation: 6198
Well, I think this shows the data you want, in debug
, and you can use that with set_fact
as you see fit:
- name: Play for reading json
hosts: localhost
vars_files:
- acct_list.json
- key_auths.json
vars:
project_id: 123
tasks:
- debug:
msg: "{{ key_gen_auths[item] | default('Not Found') }}"
loop: "{{ service_accounts.keys() }}"
ignore_errors: yes
Upvotes: 1
Reputation: 68254
You can read the files without lookup give 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:[email protected]
role: roles/iam.serviceAccountUser
sql-automation:
- members:
- serviceAccount:[email protected]
role: roles/iam.serviceAccountUser
worker:
- members:
- serviceAccount:[email protected]
role: roles/iam.serviceAccountKeyAdmin
Q: "If the service account exists in service_accounts
extract that object from key_gen_auths
."
A: Get the lists of the keys from the dictionaries. Then the intersect of these lists gives the existing service accounts
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) }}"
give
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]
Use the list of existing accounts to extract the objects and create a dictionary
access_file: "{{ dict(service_account_exists|
zip(service_account_exists|map('extract', key_gen_auths))) }}"
give
access_file:
gke-node:
- members:
- serviceAccount:[email protected]
role: roles/iam.serviceAccountUser
sql-automation:
- members:
- serviceAccount:[email protected]
role: roles/iam.serviceAccountUser
Example of the complete playbook for testing
- 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
Upvotes: 2