AWS Step Functionsでログを有効化したときにAWS CloudFormationスタック作成が失敗する原因

AWS Step Functionsでログを有効化したときにAWS CloudFormationスタック作成が失敗する原因

エラーメッセージ:The state machine IAM Role is not authorized to access the Log Destination
Clock Icon2025.06.18

困っていること

AWS Step FunctionsのステートマシンでCloudWatch Logsを有効化し、AWS CloudFormationスタックで作成しようとすると、以下のエラーで失敗しました。
ステートマシンにはIAMインラインポリシーで必要な権限を付与しているにも関わらず、このエラーが発生します。

Resource handler returned message: "The state machine IAM Role is not authorized to access the Log Destination (Service: Sfn, Status Code: 400, Request ID: cddcdb65-5400-4746-8b4e-4899c6470676) (SDK Attempt Count: 11)" (RequestToken: 92d4f4db-14a7-cf2a-33b3-93c2e18d5b28, HandlerErrorCode: AccessDenied)
cm-hirai-screenshot 2025-06-17 11.33.31

失敗したテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Simple Step Functions with CloudWatch Logs enabled'

Parameters:
  StateMachineName:
    Type: String
    Default: simple-success-state-machine
    Description: Name for the Step Functions State Machine

Resources:
  # CloudWatch Logs ロググループ
  StepFunctionsLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub '/aws/vendedlogs/states/${StateMachineName}'
      RetentionInDays: 14

  # Step Functions ステートマシン
  SimpleStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties:
      StateMachineName: !Ref StateMachineName
      StateMachineType: STANDARD
      RoleArn: !GetAtt StepFunctionsRole.Arn
      Definition:
        Comment: A description of my state machine
        StartAt: 成功
        States:
          成功:
            Type: Succeed
        QueryLanguage: JSONata
      LoggingConfiguration:
        Level: ALL
        IncludeExecutionData: true
        Destinations:
          - CloudWatchLogsLogGroup:
              LogGroupArn: !GetAtt StepFunctionsLogGroup.Arn

  # Step Functions 実行用 IAM ロール
  StepFunctionsRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub '${StateMachineName}-execution-role'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: states.amazonaws.com
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                aws:SourceAccount: !Sub ${AWS::AccountId}
              ArnLike:
                aws:SourceArn: !Sub 'arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:*'

  # Step Functions 用 IAM ポリシー
  StepFunctionsPolicy:
    Type: AWS::IAM::RolePolicy
    Properties:
      PolicyName: StepFunctionsLoggingPolicy
      RoleName: !Ref StepFunctionsRole
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          # CloudWatch Logs 権限
          - Effect: Allow
            Action:
              - logs:CreateLogDelivery
              - logs:CreateLogStream
              - logs:GetLogDelivery
              - logs:UpdateLogDelivery
              - logs:DeleteLogDelivery
              - logs:ListLogDeliveries
              - logs:PutLogEvents
              - logs:PutResourcePolicy
              - logs:DescribeResourcePolicies
              - logs:DescribeLogGroups
            Resource: '*'

ログの権限は以下のドキュメントの通りに設定しています。

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/cw-logs.html#cloudwatch-iam-policy

原因

原因は、CloudFormationでリソースが並行作成される際に、ステートマシンの作成がIAMポリシーの適用完了前に実行されるためです。

最新のデプロイタイムラインでも確認できます。
cm-hirai-screenshot 2025-06-17 11.24.12

CloudFormationでは、明示的な依存関係が指定されていない場合、リソースが並行して作成されます。上記のテンプレートでは以下の順序で処理されていると考えられます。

  1. StepFunctionsRole(IAMロール)が作成完了
  2. SimpleStateMachine(ステートマシン)が作成開始 ← この時点でロールにまだ権限がない
  3. StepFunctionsPolicy(IAMポリシー)が作成完了

この場合、ステートマシンの作成時点ではログ出力用の権限がIAMロールに付与されていないため、「The state machine IAM Role is not authorized to access the Log Destination」というエラーが発生します。

解決方法

方法1: DependsOnを使用した依存関係の明示

ステートマシンの作成前にIAMポリシーが確実に作成されるよう、DependsOnで依存関係を明示します。

一部抜粋
# Step Functions ステートマシン
SimpleStateMachine:
  DependsOn: 
    - StepFunctionsPolicy  # ポリシー作成後にステートマシンを作成
  Type: AWS::StepFunctions::StateMachine
  Properties:
    # ... 他の設定は同じ
完全なテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Simple Step Functions with CloudWatch Logs enabled'

Parameters:
  StateMachineName:
    Type: String
    Default: simple-success-state-machine
    Description: Name for the Step Functions State Machine

