Step Function 中的嵌套 Step Function:未知错误:“...未授权创建托管规则”
Posted
技术标签:
【中文标题】Step Function 中的嵌套 Step Function:未知错误:“...未授权创建托管规则”【英文标题】:Nested Step Function in a Step Function: Unknown Error: "...not authorized to create managed-rule" 【发布时间】:2020-06-22 01:39:18 【问题描述】:我在 SAM/CloudFormation 模板中创建了一个 Step Function(父级),除其他外,它调用另一个 Step Function(子级)。我正在按照使用service integration pattern 从父级调用子级的说明进行操作。但是我遇到了一个与 IAM 相关的(我认为)错误,我在通过 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)
为了获得我想要的同步行为(父调用子,等待子的执行完成,然后进入下一个状态)我使用建议(来自上面的服务集成模式链接)创建一个任务(在我的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 执行权限,并且更适用于该问题,具有 Child 的 StartExecution
的权限。我按照下面链接中的说明进行操作,说明 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
状态进行部署以进行测试时,我离开了上面定义的角色,所以,我再次知道,这不是导致这种情况的策略的语法错误。显然,这不一样可能有错误或缺少政策。)
【问题讨论】:
在权限修复后我仍然遇到这个问题,它也是间歇性的。尝试添加一堆DependsOn
,但没有帮助!
【参考方案1】:
[根据 @Matt 的帖子和 @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
AWS Step Functions 示例项目“在工作流中启动工作流”包含类似的内容,但仅限于它调用的单个 Lambda 函数。
【讨论】:
啊哈。这对我帮助很大!谢谢。它帮助我更仔细地阅读了上面的链接(这里:docs.aws.amazon.com/step-functions/latest/dg/…),我最初说只需要states:StartExecution
。但是,向下滚动您会发现它根据 同步 调用的需要概述了您在此处显示的内容(加上更多内容)。我猜当它是异步的时,它只是使用startExecution
“触发并忘记”,但要跟踪完成,您需要让 CloudWatch 将消息发送回 Step Functions。今晚我会尝试,一旦测试,我会将其标记为已解决。
请参阅下文,了解如何将此答案完全纳入正确的角色定义中。
您实际上并不需要所有资源 *。 (允许任何角色访问 * 资源通常是个坏主意)您要查找的是StepFunctionsGetEventsForStepFunctionsExecutionRule
。它用于 Step Function 中的嵌套工作流(即作为任务启动另一个状态机执行)
我遇到了类似的问题,但是在调用 ECS 时,为了弄清楚我最初在资源上允许“*”,然后在控制台中注意到它指的是 StepFunctionsGetEventsForECSTaskRule。事实上,我遇到了这两个问题,因为它是一个 Step Function 调用一个运行 ECS 任务的 Step Function【参考方案2】:
添加完整的角色定义,结合 Andrew 提供的内容和文档中的内容来解决问题。它分为四个部分:
-
允许子 Step Function 通过 states:StartExecution 运行
允许父级描述和停止任何 Step Functions。 (我认为这可能会根据资源进行更紧密的定制;但是,这是 AWS 文档的复制和粘贴。)
允许父级创建/修改(放置)规则到 Cloud Watch(特定系统生成/管理的资源)中,以便它可以保持到执行完成(因为同步执行)。
允许父级在 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
【讨论】:
我添加了托管策略 CloudWatchEventsFullAccess,一切正常。谢谢。【参考方案3】:我添加了“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"
【讨论】:
请注意,这不是好的做法。消除错误是一回事,正确地做到这一点是另一回事。为什么不给它,或者在这种情况下的所有资源,完全的管理员访问权限,再也不用担心权限了? ;-) 对所有资源的完全管理员访问权限?我不确定你指的是什么? 我指出您的解决方案使用“CloudWatchEventsFullAccess”托管策略提供了太多权限。我们不希望每次遇到权限问题时都使用“AdministratorAccess”策略,对吧?给它“CloudWatchEventsFullAccess”就是沿着这条路走的;过度分配权限以缓解问题。【参考方案4】:只需一秒钟。这稍有不同,它是一个内联策略,授权对 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/xxxxxxxx
由 SAM CloudFormation 转换为 AWS::Serverless::StateMachine
资源生成。这是公然的自动化。
【讨论】:
【参考方案5】:StepFunctionsGetEventsForStepFunctionsExecutionRule
绝对是解决方案的关键。就我的情况而言,这还不够。使用 Terraform 时,我还必须将 AWS 提供程序提高到 >= 2.69,因为这是提供程序获取 AccessDeniedExceptions 的重试逻辑的地方。此外,我遇到了 Terraform 为应用更改而构建的资源依赖图的问题。该图有 terraform 在创建策略之前尝试创建状态机,并且策略依赖于状态机。解决方案是将 uber 策略分解为状态机使用的角色的三个策略附件。一个政策有StepFunctionsGetEventsForStepFunctionsExecutionRule
,第二个政策围绕states
行动,第三个是原始的超级政策。有了这个,依赖图就创建了两个新策略,然后是状态机,然后是原始 uber 策略,一切都很好。
【讨论】:
以上是关于Step Function 中的嵌套 Step Function:未知错误:“...未授权创建托管规则”的主要内容,如果未能解决你的问题,请参考以下文章
Step Function 中的 AWS Batch 作业执行结果
如何在 PLIST 中访问嵌套的 NSDictionary?