通过 Terraform 创建 CloudFront 分配时无效的 LambdaFunctionAssociation
InvalidLambdaFunctionAssociation when creating CloudFront distribution via Terraform
我想创建一个可以调用 lambda
(@edge) 的 CloudFront 分配。我能够使用 AWS 控制台做到这一点。我现在正尝试使用 Terraform 实现相同的目标。我的配置如下。
首先,我为 lambda 创建了一个角色。
resource "aws_iam_role" "my_edge_lambda_iam_role" {
name = "my_edge_lambda_iam_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
接下来,我创建了一个 lambda。
resource "aws_lambda_function" "redirect_lambda" {
filename = "myscript.js.zip"
function_name = "my_js_script"
role = "arn:aws:iam::123456789:role/my_edge_lambda_iam_role"
handler = "index.handler"
runtime = "nodejs4.3-edge"
}
最后,我(尝试)使用上述 lambda 函数的 ARN 创建了 CloudFront 分配。定义如下
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = "my-bucket.s3.amazonaws.com"
origin_id = "<my S3 path>"
}
enabled = true
is_ipv6_enabled = true
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "<my target origin>"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
lambda_function_association {
event_type = "viewer-request"
lambda_arn = "<arn of the lambda function denerated above>"
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 86400
max_ttl = 31536000
}
price_class = "PriceClass_All"
viewer_certificate {
cloudfront_default_certificate = true
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
}
尝试创建分发时,出现以下异常。
Error applying plan:
1 error(s) occurred:
* aws_cloudfront_distribution.s3_distribution: 1 error(s) occurred:
* aws_cloudfront_distribution.s3_distribution: InvalidLambdaFunctionAssociation: Failed to retrieve the function from Lambda. ErrorCode: AccessDeniedException Function: arn:aws:lambda:us-east-2:12345678:function:my_js_script
status code: 400, request id: 65579sd33-3f2d5-181e7-9140-79c1ff79fbdd
会不会是我定义角色的方式有问题?
作为 Michael mentioned in the , you need to add an aws_lambda_permission
资源以允许 AWS 服务调用 Lambda 函数。
resource "aws_lambda_permission" "allow_cloudfront" {
statement_id = "AllowExecutionFromCloudFront"
action = "lambda:GetFunction"
function_name = "${aws_lambda_function.redirect_lambda.function_name}"
principal = "edgelambda.amazonaws.com"
}
AWS docs 有更多关于如何在 Terraform 之外允许此操作的信息,在这种情况下使用 CLI:
aws lambda add-permission \
--function-name arn \
--statement-id statement-id \
--action lambda:GetFunction \
--principal edgelambda.amazonaws.com
我想创建一个可以调用 lambda
(@edge) 的 CloudFront 分配。我能够使用 AWS 控制台做到这一点。我现在正尝试使用 Terraform 实现相同的目标。我的配置如下。
首先,我为 lambda 创建了一个角色。
resource "aws_iam_role" "my_edge_lambda_iam_role" {
name = "my_edge_lambda_iam_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
接下来,我创建了一个 lambda。
resource "aws_lambda_function" "redirect_lambda" {
filename = "myscript.js.zip"
function_name = "my_js_script"
role = "arn:aws:iam::123456789:role/my_edge_lambda_iam_role"
handler = "index.handler"
runtime = "nodejs4.3-edge"
}
最后,我(尝试)使用上述 lambda 函数的 ARN 创建了 CloudFront 分配。定义如下
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = "my-bucket.s3.amazonaws.com"
origin_id = "<my S3 path>"
}
enabled = true
is_ipv6_enabled = true
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "<my target origin>"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
lambda_function_association {
event_type = "viewer-request"
lambda_arn = "<arn of the lambda function denerated above>"
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 86400
max_ttl = 31536000
}
price_class = "PriceClass_All"
viewer_certificate {
cloudfront_default_certificate = true
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
}
尝试创建分发时,出现以下异常。
Error applying plan:
1 error(s) occurred:
* aws_cloudfront_distribution.s3_distribution: 1 error(s) occurred:
* aws_cloudfront_distribution.s3_distribution: InvalidLambdaFunctionAssociation: Failed to retrieve the function from Lambda. ErrorCode: AccessDeniedException Function: arn:aws:lambda:us-east-2:12345678:function:my_js_script
status code: 400, request id: 65579sd33-3f2d5-181e7-9140-79c1ff79fbdd
会不会是我定义角色的方式有问题?
作为 Michael mentioned in the aws_lambda_permission
资源以允许 AWS 服务调用 Lambda 函数。
resource "aws_lambda_permission" "allow_cloudfront" {
statement_id = "AllowExecutionFromCloudFront"
action = "lambda:GetFunction"
function_name = "${aws_lambda_function.redirect_lambda.function_name}"
principal = "edgelambda.amazonaws.com"
}
AWS docs 有更多关于如何在 Terraform 之外允许此操作的信息,在这种情况下使用 CLI:
aws lambda add-permission \
--function-name arn \
--statement-id statement-id \
--action lambda:GetFunction \
--principal edgelambda.amazonaws.com