I am able to deploy a lambda function via CloudFormation, but I wish to deploy it while including a Lambda layer for the requests library.
My CloudFormation template contains the following resources:
LambdaFunction (gets created successfully)
LambdaIAMRole (gets created successfully)
LambdaIAMPolicy (gets created successfully)
LambdaScheduledRule (gets created successfully)
LambdaResourcePolicy (for the LambdaScheduledRule, gets created successfully)
LambdaLayer (CREATE_FAILED)
Status Reason:
Your access has been denied by S3, please make sure your request credentials have permission to GetObject for [bucket] xxxx-nprd-xxxx-xxx-xxxxx-us-east-2/python.zip. S3 Error Code: AccessDenied. S3 Error Message: Access Denied (Service: AWSLambdaInternal; Status Code: 403; Error Code: AccessDeniedException; Request ID: e1d25641-e4cc-47d7-abb4-f0d1b9fb4240; Proxy: null)
Here is the code I used to create some of the above resources:
"LambdaFunction" : {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {"Ref" : "CodeSourceBucket" },
"S3Key": "lambdafunction.zip"
},
"Environment":{
"Variables" :{
"BUCKET": {"Ref": "xxxx-nprd-xxxx-xxx-xxxxx-us-east-2"},
"BUCKET_PREFIX": {"Ref": "xxx"},
"WEBSITE_URL": {"Ref": "xxx"}
}
},
"EphemeralStorage" : {
"Size" : 512
},
"Handler": "lambda_handler",
"Role": {"Fn::GetAtt" : [ "LambdaIAMRole", "Arn" ]},
"Runtime": "python3.9",
"FunctionName": { "Fn::Sub": "xxx"},
"Description": "xxx",
"Timeout": "90",
"MemorySize": 512
}
},
"LambdaIAMRole" : {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": { "Fn::Sub": "xxx-role"},
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/"
}
},
"IAMPolicy": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": { "Fn::Sub": "xxxxxx"},
"PolicyDocument" : {
"Statement": [
{
"Effect": "Allow",
"Action":
[
"s3:GetObject"
],
"Resource": [
{"xxxx-nprd-xxxx-xxx-xxxxx-us-east-2"},
{"xxxx-nprd-xxxx-xxx-xxxxx-us-east-2/*"}
]
},
{
"Effect": "Allow",
"Action":
[
"s3:get*",
"s3:put*"
],
"Resource": [
{"xxxx-nprd-xxxx-xxx-xxxxx-us-east-2"},
{"xxxx-nprd-xxxx-xxx-xxxxx-us-east-2/*"}
]
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"glue:StartJobRun",
"glue:GetJobRun"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "lambda:GetLayerVersion",
"Resource": "arn:aws:lambda:us-east-x:xxxxxxxxxxxx:request_layer-2-28:1"
}
]
},
"Roles" : [ {"Ref":"IAMRole"} ]
}
},
"LambdaLayer": {
"Type" : "AWS::Lambda::LayerVersion",
"Properties" : {
"CompatibleArchitectures" : [ "x86_64" ],
"CompatibleRuntimes" : [ "python3.7", "python3.8", "python3.9" ],
"Content" : {
"S3Bucket": "xxxx-nprd-xxxx-xxx-xxxxx-us-east-2",
"S3Key": "python.zip"
},
"Description" : "Requests library"
}
}
I was able to manually create my lambda layer for the requests library through the AWS console after creating my lambda function, but I don't know which permissions to include in the template to allow the lambda function to access the Lambda Layer of the python.zip in the S3 bucket (the python.zip contains the requests library).
My stack keeps failing to be created because the LambdaLayer resource is failing.
I don't see a "lambda layer" policy that I can attach to the role I am using for this lambda function. I also do not see a lambda layer resource policy.
I tried to add
{
"Effect": "Allow",
"Action": "lambda:GetLayerVersion",
"Resource": "arn:aws:lambda:us-east-x:xxxxxxxxxxxx:layer:request_layer-2-28:1"
}
to the IAM policy, but it didn't work. Am I supposed to add "Layers" property to the LambdaFunction resource?
I also tried to add {
"Effect": "Allow",
"Action":
[
"s3:GetObject"
],
to the policy but it did't work. Please help.