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

使用SAM模板创建State Machine角色失败求助

SAM模板中State Machine执行角色创建失败的排查与修复

问题背景

我正在构建嵌套堆栈,当前先尝试让独立SAM模板运行。已填写所有必要参数,但State Machine执行角色创建一直失败。此前了解到额外策略可能冲突,试过注释相关策略,但无论注释与否模板执行都失败。

原模板代码

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Parameters:
  SourceBucketName:
    Type: String
    Description: 用于存储代码库的存储桶名称。
  GlueAssetsBucketName:
    Type: String
    Description: 用于存储Glue运行时日志、临时文件等的存储桶名称。
  SaphanaGlueConnection:
    Type: String
    Description: Glue与SAP HANA的连接名称。
  GlueJobRoleArn:
    Type: String
    Description: Glue任务所用IAM角色的ARN。
  # StateMachineExecutionRoleArn:
  #   Type: String
  #   Description: Step Function执行所用IAM角色的ARN。

Resources:
  StateMachineExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties: 
      RoleName: !Sub 'SMExecutionRole-${AWS::StackName}'
      AssumeRolePolicyDocument: 
        Version: '2012-10-17'
        Statement: 
          - Effect: 'Allow'
            Principal:
              Service: 'states.amazonaws.com'
            Action: 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AWSStepFunctionsFullAccess'
        # - 'arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole'
      # Policies:
      #   - PolicyName: !Sub '${AWS::StackName}-StepFunctionPolicy'
      #     PolicyDocument:
      #       Version: '2012-10-17'
      #       Statement:
      #         - Effect: 'Allow'
      #           Action:
      #             - 'glue:StartJobRun'
      #             - 'glue:GetJobRun'
      #             - 'glue:GetJobRuns'
      #             - 'glue:BatchStopJobRun'
      #           Resource: '*'

  DevHanaS3GoldTdpAllSalesOpenperiodsGlueJob:
    Type: 'AWS::Glue::Job'
    Properties:
      Name: !Sub 'dev-hana-s3-gold-tdp-all-sales-openperiods-${AWS::StackName}'
      Role: !Ref GlueJobRoleArn
      Command:
        Name: 'glueetl'
        ScriptLocation: !Sub 's3://${SourceBucketName}/TDP/jobs/tdp-all-sales/glue/dev-hana-s3-gold-tdp-all-sales-openperiods.py'
        PythonVersion: '3'
      DefaultArguments:
        "--enable-metrics": "true"
        "--enable-spark-ui": "true"
        "--spark-event-logs-path": !Sub "s3://${GlueAssetsBucketName}/sparkHistoryLogs-${AWS::StackName}/"
        "--enable-job-insights": "false"
        "--enable-observability-metrics": "true"
        "--enable-glue-datacatalog": "true"
        "--enable-continuous-cloudwatch-log": "true"
        "--job-bookmark-option": "job-bookmark-disable"
        "--job-language": "python"
        "--TempDir": !Sub "s3://${GlueAssetsBucketName}/temporary-${AWS::StackName}/"
      Connections:
        Connections:
          - !Ref SaphanaGlueConnection
      MaxRetries: 0
      Timeout: 2880
      WorkerType: 'G.1X'
      NumberOfWorkers: 10
      GlueVersion: '4.0'
      ExecutionClass: 'STANDARD'

  DevS3RedshiftGoldTdpAllSalesOpenperiodsGlueJob:
    Type: 'AWS::Glue::Job'
    Properties:
      Name: !Sub 'dev-s3-redshift-gold-tdp-all-sales-openperiods-${AWS::StackName}'
      Role: !Ref GlueJobRoleArn
      Command:
        Name: 'glueetl'
        ScriptLocation: !Sub 's3://${SourceBucketName}/TDP/jobs/tdp-all-sales/glue/dev-s3-redshift-gold-tdp-all-sales-openperiods.py'
        PythonVersion: '3'
      DefaultArguments:
        "--enable-metrics": "true"
        "--enable-spark-ui": "true"
        "--spark-event-logs-path": !Sub "s3://${GlueAssetsBucketName}/sparkHistoryLogs-${AWS::StackName}/"
        "--enable-job-insights": "false"
        "--enable-observability-metrics": "true"
        "--enable-glue-datacatalog": "true"
        "--enable-continuous-cloudwatch-log": "true"
        "--job-bookmark-option": "job-bookmark-disable"
        "--job-language": "python"
        "--TempDir": !Sub "s3://${GlueAssetsBucketName}/temporary-${AWS::StackName}/"
      Connections:
        Connections:
          - !Ref SaphanaGlueConnection
      MaxRetries: 0
      Timeout: 2880
      WorkerType: 'G.1X'
      NumberOfWorkers: 10
      GlueVersion: '4.0'
      ExecutionClass: 'STANDARD'

