boto / boto3

AWS SDK for Python
https://aws.amazon.com/sdk-for-python/
Apache License 2.0
9.07k stars 1.87k forks source link

Please provide a way to get an SNS topic ARN by topic name #4177

Closed gh-andre closed 4 months ago

gh-andre commented 4 months ago

Describe the feature

SNS topics should not be created just because a subscriber service was started and it ends up creating a topic only because there's no straightforward way to obtain an ARN of an existing topic by name.

There are currently 3 ways to achieve this, all are hacky, using implementation details or creating a potential security vulnerability by requiring excessive permissions.

Use Case

When a subscriber app/service is started, it should attempt to obtain an SNS topic ARN by topic name and if one doesn't exist, that app should report an error because topics, unlike subscription SQS queues, in many cases are not expected to be created at will and are expected to be configured based on app's notification requirements and participating services.

Proposed Solution

This functionality should behave analogous to get_queue_url, but with SNS topics, so a method like get_topic_arn that takes a topic name would be the solution here. The new method would have its own permissions and would not rely on being able to list SNS topics.

Other Information

I do realize that the underlying SDK does not provide this functionality. My hope is that this feature request would make some sense for an internal request for implementing it in the AWS API. If that's not the case, I would be happy to ask for this feature where it is more appropriate, but I cannot seem to find a place to submit this request for the AWS API.

Acknowledgements

SDK version used

1.34.128

Environment details (OS name and version, etc.)

Windows 11, Ubuntu 22

tim-finnigan commented 4 months ago

Thanks for your feature request. As you mentioned, the SNS team would first need to provide this functionality via an AWS API. I did find an internal tracking item for the request to fetch SNS topic ARNs (and tags) in a single API call. However, it hasn't received many +1s and is therefore a low priority for the team right now. But I will go ahead and add your +1 and use case to the tracking item.

In the meantime, getting the ARN via create_topic, list_topics, or constructing it like this is probably your best bet. You can construct the ARN like this:

import boto3
from botocore.exceptions import ClientError

def get_topic_arn(topic_name):
    sns_client = boto3.client('sns')
    sts_client = boto3.client('sts')

    try:
        caller_identity = sts_client.get_caller_identity()
        account_id = caller_identity['Account']

        response = sns_client.get_topic_attributes(TopicArn=f"arn:aws:sns:{sns_client.meta.region_name}:{account_id}:{topic_name}")
        return response['Attributes']['TopicArn']
    except ClientError as e:
        if e.response['Error']['Code'] == 'NotFoundException':
            return None
        else:
            raise e

topic_name = "topic-name"
topic_arn = get_topic_arn(topic_name)

if topic_arn:
    print(f"Topic ARN: {topic_arn}")
else:
    print(f"Topic '{topic_name}' does not exist.")
github-actions[bot] commented 4 months ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.

gh-andre commented 4 months ago

@tim-finnigan Thanks for adding +1 to the internal work item. Much appreciated.

Constructing ARNs will require apps to provide configuration for AWS partitions and regions, which would make configuration bigger than it needs to be otherwise, where as getting a topic by name requires only proper permissions.

Plus, the account from which I want to access the topic may be not the account where the topic is created.

Getting an ARN from a topic name is really the only good solution for this. I hope it collects enough votes to be implemented on the server side. This is really basic functionality that would keep topics more secure and more usable (i.e. CreateTopic will fail for different attributes, not because permissions, etc.)