skip to Main Content

I am trying to find resources in my AWS based on certain tag conditions. I have been using jq to achieve it but is there way of using resourcegroupstaggingapi so they provide a direct way to filter resources where any of the specified tags is missing.

I have 2 use cases and this is how i’ve been filtering them using jq :

  1. When SV tag exists but DM does not : aws resourcegroupstaggingapi get-resources --tags-per-page 100 | jq '.ResourceTagMappingList | map(select(.Tags[] | select(.Key == "SV") and select(.Key != "DM")))'
  2. When either of CostCenter, Environment or Team tag does not exist : aws resourcegroupstaggingapi get-resources --tags-per-page 100 | jq '.ResourceTagMappingList | map(select(.Tags[] | (.Key | IN("CostCenter", "Environment", "Team",) | not)))'

I tried doing the same without using jq like this :

  1. When SV tag exists but DM does not : aws resourcegroupstaggingapi get-resources --tag-filters "Key=SV,Values=*" "Key=DM,Values=NULL"
  2. When either of CostCenter, Environment or Team tag does not exist : aws resourcegroupstaggingapi get-resources --tag-filters "Key=CostCenter,Values=" "Key=Environment,Values=" "Key=Team,Values="

But with jq i am able to get the output for both however without jq, i just get empty result for both

{
    "ResourceTagMappingList": []
}

Can someone please check to see what exactly i’m doing wrong. Any help will be appreciated. Thank you.

2

Answers


  1. The AWS CLI resourcegroupstaggingapi is indeed designed to help users get resources based on tags. However, the filtering capability of the resourcegroupstaggingapi is somewhat limited compared to what jq can provide. You might have run into some of these limitations.

    The --tag-filters option in resourcegroupstaggingapi is used for filtering resources that have specific tags with specific values, but it may not work well for more complex conditions such as checking for the absence of certain tags. And I don’t think the Values=NULL and Values= syntax you attempted to use is not supported for representing the absence of a tag.

    Given the limitations of the resourcegroupstaggingapi, it might be prudent to continue using jq for your filtering needs. It is a powerful tool for this purpose, and you have already constructed working commands for your use cases.

    But if you have to not use jq, you might consider creating AWS Lambda functions (using the console.aws.amazon.com/lambda) to automate the filtering process. That would allow you to write more complex logic in a programming language like Python or Go, and could be triggered on a schedule or by other events in your AWS environment.

    Meaning, instead of using the CLI, you could use one of the AWS SDKs (e.g., Boto3 for Python, AWS SDK for Go) to write a script that retrieves and filters your resources based on tags. That would provide you with a lot more flexibility to implement complex logic.

    In the "Execution role" section of the Lambda console, choose "Create a new role with basic Lambda permissions" or use an existing role with the necessary permissions.
    The role would need permissions to call resourcegroupstaggingapi and any other AWS services your function will interact with.

    # Python code snippet using Boto3
    import boto3
    
    def get_filtered_resources():
        client = boto3.client('resourcegroupstaggingapi')
        response = client.get_resources(
            TagFilters=[
                {
                    'Key': 'SV',
                    'Values': []
                },
            ],
            ResourcesPerPage=100
        )
        filtered_resources = [resource for resource in response['ResourceTagMappingList'] if not any(tag['Key'] == 'DM' for tag in resource['Tags'])]
        return filtered_resources
    
    filtered_resources = get_filtered_resources()
    

    And aws lambda invoke --function-name YourFunctionName --payload '{ }' output.txt to test it out.

    Login or Signup to reply.
  2. As VonC said, there isn’t a way to filter resources using resourcegroupstaggingapi, however for your first use case for When SV tag exists but DM does not, the jq query should be :

    jq '.ResourceTagMappingList | map(select(any(.Tags[]; .Key == "SV") and all(.Tags[]; .Key != "DM")))'

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search