分仓部署Lambda时,未创建Lambda如何在IAM策略中指定其ARN?
跨仓库创建IAM策略与Lambda函数的ARN引用解决方案
问题背景
我正在维护两个代码仓库:一个负责创建Lambda函数所需的IAM角色和策略,另一个负责部署实际的Lambda函数。现在遇到了问题:由于Lambda函数要等第二个仓库部署才会存在,第一个仓库的IAM策略里无法直接通过Fn::GetAtt引用它的ARN。
当前策略中有问题的片段:
{ "Effect": "Allow", "Action": [ "lambda:InvokeFunction", "lambda:GetFunctionConfiguration" ], "Resource": [ {"Fn::GetAtt": ["LambdaFunction", "Arn"] } ] }
完整的LambdaPolicy配置:
"LambdaPolicy": { "Type": "AWS::IAM::Policy", "Properties": { "Roles": [ { "Ref": "LambdaRole" } ], "PolicyName": { "Fn::Join" : [ "", [ "LambdaPolicy", { "Ref": "CISuffix" } ]] }, "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": [ { "Fn::Join": ["", ["arn:aws:logs:", {"Ref" : "AWS::Region"}, ":", {"Ref": "AccountNumber"},":*" ]] } ] }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ { "Fn::Join": ["", ["arn:aws:logs:", {"Ref" : "AWS::Region"}, ":", {"Ref": "AccountNumber"},":log-group:/aws/lambda/*" ]] } ] }, { "Effect": "Allow", "Action": [ "lambda:InvokeFunction", "lambda:GetFunctionConfiguration" ], "Resource": [ {"Fn::GetAtt": ["LambdaFunction", "Arn"] } ] }, { "Action": [ "kms:Decrypt" ], "Resource": { "Fn::Join": ["", ["arn:aws:logs:", {"Ref" : "AWS::Region"}, ":", {"Ref": "AccountNumber"},":log-group:/aws/lambda/Lambda:*" ]] }, "Effect": "Allow" }, { "Action": [ "secretsmanager:GetResourcePolicy", "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:ListSecretVersionIds" ], "Resource": { "Fn::Join": [ "", ["arn:aws:secretsmanager:", {"Ref" : "AWS::Region"}, ":", {"Ref": "AccountNumber"}, ":secret:MySecretsABC" ]] }, "Effect": "Allow" } ] } } }
可行实现建议
1. 预先约定Lambda名称,拼接固定格式ARN
如果第二个仓库部署时会使用固定的Lambda函数名称,直接按照ARN的标准格式拼接即可,不需要依赖Fn::GetAtt:
{ "Effect": "Allow", "Action": [ "lambda:InvokeFunction", "lambda:GetFunctionConfiguration" ], "Resource": [ { "Fn::Join": ["", ["arn:aws:lambda:", {"Ref": "AWS::Region"}, ":", {"Ref": "AccountNumber"}, ":function:你的Lambda函数名称"]] } ] }
只要第二个仓库严格使用约定的名称,策略就能精准匹配到目标Lambda资源。
2. 使用通配符(仅限安全场景允许时)
如果你的Lambda函数有统一的命名前缀,且权限范围风险可控,可以用通配符缩小匹配范围:
{ "Effect": "Allow", "Action": [ "lambda:InvokeFunction", "lambda:GetFunctionConfiguration" ], "Resource": [ { "Fn::Join": ["", ["arn:aws:lambda:", {"Ref": "AWS::Region"}, ":", {"Ref": "AccountNumber"}, ":function:LambdaPrefix-*"]] } ] }
注意:这种方式会匹配所有符合前缀的Lambda函数,仅适合对权限粒度要求不高的场景。
3. 拆分策略,分阶段部署
把IAM策略拆成两部分:
- 基础权限部分:包含不依赖Lambda ARN的权限(比如日志、SecretsManager操作),由第一个仓库部署。
- Lambda权限部分:等第二个仓库创建完Lambda函数后,再通过该仓库的部署流程,新增一个
AWS::IAM::Policy资源,将Lambda调用权限附加到已存在的IAM角色上。
4. 用SSM参数存储ARN,跨仓库引用
在第二个仓库的部署模板中,创建Lambda后将其ARN写入AWS Systems Manager Parameter Store:
"LambdaArnParameter": { "Type": "AWS::SSM::Parameter", "Properties": { "Name": "/lambda/your-function/arn", "Type": "String", "Value": {"Fn::GetAtt": ["LambdaFunction", "Arn"]} } }
然后在第一个仓库的IAM策略里,通过引用这个SSM参数来获取ARN(如果用CloudFormation,可以结合自定义资源或者CDK等工具实现动态获取):
{ "Effect": "Allow", "Action": [ "lambda:InvokeFunction", "lambda:GetFunctionConfiguration" ], "Resource": [{"Ref": "LambdaArnFromSSM"}] }
这种方式需要严格控制部署顺序:先部署第二个仓库创建Lambda并写入SSM,再部署第一个仓库的IAM策略。
内容的提问来源于stack exchange,提问作者Frosty.Fluffy
相关产品推荐
相关产品推荐

