aws-lambda - 通过 Terraform 创建 CloudFront 分配时出现 InvalidLambdaFunctionAssociation

标签 aws-lambda amazon-cloudfront 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

我如何定义这个角色会不会有问题?

最佳答案

Michaelcomments 中提到,您需要添加一个 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

关于aws-lambda - 通过 Terraform 创建 CloudFront 分配时出现 InvalidLambdaFunctionAssociation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44121551/

相关文章:

amazon-web-services - Amazon aws lex 聊天机器人支持视频吗?

amazon-web-services - Amazon EventBridge/Step Function/Lambda - 是否可以在不引入同步处理的情况下实现幂等性?

node.js - 如何从 Node Web 应用程序正确访问 AWS Api Gateway

terraform - 如何将多个模板文件传递给 terraform 中的 user_Data 变量

azure - 是否可以与应用程序网关分开配置后端地址池

Terraform - 无法访问原始类型值(字符串)上的属性

amazon-web-services - "Cold"启动 S3、DynamoDB、KMS 或其他任何东西

amazon-web-services - AWS SES + S3 : Send emails with attachment from S3

ssl - 如何将云端之间的 SSL 设置为具有 EC2 自定义来源的反向代理缓存?

amazon-ec2 - CloudFront 与一个 EC2 源之间的连接如何使用 HTTPS 进行?