Resources:
  # CloudWatch Logs ロググループ
  StepFunctionsLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub '/aws/vendedlogs/states/${StateMachineName}'
      RetentionInDays: 14

  # Step Functions ステートマシン
  SimpleStateMachine:
    DependsOn: 
      - StepFunctionsPolicy
    Type: AWS::StepFunctions::StateMachine
    Properties:
      StateMachineName: !Ref StateMachineName
      StateMachineType: STANDARD
      RoleArn: !GetAtt StepFunctionsRole.Arn
      Definition:
        Comment: A description of my state machine
        StartAt: 成功
        States:
          成功:
            Type: Succeed
        QueryLanguage: JSONata
      LoggingConfiguration:
        Level: ALL
        IncludeExecutionData: true
        Destinations:
          - CloudWatchLogsLogGroup:
              LogGroupArn: !GetAtt StepFunctionsLogGroup.Arn

  # Step Functions 実行用 IAM ロール
  StepFunctionsRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub '${StateMachineName}-execution-role'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: states.amazonaws.com
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                aws:SourceAccount: !Sub ${AWS::AccountId}
              ArnLike:
                aws:SourceArn: !Sub 'arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:*'

  # Step Functions 用 IAM ポリシー
  StepFunctionsPolicy:
    Type: AWS::IAM::RolePolicy
    Properties:
      PolicyName: StepFunctionsLoggingPolicy
      RoleName: !Ref StepFunctionsRole
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          # CloudWatch Logs 権限
          - Effect: Allow
            Action:
              - logs:CreateLogDelivery
              - logs:CreateLogStream
              - logs:GetLogDelivery
              - logs:UpdateLogDelivery
              - logs:DeleteLogDelivery
              - logs:ListLogDeliveries
              - logs:PutLogEvents
              - logs:PutResourcePolicy
              - logs:DescribeResourcePolicies
              - logs:DescribeLogGroups
            Resource: '*'

この方法により、以下の順序でリソースが作成され、スタックが正常に作成できました。

  1. StepFunctionsRole(IAMロール)が作成完了
  2. StepFunctionsPolicy(IAMポリシー)が作成完了
  3. SimpleStateMachine(ステートマシン)が作成完了
    cm-hirai-screenshot 2025-06-17 11.28.10

方法2: IAMロール内にポリシーを統合

IAMロールのPoliciesプロパティを使用して、ポリシーをロール定義内に統合します。

別リソースとして定義した場合の処理順序

  1. StepFunctionsRole → 作成完了(権限なし)
  2. SimpleStateMachine → 作成開始 → 権限チェック → エラー!
  3. StepFunctionsPolicy → 作成完了

ロール内に統合した場合の処理順序

  1. StepFunctionsRole → 作成完了(権限も同時に付与)
  2. SimpleStateMachine → 作成開始 → 権限チェック → 成功!
ロール内統合版テンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Simple Step Functions with CloudWatch Logs enabled'

Parameters:
  StateMachineName:
    Type: String
    Default: simple-success-state-machine
    Description: Name for the Step Functions State Machine

Resources:
  # CloudWatch Logs ロググループ
  StepFunctionsLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub '/aws/vendedlogs/states/${StateMachineName}'
      RetentionInDays: 14

  # Step Functions ステートマシン
  SimpleStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties:
      StateMachineName: !Ref StateMachineName
      StateMachineType: STANDARD
      RoleArn: !GetAtt StepFunctionsRole.Arn
      Definition:
        Comment: A description of my state machine
        StartAt: 成功
        States:
          成功:
            Type: Succeed
        QueryLanguage: JSONata
      LoggingConfiguration:
        Level: ALL
        IncludeExecutionData: true
        Destinations:
          - CloudWatchLogsLogGroup:
              LogGroupArn: !GetAtt StepFunctionsLogGroup.Arn

  # Step Functions 実行用 IAM ロール(ポリシー統合版)
  StepFunctionsRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub '${StateMachineName}-execution-role'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: states.amazonaws.com
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                aws:SourceAccount: !Sub ${AWS::AccountId}
              ArnLike:
                aws:SourceArn: !Sub 'arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:*'
      Policies:  # ロール定義内にポリシーを統合
        - PolicyName: StepFunctionsLoggingPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              # CloudWatch Logs 権限
              - Effect: Allow
                Action:
                  - logs:CreateLogDelivery
                  - logs:CreateLogStream
                  - logs:GetLogDelivery
                  - logs:UpdateLogDelivery
                  - logs:DeleteLogDelivery
                  - logs:ListLogDeliveries
                  - logs:PutLogEvents
                  - logs:PutResourcePolicy
                  - logs:DescribeResourcePolicies
                  - logs:DescribeLogGroups
                Resource: '*'

この方法により、IAMロールとその権限が同時に作成されるため、ステートマシン作成時には既に必要な権限が付与されています。結果として、スタックが正常に作成できました。

cm-hirai-screenshot 2025-06-17 11.32.35

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.