Nested Step Function in a Step Function: Unknown Error: "...not authorized to create managed-rule"

Nested Step Function in a Step Function: Unknown Error: "...not authorized to create managed-rule"

我有一个在 SAM/CloudFormation 模板中创建的 Step Function (Parent),除其他外,它调用另一个 Step Function (Child)。我正在按照有关使用 service integration pattern 从 Parent 调用 Child 的说明进行操作。但是我收到 IAM-related(我认为)错误,我在通过 CLI 部署时无法解决。 (错误显示在 CLI 输出中,因此它实际上从未进入 AWS。之前有很多部署,因此 changeset 只是尝试使用此部署修改 Step Function。 )

'arn:aws:iam::{Account-Number}:role/{Parent-Step-Function-Role-Name}' is not authorized to create managed-rule. (Service: AWSStepFunctions; Status Code: 400; Error Code: AccessDeniedException; Request ID: {Long-Id-Number})

为了获得我想要的同步行为(Parent 调用 Child,等待 Child 的执行完成,然后进入下一个状态)我使用建议(来自上面的服务集成模式 link)创建一个如下所示的任务(在我的 SAM 模板中):

...More States...

"Call Child State": {
  "Type": "Task",
  "Next": "The Next State",
  "Resource": "arn:aws:states:::states:startExecution.sync",
  "Parameters": {  
    "Input": {
      "comment": "Hello World!"
    },
    "StateMachineArn": "${ChildStepFunction}",
    "Name": "ChildExecutionFromParent"
  }
},

...More States...

我已经为 Parent 定义了 IAM-role 如下,确保它只对 Parent 中的 Lambda 函数具有 Lambda 执行权限,并且更适用于问题,有权 StartExecution of Child。我按照下面 link 中的说明进行操作,其中说明 StartExecution 是使用服务集成模式时唯一需要的权限。

https://docs.aws.amazon.com/step-functions/latest/dg/stepfunctions-iam.html

ParentStepFunctionRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: 2012-10-17
      Statement:
        -
          Effect: Allow
          Principal:
            Service:
              - !Sub states.${AWS::Region}.amazonaws.com
          Action: sts:AssumeRole
    Policies:
      -
        PolicyName: ChildStepFunctionExecution
        PolicyDocument:
          Version: 2012-10-17
          Statement:
            -
              Effect: Allow
              Action: states:StartExecution
              Resource: !Ref ChildStepFunction
            -
              Effect: Allow
              Action: lambda:InvokeFunction
              Resource:
                  - !GetAtt Function1.Arn
                  ...
                  - !GetAtt FunctionX.Arn

我尝试用简单的 Pass 状态替换上面的状态,以确保 Step Function 中没有其他错误阻止部署,并且部署良好。所以我知道这与那个州有关。 (另请注意,在使用 Pass 状态进行测试时,我保留了上面定义的角色,因此,我再次知道,这不是导致此问题的策略的语法错误。显然,这不是可能与 错误 缺失 策略相同。)

[根据@Matt 的 post 和@Joe.CK 的评论于 2020 年 5 月 22 日更新,以将范围缩小到所需的特定资源。]

这个 Stack Overflow 问题为我指明了正确的方向。 botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the CreateStateMachine operation

问题似乎源于 CloudWatch,我可以通过将以下语句添加到我的 IAM 策略来解决这个问题。

- Effect: Allow
  Action:
  - events:PutTargets
  - events:PutRule
  - events:DescribeRule
  Resource: 
  - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/StepFunctionsGetEventsForStepFunctionsExecutionRule

A​​WS Step Functions 示例项目 "Start a workflow within a workflow" 包含类似但仅限于它调用的单个 Lambda 函数的内容。

