Boto3 SNS Publish to a wildcard Topic ARN - amazon-web-services

Background
AWS services are regional (e.g. us-west-2, us-east-1) and the boto3 library requires you to set a default region before accessing the Client or Resources. However, the documentation here shows that you can have an SNS Topic ARN with a wildcard substituted for the region. The documentation says:
Documentation: Amazon Simple Notification Service (Amazon SNS)
Syntax:
arn:aws:sns:region:account-id:topicname
arn:aws:sns:region:account-id:topicname:subscriptionid
Examples:
arn:aws:sns:*:123456789012:my_corporate_topic
arn:aws:sns:us-east-1:123456789012:my_corporate_topic:02034b43-fefa-4e07-a5eb-3be56f8c54ce
Code
When I use boto3's SNS Resource/Client to Publish to a Topic ARN (that has a wildcard for the region), I get the below error. When I don't have the wildcard for the region (e.g. I specify us-west-2), everything works. I looked into the boto3 library and it seems to just replace values in a JSON mapping (e.g. inserts Topic string) so I don't understand why this would be an invalid parameter if the documentation above shows that it's valid.
import boto3
client = boto3.client('sns', region_name='us-west-2')
client.publish(TopicArn='arn:aws:sns:*:123456789:some-topic', Message='SomeMessage')
Error Message
File "/Users/wliu/.virtualenvs/myenv/lib/python2.7/site-packages/botocore/client.py", line 548, in _make_api_call
raise ClientError(parsed_response, operation_name)
ClientError: An error occurred (InvalidParameter) when calling the Publish operation: Invalid parameter: TopicArn Reason: A * ARN must begin with arn:null, not arn:aws:sns:*:123456789:my_topic

The documentation does not show that it's valid for the context in which you are using it. You're misapplying or misinterpreting the documentation, confusing the applicability of patterns and literals. Publish requires a literal, and doesn't mention wildcards in the relevant section of the docs of the underlying API.
You can use wildcards as part of the resource ARN when specifing the resource to which an IAM policy statement applies, when the particular service supports resouce-level policies.
From the SNS-specific policy language documentation:
For Amazon SNS, topics are the only resource type you can specify in a policy. Following is the Amazon Resource Name (ARN) format for topics.
Example
If you had a topic named my_topic in each of the different Regions that Amazon SNS supports, you could specify the topics with the following ARN.
arn:aws:sns:*:123456789012:my_topic
http://docs.aws.amazon.com/sns/latest/dg/UsingIAMwithSNS.html#SNS_ARN_Format
However, this is all applicable only to policies, which also support patterns like arn:aws:sns:*:123456789012:bob_*, and such a pattern would (perhaps more intuitively) not be a valid topic for a Publish request.

Related

Cannot list nor describe MSK topic's configuration with AWS CLI

Is it possible to use the AWS CLI tool to list the Kafka MSK topics and describe the configuration of them?
The AWS documentation defines the topic's arn as this: arn:aws:kafka:region:account-id:topic/cluster-name/cluster-uuid/topic-name
I tried to execute the following command (some parts of the id is replaced wit X and the topic name with Y):
aws --profile dev --region eu-central-1 kafka describe-configuration --arn 'arn:aws:kafka:eu-central-1:XXXXXXXXXXX:topic/sre-dev-central-km-msk/0c4e35a9-XXXX-4d32-XXXX-76aa15890225-8/YYYYYYY
But I get the following error:
An error occurred (BadRequestException) when calling the DescribeConfiguration operation: One or more of the parameters are not valid.
You are using topic ARN. But you should be using ARN of MSK configuration:
The Amazon Resource Name (ARN) that uniquely identifies an MSK configuration and all of its revisions.
You can use list-configurations to find ARN of configurations.

Lambda boto3 function to verify if a cloud trail is created

I need help with creating a lambda function to verify certain aws services is enabled or created. I need to create a script that would verify maice, cloudtrail, cofig is all configured/enabled. I started with cloudtrail but it's erroring out. I kinda need help.
import boto3
def lambda_handler(event, context):
client= boto3.client('cloudtrail')
response = client.get_trail_status(Name='Test')
print (response)
Based on the information given so far, I believe that the issue is that you are not properly providing the 'Name':
As per the docs, you need to provide the ARN of the trail, not just the trail name:
Request Parameters
For information about the parameters that are common to all actions,
see Common Parameters.
The request accepts the following data in JSON format.
Name
Specifies the name or the CloudTrail ARN of the trail for which you are requesting status. To get the status of a shadow trail (a
replication of the trail in another region), you must specify its ARN.
The following is the format of a trail ARN.
arn:aws:cloudtrail:us-east-2:123456789012:trail/MyTrail
Type: String
Required: Yes

Using AWS CLI to enable encryption for SNS topic

