skip to Main Content

I am running an AWS cli command to retrieve all the groups that a user belongs to.
The result from a iam list-groups-for-user --user-name "User1" | jq '.Groups[] | . += {name: "User1", groups: [.GroupName]} | {name, groups}' provides the following result:

{
  "name": "User1",
  "groups": [
    "group1"
  ]
}
{
  "name": "User1",
  "groups": [
    "group2"
  ]
}

What I want to achieve is a more concise result where the group names are all added to a single array owned by a shared attribute, the name, for example:

{
  "name": "User1",
  "groups": [
    "group1",
    "group2"
  ]
}

How can I achieve this using jq?

2

Answers


  1. I don’t know how AWS works and what it provides, but based on your current approach you may be looking for an array of unique group names, put into an object alongside with a static string as user name.

    … | jq '{name: "User1", groups: (.Groups | map(.GroupName) | unique)}'
    

    If you wanted to parametrize the string, use --arg

    … | jq --arg name "User1" '{$name, groups: (.Groups | map(.GroupName) | unique)}'
    
    Login or Signup to reply.
  2. Example output of aws iam list-groups-for-user --user-name Bob looks like (docs):

    {
        "Groups": [
            {
                "Path": "/",
                "CreateDate": "2013-05-06T01:18:08Z",
                "GroupId": "AKIAIOSFODNN7EXAMPLE",
                "Arn": "arn:aws:iam::123456789012:group/Admin",
                "GroupName": "Admin"
            },
            {
                "Path": "/",
                "CreateDate": "2013-05-06T01:37:28Z",
                "GroupId": "AKIAI44QH8DHBEXAMPLE",
                "Arn": "arn:aws:iam::123456789012:group/s3-Users",
                "GroupName": "s3-Users"
            }
        ]
    }
    

    If all you want to do is create an object with a made-up username and a list of group names, then construct a new object with the required properties and use map to transform the existing list:

    {
      "name": "User1",
      "groups": .Groups | map(.GroupName)
    }
    

    Or a stream & collect approach (this is how map is implemented):

    {
      "name": "User1",
      "groups": [.Groups[].GroupName]
    }
    

    Output generated when feeding the sample from the official docs:

    {
      "name": "User1",
      "groups": [
        "Admin",
        "s3-Users"
      ]
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search