############### STEP FUNCTIONS ###############
  GoldTdpAllSalesDailyStepFunction:
    Type: AWS::Serverless::StateMachine
    Properties:
      Name: !Sub 'gold-tdp-all-sales-daily-${AWS::StackName}'
      DefinitionUri: 
        Bucket: !Ref SourceBucketName
        Key: 'TDP/jobs/tdp-all-sales/step_functions/gold-tdp-all-sales-daily.json'
      DefinitionSubstitutions:
        DevHanaS3GoldTdpAllSalesOpenperiodsJob: !Ref DevHanaS3GoldTdpAllSalesOpenperiodsGlueJob
        DevS3RedshiftGoldTdpAllSalesOpenperiodsJob: !Ref DevS3RedshiftGoldTdpAllSalesOpenperiodsGlueJob
      Events:
        ScheduledExecution:
          Type: Schedule
          Properties:
            Description: "Gold层TDP全销售每日Step Function的调度规则"
            Schedule: "cron(0 6 * * ? *)"
            Enabled: true
            Name: !Sub 'gold-tdp-all-sales-daily-${AWS::StackName}'
      Role: !GetAtt StateMachineExecutionRole.Arn
      Type: STANDARD
      Logging:
        Level: "OFF"
        IncludeExecutionData: false
      Tracing:
        Enabled: false
      Tags:
        StackName: !Ref AWS::StackName

Outputs:
  DevHanaS3GoldTdpAllSalesOpenperiodsJobName:
    Description: "开发环境下HANA到S3 Gold层TDP全销售未结期间Glue任务的名称"
    Value: !Ref DevHanaS3GoldTdpAllSalesOpenperiodsGlueJob

  DevS3RedshiftGoldTdpAllSalesOpenperiodsJobName:
    Description: "开发环境下S3到Redshift Gold层TDP全销售未结期间Glue任务的名称"
    Value: !Ref DevS3RedshiftGoldTdpAllSalesOpenperiodsGlueJob

  GoldTdpAllSalesDailyStepFunctionArn:
    Description: "Gold层TDP全销售每日Step Function的ARN"
    Value: !Ref GoldTdpAllSalesDailyStepFunction

排查方向与修复方案

1. 最可能的原因:角色命名冲突

原模板中显式指定了RoleName: !Sub 'SMExecutionRole-${AWS::StackName}',如果同一AWS账号同一区域内已经存在同名角色,就会导致创建失败。

修复:移除显式的RoleName配置,让AWS自动生成唯一的角色名称,避免冲突:

StateMachineExecutionRole:
  Type: 'AWS::IAM::Role'
  Properties: 
    # 去掉显式RoleName,由AWS自动生成唯一名称
    AssumeRolePolicyDocument: 
      Version: '2012-10-17'
      Statement: 
        - Effect: 'Allow'
          Principal:
            Service: 'states.amazonaws.com'
          Action: 'sts:AssumeRole'

2. 权限策略优化(避免过宽权限与潜在冲突)

原模板使用AWSStepFunctionsFullAccess托管策略,权限过于宽泛,而且可能包含一些与当前场景无关的操作,甚至可能因权限过大导致创建时的隐性问题。建议替换为最小必要权限:

修正后的角色完整配置:

StateMachineExecutionRole:
  Type: 'AWS::IAM::Role'
  Properties: 
    AssumeRolePolicyDocument: 
      Version: '2012-10-17'
      Statement: 
        - Effect: 'Allow'
          Principal:
            Service: 'states.amazonaws.com'
          Action: 'sts:AssumeRole'
    Policies:
      - PolicyName: !Sub '${AWS::StackName}-StepFunctionGlueAccess'
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            # 允许操作当前模板创建的两个Glue Job
            - Effect: 'Allow'
              Action:
                - 'glue:StartJobRun'
                - 'glue:GetJobRun'
                - 'glue:GetJobRuns'
                - 'glue:BatchStopJobRun'
              Resource: 
                - !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:job/${DevHanaS3GoldTdpAllSalesOpenperiodsGlueJob}'
                - !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:job/${DevS3RedshiftGoldTdpAllSalesOpenperiodsGlueJob}'
            # Step Functions基础运行所需的日志权限(即使当前关闭日志,后续开启无需修改)
            - Effect: 'Allow'
              Action:
                - 'logs:CreateLogDelivery'
                - 'logs:GetLogDelivery'
                - 'logs:UpdateLogDelivery'
                - 'logs:DeleteLogDelivery'
                - 'logs:ListLogDeliveries'
                - 'logs:PutResourcePolicy'
                - 'logs:DescribeResourcePolicies'
                - 'logs:DescribeLogGroups'
              Resource: '*'

3. 额外排查步骤

  • 查看CloudFormation堆栈事件,找到角色创建失败的具体错误信息(比如Role already exists或Permission denied),精准定位问题。
  • 检查AWS账号的IAM角色配额是否已满,若已满需要申请提升配额。
  • 确认部署模板的IAM用户/角色拥有iam:CreateRole、iam:PutRolePolicy、iam:AttachRolePolicy等必要权限。

内容的提问来源于stack exchange,提问作者RagePwn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 22:35:55