skip to Main Content

I try to collect stats from AWS CostExplorer using boto3 lib.
I’ve used method get_cost_and_usage_with_resources ( see details: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ce/client/get_cost_and_usage_with_resources.html ) and it returns response with resources (ID or ARN), their usage and cost.

I would like to map this data with tags related to these resources, but the problem is that i could map them if i have resource ARN. In this case i use method get_resources ( see details: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/resourcegroupstaggingapi/client/get_resources.html ). This method accept only list of ARNs, not IDs.

In case when i have only resource ID ( for example EC2 volume vol-0053852a4f079axxx ), i couldn’t get tags of resource.

So the question is how to get tags of any AWS resource if i have only resource ID and i wouldn’t like to create boto3 client for each service separately?

I’ve tried to use method get_resources ( see details: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/resourcegroupstaggingapi/client/get_resources.html ), but it returns error because it accepts only resource ARN

Code is below:

import boto3

tag_client = boto3.client('resourcegroupstaggingapi')

def get_resource_tags(resource_arn):
response = tag_client.get_resources(
ResourceARNList=[resource_arn]
)
print(response)

get_resource_tags("vol-0e6abc422806b0xxx")

Error is below:

botocore.errorfactory.InvalidParameterException: An error occurred (InvalidParameterException) when calling the GetResources operation: vol-0e6abc422806b0xxx is not a valid AmazonResourceName (ARN)

2

Answers


  1. Chosen as BEST ANSWER

    I've found the answer Instead of making request without tags, we make request and filter response with tags that we're looking for. For example, let's say tag "billing_center" with some test value.

    ce_client = boto3.client('ce')
    ce_client.get_cost_and_usage_with_resources(
            TimePeriod={'Start': start_date.strftime('%Y-%m-%d'), 'End': end_date.strftime('%Y-%m-%d')},
            Granularity='DAILY',
            Metrics=['UnblendedCost'],
            GroupBy=[{'Type': 'DIMENSION', 'Key': 'RESOURCE_ID'}],
            Filter={
                'Tags': {
                    'Key': "billing_center",
                    'Values': ["some_value"],
                    'MatchOptions': ['EQUALS']
                }
            }
        )
    

    If AWS resource doesn't have any tags, we just make request with empty value of tag.

    ce_client.get_cost_and_usage_with_resources(
        TimePeriod={'Start': start_date.strftime('%Y-%m-%d'), 'End': end_date.strftime('%Y-%m-%d')},
        Granularity='DAILY',
        Metrics=['UnblendedCost'],
        GroupBy=[{'Type': 'DIMENSION', 'Key': 'RESOURCE_ID'}],
        Filter={
            'Tags': {
                'Key': "billing_center",
                'Values': [""],
                'MatchOptions': ['EQUALS']
            }
        }
    )
    

    After we've got response, we could map our resources with the necessary tags that we used in the request to boto3 ce client.


  2. resourcegroupstaggingapi only accept the resource arn and so if you really want to use it with ec2 id, then you should create an arn from the id. See documentation here. AWS serve the arn structure for almost resources.

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