Search code examples
jsonamazon-web-servicestagsjqaws-cli

Automation to detect untagged resources in AWS


I am trying to run api call to find the list of AWS resources that dont have correct tags and get the output into json file:

Name: "Unused" Name in Resolve = false

aws resourcegroupstaggingapi get-resources --tags-er-page 100 | jq '.ResourceTagMappingList{} | select(contains({Tags: [{Key: "Name"}, [{Key: "Name in Resolve"}]}))' > tag.json

But, it gives the list of all the tags along with tag "Name" and "Name in Resolve". I want to filter the output with only those 2 tags with its values

Actual Results:

{
 "ResourceARN":"arn:aws:backup:$Region:$AccountId:recovery-point:xxxxxxxx",
 "Tags": [
  {
   "Key: "Name",
   "Value": "eks-efs-non-prod"
  },
  {
   "Key": "Deptt"
   "Value": "XXX"
  },
  {
   "Key": "BusinessUnit"
   "Value": "XXX"
  },
  {
   "Key": "Name in Resolve"
   "Value": "True"
  },
  {
   "Key": "SysOwner"
   "Value": "XXX"
  },
  {
   "Key": "IT Director"
   "Value": "Ankur K"
  }
 ]
}
{
 "ResourceARN":"arn:aws:backup:$Region:$AccountId:recovery-point:xxxxxxxx",
 "Tags": [
  {
   "Key: "Name",
   "Value": "Unused"
  },
  {
   "Key": "Deptt"
   "Value": "XXX"
  },
  {
   "Key": "BusinessUnit"
   "Value": "XXX"
  },
  {
   "Key": "Name in Resolve"
   "Value": "false"
  },
 {
   "Key": "SysOwner"
   "Value": "XXX"
  },
  {
   "Key": "IT Director"
   "Value": "Ankur K"
  }
 ]
}

Expected Results:

{
 "ResourceARN":"arn:aws:backup:$Region:$AccountId:recovery-point:xxxxxxxx",
 "Tags": [
  {
   "Key: "Name",
   "Value": "eks-efs-non-prod"
  },
  {
   "Key": "Name in Resolve"
   "Value": "True"
  }
 ]
}
{
 "ResourceARN":"arn:aws:backup:$Region:$AccountId:recovery-point:xxxxxxxx",
 "Tags": [
  {
   "Key: "Name",
   "Value": "Unused"
  },
  {
   "Key": "Name in Resolve"
   "Value": "false"
  }
 ]
}

Solution

  • The JSON sample has some small errors, but using it (with corrections) as input, the relevant jq filter would be:

    .Tags |= map(select(.Key | IN("Name", "Name in Resolve")))
    

    If your jq does not have IN/1, then you could simply copy its def into the beginning of your program:

    def IN(s): first((s == .) // empty) // false;