is there a way to use the AWS CLI to modify attributes of an SNS topic ?
I'm trying to enable Encryption for an SNS topic but the documentation presented here
https://docs.aws.amazon.com/sns/latest/dg/sns-enable-encryption-for-topic.html
only specifies 2 methods:
Using the AWS Console
Using the Java AWS SDK
Here is what you are looking for:
https://docs.aws.amazon.com/cli/latest/reference/sns/set-topic-attributes.html
--attribute-name (string)
A map of attributes with their corresponding values.
The following attribute applies only to server-side-encryption :
KmsMasterKeyId - The ID of an AWS-managed customer master key (CMK) for Amazon SNS or a custom CMK. For more information, see Key Terms . For more examples, see KeyId in the AWS Key Management Service API Reference .
Use set-topic-attribute command.
Example:
aws sns set-topic-attributes --topic-arn arn:aws:sns:us-west-2:123456789012:MyTopic --attribute-name KmsMasterKeyId --attribute-value arn:aws:kms:us-east-2:111122223333:alias/ExampleAlias
You can also use the key id, key id arn or just alias name for the attribute value.

Sending message to AWS Lambda from AWS Pinpoint Custom Channel

I am trying to send messages to my AWS Lambda Function from AWS Pinpoint through custom channel as described here
My problem is about granting permission to AWS Pinpoint to invoke my lambda function. The AWS CLI command provided in the documentation for granting permission is not working. When I execute the aws lambda add-permission command from AWS CLI like described in the documentation, I got the following error:
"no matches found: arn:aws:mobiletargeting:us-east-1:<account-id>:apps/*"
The result doesn't change if I change the ARN to any of the below:
arn:aws:mobiletargeting:us-east-1:<account-id>:apps/<pinpoint-app-id>/*
arn:aws:mobiletargeting:us-east-1:<account-id>:apps/<pinpoint-app-id>/campaigns/*
arn:aws:mobiletargeting:us-east-1:<account-id>:/apps/<pinpoint-app-id>/*
arn:aws:mobiletargeting:us-east-1:<account-id>:/apps/<pinpoint-app-id>/campaigns/*
I tried the same with AWS Cloudformation instead of AWS CLI, I succeeded to grant permission to AWS Pinpoint to invoke my lambda function. At least the Resource Based Policy appeared in the "Permissions" tab of my AWS Lambda Function Console. The source ARN like condition is
arn:aws:mobiletargeting:us-east-1:<account-id>:apps/<pinpoint-app-id>/*
But, when I try to create a campaign under the same pinpoint application (i.e., project) I got the following error message:
"Amazon Pinpoint couldn’t invoke the Lambda function that you specified for custom delivery. Verify that a function policy is assigned to the function and that Amazon Pinpoint is authorized to invoke the function."
I tried different SourceArn like condition including the followings, but the result is the same:
arn:aws:mobiletargeting:us-east-1:<account-id>:apps/<pinpoint-app-id>/*
arn:aws:mobiletargeting:us-east-1:<account-id>:apps/<pinpoint-app-id>/campaigns/*
arn:aws:mobiletargeting:us-east-1:<account-id>:apps/*
arn:aws:mobiletargeting:us-east-1:<account-id>:*
arn:aws:mobiletargeting:us-east-1:<account-id>:/apps/*
Couldn't figure out what the problem is. Any idea about what I am missing will be greatly appreciated.
Thanks in advance!
Interesting but the same aws lambda add-permission command that returned no matches found: arn:aws:mobiletargeting:us-east-1:<account-id>:apps/* is working after sudo su.
This is probably too late, but for anyone that has a similar problem and don't want to go through the whole cloudformation template at least for now.
I had the same issue with
"no matches found: arn:aws:mobiletargeting:us-east-1::apps/*".
It was due to my terminal behaving weirdly with '*', so adding single quotes around the arn worked, like:
arn:aws:mobiletargeting:us-east-1:<account-id>:apps/<pinpoint-app-id>/*

Find Cloudwatch log group for a given resource

I'm creating a logs aggregator lambda to send Cloudwatch logs to a private log analysis service. Given the number of resources used by my employer, it was decided to create a subscription lambda that handles log group subscription to the aggregator.
The solution works fine, but it requires to manually search a resource's log group via amazon console and then invoke the subscription lambda with it.
My question:
Is there a way to, given a resource arn, find which log group is mapped to it? Since I'm using Cloudformation to create resources it is easy to export a resource's arn.
UPDATE
To present an example:
Let's say I have the following arn:
arn:aws:appsync:<REGION>:<ACCOUNTID>apis/z3pihpr4gfbzhflthkyjjh6yvu
which is an Appsync GraphQL API.
What I want it a method (using te API or some automated solution) to get the Cloudwatch log group of that resource.
You can try the describe-log-groups command. It is available on the cli, must also be there on the API.
To get the names of the log groups you can go with:
aws logs describe-log-groups --query 'logGroups[*].logGroupName' --log-group-name-prefix '/aws/appsync/[name-of-the-resource]'
Output will look like this:
[
"/aws/appsync/[name-of-your-resource]"
]