I want to add a cloudwatch subscription to a AWS lambda logs thereby making my AWS lambda triggered by cloudwatch logs. What permissions should I add to the role which lambda is using to enable this?
Your Lambda will by default have access to CloudWatch to write logs (with the default AWSLambdaBasicExecutionRole), however if you want to manually add it this is the policy with the required permissions:
{
"document": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
},
"name": "AWSLambdaBasicExecutionRole",
"id": "xxxxx",
"type": "managed",
"arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
Lambda function policy for CloudWatch event trigger on Lambda:
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "uuid",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "lambda:invokeFunction",
"Resource": "arn:aws:lambda:us-east-x:xxxxxxxxxxxx:function:LambdaFunction",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:events:us-east-x:xxxxxxxxxxxx:rule/CloudWatchRule"
}
}
}
]
}
Related
I'm trying to get CloudWatch to send to my SNS topic. The topic is encrypted. However I get this error
Received error: "CloudWatch Alarms does not have authorization to access the SNS topic encryption key."
I have added KMS permissions to the access policy associated with the SNS topic but I get this error when I try to save the policy
Error code: InvalidParameter - Error message: An error occurred while setting the attribute access policy. Invalid parameter: Policy statement action out of service scope!
Is there something in the policy I am misisng?
{
"Version": "2012-10-17",
"Id": "SNS",
"Statement": [
{
"Sid": "SNSPolicy",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish"
],
"Resource": "arn:aws:sns:*:my-account-name:my-topic-name"
},
{
"Sid": "CloudWatch",
"Effect": "Allow",
"Principal": {
"Service": "cloudwatch.amazonaws.com"
},
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": [
"arn:aws:kms:*:my-account-name:key/*"
],
"Condition": {
"StringEquals": {
"kms:RequestAlias": "alias/my-alias-name"
}
}
}
]
}
Cloudwatch is not having necessary permission to access the KMS key which is being used by the SNS topic.
Below SNS topic access policy will give access to the Amazon cloudwatch events.
{
"Version": "2012-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"
],
"Resource": "arn:aws:sns:<region>:<account>:<snstopic>",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "<account>"
}
}
},
{
"Sid": "AWSEvents_test_Id10633056916634",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:<region>:<account>:<snstopic>"
}
]
}
Below customer managed KMS key policy, it will give access to Amazon cloudwatch event source.
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account>:<iamuser>",
"Service": "cloudwatch.amazonaws.com"
},
"Action": "kms:*",
"Resource": "*"
}
]
}
Several AWS services publish events to Amazon SNS topics. To know more, Kindly refer here
I've been all over the internet looking for a solution to this. I have been trying to setup an AWS Lambda function to send a message to SNS every time a file is uploaded to a particular S3 bucket, according to this tutorial. At this point, I have the function setup and I can invoke it successfully. However, when I attempt to connect the function to S3, I get an error stating An error occurred (InvalidArgument) when calling the PutBucketNotification operation: Unable to validate the following destination configurations. According to this article, I should be able to add a permission that will let S3 invoke the Lambda function, like this:
aws lambda add-permission \
--function-name my-file-upload \
--principal s3.amazonaws.com \
--statement-id AcceptFromImport \
--action "lambda:InvokeFunction" \
--source-arn arn:aws:s3:::file-import \
--source-account my_account_id
I did this, and noticed that the policy associated with the Lambda function updated and appeared to be correct. However, the error persists. I've looked at a similar question, here, but none of the solutions here worked.
Execution Role ARN: arn:aws:iam::my_account_id:role/lambda-upload-stream
Execution Role (lambda-upload-stream) trust relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Execution Role policy (my-file-upload):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AccessObject",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::file-import/*"
},
{
"Sid": "SendUpdate",
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "arn:aws:sns:ap-northeast-1:my_account_id:comm-in"
}
]
}
Lambda function ARN: arn:aws:lambda:ap-northeast-1:my_account_id:function:my-file-upload
Lambda function role document
{
"roleName": "lambda-upload-stream",
"policies": [
{
"name": "my-file-upload",
"id": "AWS_ACCESS_KEY_ID",
"type": "managed",
"arn": "arn:aws:iam::my_account_id:policy/my-file-upload",
"document": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AccessObject",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::file-import/*"
},
{
"Sid": "SendUpdate",
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "arn:aws:sns:ap-northeast-1:my_account_id:comm-in"
}
]
}
}
],
"resources": {
"s3": {
"service": {
"name": "Amazon S3",
"icon": "data:image/svg+xml;base64,very_long_base64_string1"
},
"statements": [
{
"resource": "arn:aws:s3:::file-import/*",
"service": "s3",
"effect": "Allow",
"action": "s3:GetObject",
"source": {
"index": "AccessObject",
"policyName": "my-file-upload",
"policyType": "managed"
}
}
]
},
"sns": {
"service": {
"name": "Amazon SNS",
"icon": "data:image/svg+xml;base64,very_long_base64_string2"
},
"statements": [
{
"resource": "arn:aws:sns:ap-northeast-1:my_account_id:comm-in",
"service": "sns",
"effect": "Allow",
"action": "sns:Publish",
"source": {
"index": "SendUpdate",
"policyName": "my-file-upload",
"policyType": "managed"
}
}
]
}
},
"trustedEntities": [
"lambda.amazonaws.com"
]
}
Lambda function resource policy:
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:ap-northeast-1:my_account_id:function:my-file-upload",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "my_account_id"
},
"ArnLike": {
"AWS:SourceArn": "arn:aws:s3:::file-import"
}
}
}
]
}
My question is: what am I doing wrong here and how do I fix it?
The thing you need to create is called a "Resource-based policy", and is what should be created by aws lambda add-permission.
A Resource-based policy gives S3 permission to invoke your lambda. This is a property on your lambda itself, and is not part of your lambda's IAM role (Your lambda's IAM role controls what your lambda can do, a Resource-based policy controls who can do what to your lambda. You can view this resource in the UI on the aws console by going to your lambda, clicking "Permissions" and scrolling down to "Resource-based policy". The keyword you want to look out for is lambda:InvokeFunction, which is what gives other things permission to call your lambda, including other AWS accounts, and other AWS services on your account (like s3).
That being said, the command you ran should have created this policy. Did you make sure to replace my_account_id with your actual account id when you ran the command?
In addition, make sure you replace --source-arn arn:aws:s3:::file-import with the actual ARN of your bucket (I assume you had to create a bucket with a different name because s3 buckets must have globally unique names, and file-import is almost surely already taken)
I figured out what the problem was. My initial command was:
aws s3api put-bucket-notification --bucket azure-erp-import \
--notification-configuration "CloudFunctionConfiguration={Id=file-uploaded,Events=[],Event=s3:ObjectCreated:*,CloudFunction=arn:aws:lambda:ap-northeast-1:my_account_id:function:my-file-upload,InvocationRole=arn:aws:iam::my_account_id:role/lambda-upload-stream}"
This failed because the arn:aws:iam::my_account_id:role/lambda-upload-stream role doesn't have permissions to call lambda:InvokeFunction on the lambda function. Removing this value fixed the error.
I have used the below policy for the SNS topic to subscribe this SNS in Lambda with account number as 222222222222. I have also given access to my lambda with a similar policy adding it to the execution role of Lambda.
Getting the error below:
An error occurred when creating the trigger: User:
arn:aws:sts::222222222222:assumed-role/TSI_Base_FullAccess/AXXXXXXXX
is not authorized to perform: SNS:Subscribe on resource:
arn:aws:sns:eu-west-1:111111111111:Story-5555 (Service: AmazonSNS;
Status Code: 403; Error Code: AuthorizationError; Request ID:
1321942c-25c4-52a1-bacb-c2e9bd641067)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1582008007178",
"Action": [
"sns:GetSubscriptionAttributes",
"sns:GetTopicAttributes",
"sns:ListSubscriptions",
"sns:ListSubscriptionsByTopic",
"sns:ListTagsForResource",
"sns:ListTopics",
"sns:Publish",
"sns:Subscribe"
],
"Effect": "Allow",
"Resource": "arn:aws:sns:eu-west-1:111111111111:Story-5555",
"Condition": {
"ArnEquals": {
"aws:PrincipalArn": "arn:aws:lambda:eu-west-1:222222222222:function:New_Cross_SNS"
}
}
}
]
}
According AWS Documentation you should specify principle additionally to the condition.
So your policy should resemble
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1582008007178",
"Action": [
"sns:GetSubscriptionAttributes",
"sns:GetTopicAttributes",
"sns:ListSubscriptions",
"sns:ListSubscriptionsByTopic",
"sns:ListTagsForResource",
"sns:ListTopics",
"sns:Publish",
"sns:Subscribe"
],
"Effect": "Allow",
"Resource": "arn:aws:sns:eu-west-1:111111111111:Story-5555",
"Principal": {
"AWS": ["222222222222"]
},
"Condition": {
"ArnEquals": {
"aws:PrincipalArn": [
"arn:aws:lambda:eu-west-1:222222222222:function:New_Cross_SNS",
"arn:aws:sts::222222222222:assumed-role:TSI_Base_FullAccess:AXXXXXXXX"
]
}
}
}
]
}
The way to be sure which ARN to specify in the condition section of the policy is to call (and print) get-caller-identity API from your function.
I’ve created a set of AWS Lambdas using the Serverless framework, and a React app which calls these. A user pool and an identity pool have been setup in AWS Cognito, and a table in DynamoDB. (I've followed the tutorial on serverless-stack.com). It's a simple notes app.
The client app is deployed to: https://dev.cakebook.co
The API is deployed: https://api.cakebook.co/dev/orders
However, after I log in using this Cognito user:
admin#example.com
Passw0rd!
I get a 403 response for the GET of the orders:
message: “User: arn:aws:sts::********8766:assumed-role/cakebook-api-dev-CognitoAuthRole-1DTRT5XGEGRXW/CognitoIdentityCredentials is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-2:********8766:sss6l7svxc/dev/GET/orders”
I'm new to all this, but it looks like my Cognito user does not have permission to call the Lambda (or API gateway?). Is that the issue? If so, how do I give the users permission to call the Lambdas?
UPDATE, requested JSON
Execution Role:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogStream"
],
"Resource": [
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-create:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-get:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-list:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-update:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-delete:*"
],
"Effect": "Allow"
},
{
"Action": [
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-create:*:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-get:*:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-list:*:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-update:*:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-delete:*:*"
],
"Effect": "Allow"
},
{
"Action": [
"dynamodb:DescribeTable",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem"
],
"Resource": [
"arn:aws:dynamodb:us-east-2:********8766:table/orders"
],
"Effect": "Allow"
},
{
"Sid": "1",
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-2:********8766:function:cakebook-api-dev-list",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:cognito-identity:us-east-2:********8766:identitypool/us-east-2:d9e4e505-c64a-4836-8e56-3af843dbe453"
}
}
}
]
}
Function Policy:
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "cakebook-api-dev-ListLambdaPermissionApiGateway-U7OCBI3JM44G",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-2:********8766:function:cakebook-api-dev-list",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:us-east-2:********8766:w5o4vxx4f0/*/*"
}
}
},
{
"Sid": "lambda-da48f6d0-6d3c-4bbf-a761-ca3510f79624",
"Effect": "Allow",
"Principal": {
"Service": "cognito-sync.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-2:********8766:function:cakebook-api-dev-list",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:cognito-identity:us-east-2:********8766:identitypool/us-east-2:d9e4e505-c64a-4836-8e56-3af843dbe453"
}
}
}
]
}
You need to update Lambda permission to allow invoking by Cognito user pool.
Option A - update permission in JSON format
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "lambda-something",
"Effect": "Allow",
"Principal": {
"Service": "cognito-sync.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:eu-west-1:__accountId__:__function_name__",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:cognito-identity:eu-west-1:__accountId__:identitypool/eu-west-1:....."
}
}
}
]
}
Option B - in console
Go to Lambda Configuration page
Add trigger Cognito Sync Trigger
During saving it will offer to configure Lambda permission automatically - agree
I have an SQS queue which used to have the following policy doc. for receiving S3 events from a bucket:
{
"Version": "2008-10-17",
"Id": "example-ID",
"Statement": [
{
"Sid": "example-statement-ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"sqs:SendMessage",
"sqs:ReceiveMessage"
],
"Resource": "arn:aws:sqs:us-east-1:<>:cypher-queue",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:*:*:cypher-secondarybucket"
}
}
}
]
}
Now, I have enabled Server-side encryption(SSE) for the queue. And, I have followed this doc for writing the policy statement for encryption. The policy statement now, looks like this:
{
"Version": "2008-10-17",
"Id": "example-ID",
"Statement": [
{
"Sid": "example-statement-ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"sqs:SendMessage",
"sqs:ReceiveMessage"
],
"Resource": "arn:aws:sqs:us-east-1:<>:cypher-queue",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:*:*:cypher-secondarybucket"
}
}
},
{
"Effect": "Allow",
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "arn:aws:sqs:us-east-1:<>:cypher-queue",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:*:*:cypher-secondarybucket"
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:<>:cypher-queue",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:*:*:cypher-secondarybucket"
}
}
}
]
}
But now, the queue is not getting any messages from the bucket on file additions. Is there something wrong which I did with the permissions?
This is now possible. From the AWS documentation:
https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#grant-destinations-permissions-to-s3 under the section AWS KMS Key Policy
If the SQS queue is SSE enabled, you can attach the following key
policy to the associated AWS Key Management Service (AWS KMS) customer
managed customer master key (CMK). The policy grants the Amazon S3
service principal permission for specific AWS KMS actions that are
necessary for to encrypt messages added to the queue.
{
"Version": "2012-10-17",
"Id": "example-ID",
"Statement": [
{
"Sid": "example-statement-ID",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "*"
}
]
}
I have missed the following announcement from the same article. A very silly mistake on my part. Will need to wait for sending S3 events to encrypted SQS.
The following features of AWS services aren't currently compatible
with encrypted queues:
Amazon CloudWatch Events
Amazon S3 Event Notifications
Amazon SNS Topic Subscriptions
Auto Scaling Lifecycle Hooks
AWS IoT Rule Actions
AWS Lambda Dead-Letter Queues