添加解决问题的完整角色定义,结合 Andrew 提供的内容和文档中的内容。它分为四个部分:

  1. 允许子步骤函数通过 states:StartExecution
  2. 运行
  3. 允许家长描述和停止任何 Step Functions。 (我认为这可能可以根据资源进行更紧密的定制;但是,这是从 AWS 的文档中复制和粘贴的。)
  4. 允许父级 create/modify(将)规则放入 Cloud Watch(特定系统 generated/managed 资源),以便它可以保持直到执行完成(由于同步执行)。
  5. 允许父级 运行 Step Function 中所有适用的 Lambda 函数。 (这实际上不是我遇到的问题的一部分,但总体上与 Step Function 相关。这还可能包括其他集成——例如 SNS——如果你有的话。)
  ParentStepFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          -
            Effect: Allow
            Principal:
              Service:
                - !Sub states.${AWS::Region}.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        -
          PolicyName: ParentStepFunctionExecutionPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              -
                Effect: Allow
                Action: states:StartExecution
                Resource: !Ref ChildStepFunction
              -
                Effect: Allow
                Action:
                  - states:DescribeExecution
                  - states:StopExecution
                Resource: "*"
              -
                Effect: Allow
                Action:
                  - events:PutTargets
                  - events:PutRule
                  - events:DescribeRule
                Resource: !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/StepFunctionsGetEventsForStepFunctionsExecutionRule
              -
                Effect: Allow
                Action: lambda:InvokeFunction
                Resource:
                  - !GetAtt Function1.Arn
                  ...
                  - !GetAtt FunctionX.Arn

稍等。这略有不同,一个内联策略,授权对 StepFunctionsGetEventsForStepFunctionsExecutionRule 托管规则资源的 events:PutRule 操作。

  StateMachine:
    Type: AWS::Serverless::StateMachine
    Properties:
      DefinitionUri: statemachine/parentstatemachine.asl.json
      DefinitionSubstitutions:
        ChildWorkflowArn: !Ref ChildStateMachine
      Policies: 
        - Version: 2012-10-17
          Statement:
            - Effect: Allow
              Action:
                - events:PutTargets
                - events:PutRule
                - events:DescribeRule
              Resource: !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/StepFunctionsGetEventsForStepFunctionsExecutionRule
        - StepFunctionsExecutionPolicy:
            StateMachineName: !Ref ChildStateMachine

只是为了确保电线没有交叉,以下有点像 CloudFormation 在没有内联策略声明的情况下报告的错误,但不完全是。

'arn:aws:iam::xxxxxxxx:role/xxxxxxxx' is not authorized to create managed-rule.
(
 Service: AWSStepFunctions; 
 Status Code: 400; 
 Error Code: AccessDeniedException; 
 Request ID: xxxxxxx;
 Proxy: null
)

role/xxxxxxxxAWS::Serverless::StateMachine 资源的 SAM CloudFormation 转换生成。这是公然的自动化。

我添加了“CloudWatcheventsFullAccess”托管策略,该错误消失了。谢谢楼上的回答。我想在这里添加我的代码示例,因为它不适合放在评论中。

  NetworkFactory:
    Type: AWS::Serverless::StateMachine
    Properties:
      DefinitionUri: statemachine/network-factory.asl.json
      DefinitionSubstitutions:
        CreateHubStateMachineArn: !Ref CreateHubStateMachine
        CreateVpcStateMachineArn: !Ref CreateVpcStateMachine
      Policies:
        - StepFunctionsExecutionPolicy:
            StateMachineName: !GetAtt CreateHubStateMachine.Name
        - StepFunctionsExecutionPolicy:
            StateMachineName: !GetAtt CreateVpcStateMachine.Name
        - "CloudWatchEventsFullAccess"

StepFunctionsGetEventsForStepFunctionsExecutionRule 绝对是解决问题的关键。对于我的情况,这还不够。使用 Terraform 时,我还必须将 AWS 提供程序设置为 >= 2.69,因为这是提供程序为 AccessDeniedExceptions 选择重试逻辑的地方。此外,我 运行 遇到了 Terraform 为应用更改而构建的资源依赖关系图的问题。在创建策略之前,该图具有尝试创建状态机的地形,并且该策略依赖于状态机。解决方案是将优步策略分解为三个策略附件,以附加到状态机所使用的角色。一项政策包含 StepFunctionsGetEventsForStepFunctionsExecutionRule,第二项政策包含 states 操作,第三项政策是最初的优步政策。有了它,依赖关系图就创建了两个新策略,然后是状态机,然后是原始的优步策略,一切都很好。

要让 StepFunction 正确侦听它向其提交任务/作业的其他一些服务,它需要能够创建 CloudWatch 事件规则。这些规则遵循命名模式:

arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/StepFunctions*

允许 events:PutTargetsevents:PutRuleevents:DescribeRule 将使 SF 能够创建和管理所需的规则。

参见例如https://docs.aws.amazon.com/step-functions/latest/dg/batch-job-notification.html - 对于批处理作业,规则的名称为 StepFunctionsGetEventsForBatchJobsRule