0

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:

JSON:

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

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

More info:

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
Ryan Fisher
  • 1,116
  • 13
  • 26

1 Answers1

0

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"
      }
    ]
  }
]
Ryan Fisher
  • 1,116
  • 13
  • 26