Terraform配置SES触发Lambda遇权限错误,固定source_arn才可正常运行
问题根源分析
1. 循环依赖的本质
核心矛盾是SES接收规则与Lambda权限之间的循环依赖:
- AWS要求创建SES接收规则时,目标Lambda必须已配置允许SES调用的权限,否则会报错无法调用Lambda
- 遵循安全规范的话,Lambda权限的
source_arn需要限制为该SES接收规则的ARN,而这个ARN只有规则创建完成后才能获取 - 这直接形成死循环:规则创建依赖权限存在,权限创建依赖规则的ARN
2. 固定ARN能部署的原因
使用固定ARN时,Lambda权限无需等待SES规则创建,可提前部署。当SES规则创建时,对应的权限已经存在,AWS能通过权限验证,因此部署成功。但这种方式缺乏灵活性,规则名称或规则集变更后权限会失效。
3. 无source_arn权限的风险
移除source_arn意味着允许任意主体调用该Lambda,完全违反最小权限原则,因此会触发tfsec高危告警,生产环境严禁使用。
解决方案
打破循环依赖的关键是不依赖SES规则的ARN属性生成Lambda权限的source_arn,而是通过规则集ARN+规则名称提前构造正确的ARN:
resource "aws_lambda_permission" "ses_invoke_lambda" { statement_id = "AllowSESToInvokeLambda" action = "lambda:InvokeFunction" function_name = aws_lambda_function.ec2_start_stop.arn principal = "ses.amazonaws.com" # 用规则集ARN+规则名称构造source_arn,无需等待规则创建 source_arn = "${aws_ses_receipt_rule_set.main.arn}:rule/${aws_ses_receipt_rule.ec2_control.name}" } resource "aws_ses_receipt_rule" "ec2_control" { name = "ec2-start-stop-rule" rule_set_name = aws_ses_receipt_rule_set.main.name enabled = true action { lambda_action { function_arn = aws_lambda_function.ec2_start_stop.arn } } # 确保Lambda权限先创建完成,再部署规则 depends_on = [aws_lambda_permission.ses_invoke_lambda] }
逻辑说明:
- SES接收规则的ARN格式固定为
[规则集ARN]:rule/[规则名称],可提前拼接生成 - Lambda权限无需等待规则生成,可独立创建
- 通过
depends_on确保规则在权限创建完成后部署,满足AWS的权限验证要求
内容的提问来源于stack exchange,提问作者Dan M
相关产品推荐
相关产品推荐

