如何通过Terraform将镜像类型Lambda关联到CloudFront分发?
问题描述
我正在将AWS中手动创建的资源迁移到Terraform。目前已编写Terraform脚本,用于创建所需的Lambda、IAM角色及Lambda写入CloudWatch日志的权限,脚本如下:
resource "aws_iam_role" "lambda_role" { name = "${var.brand}-oauth-lambda-role" inline_policy { name = "Allow-CloudWatch-Logs" policy = jsonencode({ Version = "2012-10-17", Statement = [ { Effect = "Allow", Action = [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], Resource = [ "arn:aws:logs:*:*:*" ] } ] }) } assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ { Effect = "Allow", Action = "sts:AssumeRole" Principal = { "Service": [ "lambda.amazonaws.com", "edgelambda.amazonaws.com" ] }, } ] }) } resource "aws_lambda_function" "lambda" { function_name = "${var.brand}-oauth-lambda" role = aws_iam_role.lambda_role.arn architectures = [ "x86_64" ] package_type = "Image" image_uri = "xxx.dkr.ecr.us-east-1.amazonaws.com/yyy@sha256:zzz" runtime = "nodejs18.x" }
该脚本已成功创建所有资源,但此Lambda需作为CloudFront Lambda@Edge执行。在AWS控制台中可通过Add trigger按钮将其关联至CloudFront分发,但我不清楚如何通过Terraform实现此操作,请问是否支持该操作或需采用其他方式?
解决方案
Terraform完全支持将Lambda@Edge关联到CloudFront分发,不需要单独的"trigger"资源,直接在aws_cloudfront_distribution资源中通过lambda_function_association块配置即可。
关键注意事项
- Lambda@Edge要求Lambda函数必须部署在**us-east-1(弗吉尼亚北部)**区域,即使你的CloudFront分发面向其他区域。
- IAM角色需要补充CloudFront调用Lambda的权限,同时确保角色信任策略包含
edgelambda.amazonaws.com(你的原始脚本已配置这一点)。
修改后的完整示例
- 更新IAM角色权限(添加CloudFront调用Lambda的权限):
resource "aws_iam_role" "lambda_role" { name = "${var.brand}-oauth-lambda-role" inline_policy { name = "Allow-CloudWatch-Logs" policy = jsonencode({ Version = "2012-10-17", Statement = [ { Effect = "Allow", Action = [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], Resource = [ "arn:aws:logs:*:*:*" ] } ] }) } inline_policy { name = "Allow-CloudFront-Invoke" policy = jsonencode({ Version = "2012-10-17", Statement = [ { Effect = "Allow", Action = "lambda:InvokeFunction", Resource = aws_lambda_function.lambda.arn, Principal = { Service = "cloudfront.amazonaws.com" } } ] }) } assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ { Effect = "Allow", Action = "sts:AssumeRole", Principal = { "Service": [ "lambda.amazonaws.com", "edgelambda.amazonaws.com" ] }, } ] }) }
- 配置CloudFront分发关联Lambda@Edge:
在你的CloudFront分发资源中,为目标缓存行为添加lambda_function_association块:
resource "aws_cloudfront_distribution" "cdn" { # 保留你已有的CloudFront配置(origin、default_cache_behavior基础设置等) default_cache_behavior { # 保留你已有的缓存行为配置(viewer_protocol_policy、allowed_methods等) # 关联Lambda@Edge,event_type可根据需求修改(如viewer-request、origin-response等) lambda_function_association { event_type = "viewer-request" lambda_arn = aws_lambda_function.lambda.qualified_arn # 必须使用带版本/别名的ARN } } # 如需关联到其他缓存行为,重复添加lambda_function_association块即可 }
重要提示
- Lambda@Edge关联必须使用Lambda的qualified ARN(即带版本号或别名的ARN),Terraform的
aws_lambda_function.lambda.qualified_arn会自动引用最新版本的ARN。 - 更新Lambda函数后,需发布新版本,Terraform会自动同步CloudFront关联的版本。
内容的提问来源于stack exchange,提问作者tftd
相关产品推荐
相关产品推荐

