You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 14:41:00