Reputation: 1628
I am using Ansible to create users across multiple environments. I'm trying to consolidate my user var that contains all of the data needed to create new unix users into a globally shared var. To do this, I was planning on using subelements to control which users are created on which hosts etc.
However, I am struggling to figure out how to filter down this data so that I can the correct set of credentials for the current host.
I need to filter down the "environments" key to just the element with the "name" value that I'm looking for, but retain the parent object's keys in the result.
What I have/what I want:
{
"users": [
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
},
{
"name": "env_two",
"key": "keystring",
"user_groups": [
"three",
"four"
],
"host_groups": "all"
}
]
},
{
"name": "user2",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_three",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
}
]
}
]
}
{
"users": [
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
}
]
}
]
}
I was able to get close using this query, but I don't know how to further narrow the result down so that all of the keys in each "user" object remain but filter down the sub-element "environments" to the ones matching my query.
JMESPath query: users[?environments[?name=='env_one']]
Output:
{
"users": [
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
},
{
"name": "env_two",
"key": "keystring",
"user_groups": [
"three",
"four"
],
"host_groups": "all"
}
]
}
]
}
This is the original dataset in YAML if that is useful:
YAML:
---
users:
- name: user1
token: token
unix: unixstring
mysql: mysqlstring
environments:
- name: env_one
key: keystring
user_groups:
- one
- two
host_groups: all
- name: env_two
key: keystring
user_groups:
- three
- four
host_groups: all
- name: user2
toke n: token
unix: unixstring
mysql: mysqlstring
environments:
- name: env_three
key: keystring
user_groups:
- one
- two
host_groups: all
Upvotes: 0
Views: 1047
Reputation: 1628
Well, I found a solution that will work:
- set_fact:
users: >
{{ users
| json_query("[?environments[?name=='" + ansible_environment + "']].{
name: name,
yubikey_public_id: yubikey_public_id,
unix_initial_password: unix_initial_password,
mysql_initial_password: mysql_initial_password,
environments: environments[?name=='" + ansible_environment + "']}") }}
It would be better if I could somehow include all of the "users" element's keys without calling them out explicitly (name, token, unix...) so that the query didn't have to change if I added more fields to that element. But I don't know if that is possible.
Query result:
[
{
"name": "user1",
"token": "token",
"unix": "unixstring",
"mysql": "mysqlstring",
"environments": [
{
"name": "env_one",
"key": "keystring",
"user_groups": [
"one",
"two"
],
"host_groups": "all"
}
]
}
]
Upvotes: 1