amazon-web-servicesaws-cloudformationamazon-iamaws-step-functionsaws-sam

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


I have a Step Function (Parent) created in a SAM/CloudFormation template that, among other things, calls another Step Function (Child). I'm following the instructions on calling Child, from Parent, using the service integration pattern. But I'm getting an IAM-related (I think) error I can't resolve when deploying via the CLI. (The error manifests in the CLI output, so it never actually makes it into AWS. There have been plenty of prior deployments, so the changeset is just trying to modify the Step Function with this deployment.)

'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})

To get the synchronous behavior I want (Parent calls Child, waits for execution of Child to complete, then moves onto the next State) I use the suggestion (from the service integration pattern link above) to create a task (in my SAM template) that looks like the following:

...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...

I've defined the IAM-role for Parent as follows, making sure that it only has Lambda execution privileges for the Lambda functions in Parent, and, more applicably to the problem, has permission to StartExecution of Child. I followed the instructions in the link just below, that stated StartExecution was the only permission needed when using the service integration pattern.

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

I've tried replacing the above State with a simple Pass State to make sure there were no other errors in the Step Function blocking the deployment, and it deployed fine. So I know it has to do with that State. (Also of note, when deploying with the Pass State for testing, I left the role as defined above, so, again, I know it's not a syntax error with the Policies that would be causing this. Obviously, that's not the same as perhaps having the wrong or missing policies.)


Solution

  • [Updated 5/22/2020 based on the post from @Matt and the comment from @Joe.CK to reduce the scope to the specific Resource required.]

    This Stack Overflow question pointed me in the right direction. botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the CreateStateMachine operation

    The issue appears to be stemming from CloudWatch and I was able to get past it by adding the following statement to my IAM policy.

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

    The AWS Step Functions sample project "Start a workflow within a workflow" includes something similar but restricted to a single Lambda function it invokes.