如何让AWS CloudFormation的Lambda函数包实现全区域可用?
问题根源
你遇到的报错确实是因为Lambda函数的代码包存储在eu-central-1区域的S3桶中,跨区域部署时,Lambda服务需要从该桶拉取代码,但当前的Lambda执行角色没有访问该跨区域S3桶的权限,且桶本身可能限制了跨区域访问。
简便解决方案(无需多区域建桶)
方案1:扩展Lambda执行角色的权限
修改模板中LambdaExecutionRole的Policies部分,添加对存储Lambda代码的S3桶的访问权限,让跨区域的Lambda服务能拉取代码包:
在LambdaExecutionRole的Policies数组中新增一条Statement:
{ "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::css-electronics-resources/lambda/mdf-to-parquet-lambda-function-v1.5.0.zip" }
修改后的LambdaExecutionRole资源片段:
"LambdaExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ], "Policies": [ { "PolicyName": { "Fn::Sub": "S3LimitedAccessPolicy-${UniqueID}" }, "PolicyDocument": { "Version": "2012-10-17", "Statement": [ // 原有输入输出桶权限语句... { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::css-electronics-resources/lambda/mdf-to-parquet-lambda-function-v1.5.0.zip" } ] } } ] } }
同时,确保css-electronics-resources桶的桶策略没有限制仅允许eu-central-1区域访问。如果桶策略有区域限制,需要删除或修改对应的条件(比如去掉aws:RequestedRegion的限制)。
方案2:内嵌Lambda代码到模板(适合小型代码包)
如果你的Lambda代码包大小不超过4MB,可以将zip文件编码为Base64字符串,直接内嵌到模板中,完全摆脱对外部S3桶的依赖:
将Lambda代码的zip文件转换为Base64(可通过base64 mdf-to-parquet-lambda-function-v1.5.0.zip > lambda-code-base64.txt命令生成),然后修改LambdaFunction的Code属性:
"Code": { "ZipFile": "这里替换为Base64编码后的字符串" }
这种方法无需任何外部存储,跨区域部署零依赖,但代码更新时需要重新生成Base64编码,且模板体积会增大。
其他可选方案(需少量额外维护)
如果希望优化跨区域部署的速度,可以使用S3跨区域复制(CRR)将代码包同步到常用区域的桶中,然后在模板中用AWS::Region动态匹配对应区域的桶名:
- 在目标区域创建名为
css-electronics-resources-<区域名>的S3桶(如css-electronics-resources-us-east-2) - 配置源桶(eu-central-1)的CRR规则,自动同步
lambda/mdf-to-parquet-lambda-function-v1.5.0.zip到所有目标桶 - 修改模板中
LambdaFunction的Code部分:
"Code": { "S3Bucket": { "Fn::Sub": "css-electronics-resources-${AWS::Region}" }, "S3Key": "lambda/mdf-to-parquet-lambda-function-v1.5.0.zip" }
内容的提问来源于stack exchange,提问作者mfcss

