求SAM模板中引用同模板内客户托管策略的函数角色正确示例
在SAM模板中引用同一模板内客户托管策略的正确实现(含批量复用模式)
Lambda函数角色引用同模板内托管策略示例
直接通过!Ref引用同一模板中定义的AWS::IAM::ManagedPolicy资源,即可获取其ARN并关联到角色:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: # 声明客户托管策略 MyS3AccessPolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: s3:GetObject Resource: arn:aws:s3:::my-app-bucket/* # Lambda执行角色,关联上面的托管策略 MyLambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: { Service: lambda.amazonaws.com } Action: sts:AssumeRole ManagedPolicyArns: - !Ref MyS3AccessPolicy # 引用同模板内的托管策略 - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole # 附加AWS托管策略 # 使用该角色的Lambda函数 MyS3ReaderFunction: Type: AWS::Serverless::Function Properties: CodeUri: src/s3-reader/ Handler: index.handler Runtime: python3.11 Role: !Ref MyLambdaExecutionRole
状态机角色引用同模板内托管策略示例
状态机角色的核心是AssumeRolePolicyDocument要指定states.amazonaws.com作为信任主体,其余引用逻辑和Lambda一致:
# 接上面的模板,添加状态机相关资源 # 状态机专属托管策略(允许调用Lambda) MyStateMachinePolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: lambda:InvokeFunction Resource: !GetAtt MyS3ReaderFunction.Arn - Effect: Allow Action: states:StartExecution Resource: '*' # 状态机执行角色 MyStateMachineExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: { Service: states.amazonaws.com } Action: sts:AssumeRole ManagedPolicyArns: - !Ref MyStateMachinePolicy # 引用同模板内的状态机策略 # 状态机资源 MyDataProcessingStateMachine: Type: AWS::Serverless::StateMachine Properties: DefinitionUri: statemachine/data-processing.asl.json Role: !Ref MyStateMachineExecutionRole
批量部署的可复用模式
针对大量状态机、角色和策略的场景,推荐两种复用方案:
方案1:参数化+Globals通用配置
通过Parameters定义前缀、环境等变量,结合Globals统一配置资源基础属性,避免重复代码:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Parameters: EnvPrefix: Type: String Default: "Prod" Globals: Function: Runtime: python3.11 Timeout: 30 StateMachine: Type: STANDARD Resources: # 通用Lambda日志权限策略(所有Lambda角色复用) LambdaCommonLogPolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${EnvPrefix}-*" # 通用状态机日志权限策略(所有状态机角色复用) SFNCommonLogPolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogDelivery - logs:GetLogDelivery Resource: '*' # 订单业务Lambda角色:通用策略+专属策略 OrderLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: { Service: lambda.amazonaws.com } Action: sts:AssumeRole ManagedPolicyArns: - !Ref LambdaCommonLogPolicy - !Ref OrderLambdaCustomPolicy OrderLambdaCustomPolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - dynamodb:GetItem - dynamodb:PutItem Resource: !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${EnvPrefix}-Orders" # 订单业务状态机角色:通用策略+专属策略 OrderSFNRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: { Service: states.amazonaws.com } Action: sts:AssumeRole ManagedPolicyArns: - !Ref SFNCommonLogPolicy - !Ref OrderSFNCustomPolicy OrderSFNCustomPolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: lambda:InvokeFunction Resource: !GetAtt OrderLambdaFunction.Arn # 对应的Lambda和状态机 OrderLambdaFunction: Type: AWS::Serverless::Function Properties: CodeUri: src/order-handler/ Handler: index.handler Role: !Ref OrderLambdaRole OrderStateMachine: Type: AWS::Serverless::StateMachine Properties: DefinitionUri: statemachine/order-workflow.asl.json Role: !Ref OrderSFNRole
方案2:嵌套栈复用通用角色模板
将角色、策略的通用逻辑抽成嵌套栈,主栈通过参数传递专属配置,适合超大规模部署:
# 主模板 main.yaml AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Parameters: EnvPrefix: Type: String Default: "Prod" Resources: # 创建订单业务的Lambda角色和策略 OrderLambdaStack: Type: AWS::Serverless::Application Properties: Location: ./common-role-template.yaml Parameters: EnvPrefix: !Ref EnvPrefix ServiceType: "Lambda" CustomPolicy: !Sub | { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["dynamodb:GetItem", "dynamodb:PutItem"], "Resource": "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${EnvPrefix}-Orders" } ] } # 创建支付业务的状态机角色和策略 PaymentSFNStack: Type: AWS::Serverless::Application Properties: Location: ./common-sfn-role-template.yaml Parameters: EnvPrefix: !Ref EnvPrefix TargetLambdaArn: !GetAtt OrderLambdaStack.Outputs.RoleAssociatedLambdaArn
嵌套栈模板common-role-template.yaml:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Parameters: EnvPrefix: Type: String ServiceType: Type: String AllowedValues: ["Lambda", "States"] CustomPolicy: Type: String Resources: CommonLogPolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/${ServiceType}/${EnvPrefix}-*" CustomManagedPolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: !Sub '${CustomPolicy}' ServiceExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: { Service: !Sub "${ServiceType}.amazonaws.com" } Action: sts:AssumeRole ManagedPolicyArns: - !Ref CommonLogPolicy - !Ref CustomManagedPolicy Outputs: ServiceRoleArn: Value: !GetAtt ServiceExecutionRole.Arn
常见错误排查
- 信任主体错误:Lambda角色的信任主体必须是
lambda.amazonaws.com,状态机必须是states.amazonaws.com - 引用方式错误:必须用
!Ref获取同模板内托管策略的ARN,不能硬编码 - 资源冲突:批量部署时务必给资源加唯一前缀(如环境名),避免同名资源报错
- 权限范围:策略中的Resource尽量使用
!Sub或!GetAtt动态生成,避免硬编码账号/区域
内容的提问来源于stack exchange,提问作者Allan Miller
相关产品推荐
相关产品推荐

