I am trying to send SMS to my Mobile when my EC2 instance stops.
I am automatically stopping my EC2 instance and now I want to send SMS to my mobile when it stops.
I created SNS topic with my mobile no. as subscriber.
I created an Alarm when the EC2 stops.
Under SNS > Mobile > Text messaging (SMS) > Text messaging preferences (Edit):
a. I selected "Default message type" as "Transactional".
b. I created a new IAM role.
IAM role policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:PutMetricFilter",
"logs:PutRetentionPolicy"
],
"Resource": [
"*"
]
}
]
}
SNS topic access policy
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:Publish",
"SNS:RemovePermission",
"SNS:SetTopicAttributes",
"SNS:DeleteTopic",
"SNS:ListSubscriptionsByTopic",
"SNS:GetTopicAttributes",
"SNS:Receive",
"SNS:AddPermission",
"SNS:Subscribe"
],
"Resource": "arn:aws:sns:us-west-2:account-id:sns-topic-name",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "account-id"
},
"ArnLike": {
"AWS:SourceArn": "arn:aws:cloudwatch:us-west-2:account-id:alarm:*"
}
}
}
]
}
When the alarm is triggered, I am getting the below error:
{
"actionState": "Failed",
"stateUpdateTimestamp": 1561102479560,
"notificationResource": "arn:aws:sns:us-west-2:account-id:sns-topic-name",
"publishedMessage": null,
"error": "Resource: arn:aws:cloudwatch:us-west-2:account-id:alarm:alarm-name is not authorized to perform: SNS:Publish on resource: arn:aws:sns:us-west-2:account-id:sns-topic-name"
}
I am unable to understand what permission is it expecting.
The cause of the error is most likely due to the policy having incorrect values. I'm not sure which values you changed to protect sensitive values, but you'd need to update sns-topic-name and account-id.
However, I would recommend another way of achieving your goals...
You can use Amazon CloudWatch Events to look out for a specific event (eg an instance changing state to Stopped) and have it send a message to Amazon SNS directly (without using an Alarm).
The steps are:
In the Amazon CloudWatch console, click Rules
Create rule
Service name: EC2
Event type: EC2 Instance State-change Notification
Specific state(s): Stopped
Choose Any instance or Specific instance Id(s)
On the right, under Targets, click Add target
SNS topic
Select your topic
This will then send a message whenever the instance stops.
It seems the error is due to missing permissions on your IAM role for publishing messages to an SNS topic. Make arrangements to attach necessary permissions to the role you use or to the user, like this:
{
"Id": "Policy1415489375392",
"Statement": [
{
"Sid": "AWSConfigSNSPolicy20150201",
"Action": [
"SNS:Publish"
],
"Effect": "Allow",
"Resource": "arn:aws:sns:region:account-id:myTopic",
"Principal": {
"AWS": [
"account-id1",
"account-id2",
"account-id3",
]
}
}
]
}
Related
I have an S3 bucket saving logs, I´m configuring event notification on the bucket to publish on the SQS every time a new log is avalaible.
When I tried to setup the configuration for the event notification(I´m following this walkthrough: https://www.elastic.co/guide/en/observability/8.4/monitor-aws-elastic-agent.html#aws-elastic-agent-enable-event-notification) I got the following error:
First error, permissions
I added that permission but it responds: invalid action that permission does not exist., so I added "s3:PutBucketNotification" permission, but whe I retry to configure the event notification I´m getting the following error:
Even giving me permissions i get this error...
My Access policy file for SQS is like this:
{
"Version": "2012-10-17",
"Id": "example-ID",
"Statement": [
{
"Sid": "example-statement-ID",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": [
"SQS:SendMessage"
],
"Resource": "SQS-queue-ARN",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:*:*:awsexamplebucket1"
},
"StringEquals": {
"aws:SourceAccount": "bucket-owner-account-id"
}
}
}
]
}
Does anybody know why this could be happening?
I have a NodeJS application that publishes message to AWS SNS topic string and a AWS SQS subscription for the same. On the SQS console, I can see the published message. However, I am not clear with the access policy of the SQS queue.
This answer mentions the use of "Principal": "*" - but, that is very broad. One could probably use "Principal" : {"AWS": "*"}; but, that isn't narrow either.
{
"Version": "2012-10-17",
"Id": "Policy1607949016538",
"Statement": [
{
"Sid": "Stmt1607949012567",
"Effect": "Allow",
"Principal": "*",
"Action": [
"sqs:ReceiveMessage",
"sqs:SendMessage"
],
"Resource": "arn:aws:sqs:ap-south-1:463113000000:orders"
}
]
}
Questions
While delivering a message to SQS queue, as a result of subscription, which user is in effect? Same as the one who published to the topic?
I could get the messages to flow into the queue only when I used "Principal" : {"AWS": "*"}. So, how should I define a restrictive policy such that messages are written to queues only as a result of subscription?
What is the equivalent in the AWS SQS CLI to create a queue with "Principal" : {"AWS": "*"} permissions?
The only user that matters is the one that qualifies for the policy as defined for subscription and SQS access policy.
The Condition in policy document can make the overall policy restrictive. See example below.
Adding SQS Permissions with conditions using AWS CLI Command
Example policy document restricting access to account ID.
{
"Version": "2012-10-17",
"Id": "Policy1607960702002",
"Statement": [
{
"Sid": "Stmt1607960701004",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"sqs:ReceiveMessage",
"sqs:SendMessage"
],
"Resource": "arn:aws:sqs:ap-south-1:463113000000:orders",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "463113000000"
}
}
}
]
}
When following Introducing AWS Lambda Destinations I'm told to create an SNS as destination, I do that:
But it doesn't send anything. I had already an SNS able to send mail to my account, and I have adapted the policy to accept everything from everyone (it works with the 'Publish another message' button)
If I call the sns from code it works:
if (event.Success) {
console.log("Success");
context.callbackWaitsForEmptyEventLoop = false;
var sns = new AWS.SNS();
sns.publish({
Message: 'File(s) uploaded successfully',
TopicArn: 'arn:aws:sns:XXX:YYY:ZZZ'
}, (err,data) => {
if (err) {
console.log(err.stack);
return;
}
callback(null);
});
}
But I was hoping not having to write code for that (that what's suggested from the blog entry) so for example if I change the SNS topic I don't have to change the code.
Have any of you succeeded in doing this?
Thanks,
I have reviewed and replicated the AWS Lambda Destinations blog successfully without modifying the sample code snippet from the blog.
I would suggest, you review your SNS configuration (and change us-west-2 region to your AWS region of use as need be) and check if it matches the following:
1. On your SNS topic ('arn:aws:sns:us-west-2:1234567890:YourSNSTopicOnSuccess'), navigate to the access policy and check if you have a policy similar to the following :
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"
],
"Resource": "arn:aws:sns:us-west-2:1234567890:YourSNSTopicOnSuccess"
}
]
}
2. On your Lambda role ('arn:aws:iam::1234567890:role/YourLambdaDestinationRole'), make sure of the following:
(i) The "Trust relationship" of your role has the following statement :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service":"lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
(ii) The Lambda role has an attached policy document similar to one given below:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:publish"
],
"Resource": "*"
}
]
}
The successful published message from Amazon Lambda to SNS topic should output something similar to:
{"version":"1.0","timestamp":"2020-03-22T16:29:50.528Z","requestContext":{"requestId":"43d109d2-54be-4e2e-b8d8-2757e3f06f76","functionArn":"arn:aws:lambda:eu-west-1:1234567890:function:event-destinations:$LATEST","condition":"Success","approximateInvokeCount":1},"requestPayload":{ "Success": true },"responseContext":{"statusCode":200,"executedVersion":"$LATEST"},"responsePayload":null}
Hope this helps.
I want to set up IAM policies to allow an user to publish to SNS to send SMS and to publish to a specific SNS arn.
I have found a way to allow SMS publish without allowing any SNS publish :
Authorization when sending a text message using AmazonSNSClient
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"sns:Publish"
],
"Resource": "arn:aws:sns:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": "*"
}
]
}
But this policy is explicitly denying all other SNS publish, so I can't add a policy allowing a specific SNS.
The problem is that SMS publish does not have a specific arn.
So I am looking at conditions to find a way to limit the allow to publish only SMS. But the specific SMS parameters (PhoneNumber cf https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html#publish-property) cannot be filtered in condition :
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "*",
"Condition": {"Null":{"PhoneNumber":"false"}}
}
]
}
Is there a way to accomplish such a policy ?
Actually to do the trick I found a way using an allow whit the NotResource JSON Policy Element (spec). I use this property to match the resources which do NOT have an ARN:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"NotResource": "arn:aws:sns:*:*:*"
}
]
}
With this trick I can allow all sns Publish without ARN (but I don't know if there is any other services then SMS...).
This also allow me to allow specifics ARN in another policy.
In SNS, I set up a topic.
In IAM, I have set up a policy to allow access to the topics ARN from only from a specific IP address:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"sns:Publish",
"sns:Subscribe"
],
"Resource": "arn:aws:sns:us-east-1:111111111111:topic_name",
"Condition": {
"IpAddress": {
"aws:SourceIp": "xxx.xxx.xxx.x"
}
}
}
]
}
I have attached this policy to a group, and added a user to this group.
From a C# windows application, I can now subscribe and publish the topic from the specified SourceIp listed in the policy.
But in this case, I need to use the AccessKey and SecretAccessKey of the IAM user.
Is there a way that I can bypass needing the AccessKey and SecretKey as long as the SourceIp is correct?
I see that the SNS topic "topic policy", but I could not figure out how to add the IpAddress Condition. Is that possible?
topic policy:
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"
],
"Resource": "arn:aws:sns:us-east-1:111111111111:topic_name",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "111111111111"
}
}
}
]
}
Amazon SNS requires authentication and authorization to use the service. This means either an IAM user or role. This means you must use credentials to access the service.
I would combine IAM User Policies with SNS Policies to control who (user or service) can publish / subscribe to SNS.
There are many AWS services that can use SNS. Your IP address policy may break them.
SNS: Controlling User Access to Your AWS Account