Reputation: 659
I am using the Go CDK to define the following infrastrucutre:
bucket := awss3.NewBucket(stack, aws.String("REDACTED"), &awss3.BucketProps{
AccessControl: awss3.BucketAccessControl_PRIVATE,
PublicReadAccess: aws.Bool(false),
RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
Versioned: aws.Bool(true),
})
getFileStatsLambda := awslambda.NewFunction(stack, aws.String("GetFileStatsLambda"), &awslambda.FunctionProps{
Runtime: awslambda.Runtime_GO_1_X(),
Code: awslambda.Code_FromAsset(lambdaPath("get_file_stats"), &awss3assets.AssetOptions{}),
Handler: aws.String("main"),
})
getFileStatsLambda.AddToRolePolicy(
awsiam.NewPolicyStatement(&awsiam.PolicyStatementProps{
Actions: &[]*string{aws.String("s3:ListBucket")},
Resources: &[]*string{bucket.BucketArn()},
}),
)
getFileStatsLambda.AddToRolePolicy(
awsiam.NewPolicyStatement(&awsiam.PolicyStatementProps{
Actions: &[]*string{
aws.String("s3:ListBucket"),
aws.String("s3:GetObject"),
aws.String("s3:PutObject"),
aws.String("s3:GetObjectAttributes"),
},
Resources: &[]*string{aws.String(*bucket.BucketArn() + "/*")},
}),
)
The handler of the "GetFileStatsLambda" is defined as follows:
key := args.Body
// Instantiate S3 client.
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
panic(fmt.Errorf("failed to load aws config: %w", err))
}
s3Client := s3.NewFromConfig(cfg)
// Get object stats.
headObjectOutput, err := s3Client.HeadObject(ctx, &s3.HeadObjectInput{
Bucket: aws.String("REDACTED_BUCKET_NAME"),
Key: aws.String(key),
})
if err != nil {
panic(fmt.Errorf("failed to get object stats for key %s: %w", key, err))
}
return "empty", nil
When I invoke the lambda with the below curl command, I get a "Internal Server Error"
curl -X POST \
'https://REDACTED.lambda-url.us-east-1.on.aws/' \
-H 'Content-Type: application/json' \
-d 'path/to/file'
From looking in CloudWatch, I can see that the error is:
operation error S3: HeadObject, https response error StatusCode: 403
This error happens regardless of whether the S3 key with which the lambda is invoked exists or not.
Googling this error, yields sources that attribute the error to not having one of the following permissions:
but I do already grant these in the policy used by the IAM role used by the lambda. At the moment of writing this, my policy looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject",
"s3:GetObjectAttributes",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::REDACTED_BUCKET_NAME",
"Effect": "Allow"
},
{
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject",
"s3:GetObjectAttributes",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::REDACTED_BUCKET_NAME/*",
"Effect": "Allow"
}
]
}
Note that the above policy is different from the policy defined in the CDK because I have manually edit it to be less restrictive since I last ran a CDK deploy.
Does anyone have any idea why my lambda is getting a 403 error?
Upvotes: 1
Views: 1206
Reputation: 659
The issue was that I had hardcoded the bucket name on which the lambda operates. I solved it by changing by CDK program to inject the correct bucket name into the lambda before building it. I solved it by putting my bucket name into an environment variable and having my lambda read it from there.
Upvotes: 1