peterll
peterll

Reputation: 11

Can't configure lambda and SNS with an existing S3 bucket

I have an existing S3 bucket (which has some lambda event and SNS configuration already created by my previous co-worker). I want to add a new lambda event that will trigger by PutObject in another prefix.

I have been doing this for other existing S3 bucket with no issues. However, right now with this S3 bucket, no matter i try to create a lambda (according to the some AWS document I was reading, doing this on lambda console will automatically attach the policy for the S3 to invoke the function. But I also just try to manually add the permission for the S3 to invoke lambda) or an SNS (I edited the SNS policy to allow S3 bucket to SendMessage and ReceiveMessage), I was get this error:

An error occurred when creating the trigger: Unable to validate the following destination configurations (Service: Amazon S3; Status Code: 400; Error Code: InvalidArgument; Request ID: KKBWYJGTVK8X8AYZ; S3 Extended Request ID: ZF3NOIqw8VcRYX6bohbYp7d0a+opDuXOcFRrn1KBn3vBVBIPuAQ/s7V+3vptIue1uWu6muIWBhY=; Proxy: null)

I already followed all the AWS links i can find and i even try to follow all settings of the existing lambda event trigger on the S3 (except the prefix). However, I still don't have any solutions. The only difference i can think about maybe there's a CloudFormation behind to chain all the existing applications. However, i don't think the s3 Bucket is involving.

Can you please give me any advice? Much appreciated!

Update: Also I just tested doing the same thing on another bucket - with same IAM role, and it works. So I think the issue is related to the bucket.

Upvotes: 1

Views: 908

Answers (2)

Shilp Thapak
Shilp Thapak

Reputation: 450

The issue is with the SNS's Access Policy. Adding this policy will fix this:

{
 "Version": "2012-10-17",
 "Id": "example-ID",
 "Statement": [
  {
   "Sid": "example-statement-ID",
   "Effect": "Allow",
   "Principal": {
     "Service": "s3.amazonaws.com"  
   },
   "Action": [
    "SNS:Publish"
   ],
   "Resource": "arn:aws:sns:Region:account-id:topic-name",
   "Condition": {
      "ArnLike": { "aws:SourceArn": "arn:aws:s3:::awsexamplebucket1" },
      "StringEquals": { "aws:SourceAccount": "bucket-owner-account-id" }
   }
  }
 ]
}

To use this policy, you must update the Amazon SNS topic ARN, bucket name, and bucket owner's AWS account ID.

Source: https://docs.aws.amazon.com/AmazonS3/latest/userguide/grant-destinations-permissions-to-s3.html

Upvotes: 0

Bruno Schaatsbergen
Bruno Schaatsbergen

Reputation: 406

Could you share your policy with us or any Infra-as-Code that was used previously to get where you're now, it will be very hard for anyone to figure out what the cause of this could be. I would also certainly advice to setup resources in AWS Through AWS CloudFormation, perhaps this is a good starts guide: https://www.youtube.com/watch?v=t97jZch4lMY

Please compare the below IAM Policy that defines the permissions for the Lambda function.

The required permissions include:

  • Get the object from the source S3 bucket.
  • Put the resized object into the target S3 bucket.
  • Permissions related to the CloudWatch Logs.
    {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:PutLogEvents",
                "logs:CreateLogGroup",
                "logs:CreateLogStream"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::mybucket/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::mybucket-resized/*"
        }
    ]

You will also need to configure an execution role for your Lambda.

Create the execution role that gives your function permission to access AWS resources.

To create an execution role

  • Open the roles page in the IAM console.
  • Choose Create role.
  • Create a role with the following properties.
  • Trusted entity – AWS Lambda.
  • Permissions – AWSLambdaS3Policy.
  • Role name – lambda-s3-role.

The above created policy has the permissions that the function needs to manage objects in Amazon S3 and write logs to CloudWatch Logs.

Upvotes: 1

Related Questions