question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Step Functions - support calling nested dynamic State Machine

See original GitHub issue

Description

Note: Bug occurs with the experimental library @aws-cdk/aws-stepfunctions

When creating a state machine with a nested workflow task, whose StateMachineArn is a dynamic value set using a JSONPath query, the stepfunctions CDK library recognizes the nested workflow task ARN as dynamic and suffixes StateMachineArn with .$ correctly.

However, the library doesn’t realize that the ARN provided is a dynamic value when generating default policies for the state machine. As a result, it generates a policy statement for the state machine with the action “states:StartExecution” so that the state machine can execute nested workflows (which is a good thing), but sets the resource field to the dynamic value (which is a bad thing).

Reproduction Steps

Reproduction Repo: https://github.com/sabarnac/cdk-stepfunctions-bug-repo

Steps:

  1. Run npm run cdk synth/cdk synth
  2. Open ./cdk.out/CdkStepfunctionsBugRepoStack.template.json
  3. Search for SampleStateMachineRoleDefaultPolicy
  4. Check the first policy statement
{
  "Action": "states:StartExecution",
  "Effect": "Allow",
  "Resource": "$.dynamicArn"
}

Stack Code:

import * as sfn from "@aws-cdk/aws-stepfunctions";
import * as tasks from "@aws-cdk/aws-stepfunctions-tasks";
import * as cdk from "@aws-cdk/core";

export class CdkStepfunctionsBugRepoStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const stepFunctionsTask = new sfn.Task(this, "NestedWorkflowTask", {
      task: new tasks.StartExecution(
        sfn.StateMachine.fromStateMachineArn(this, "NestedWorkflowStateMachine", sfn.Data.stringAt("$.dynamicArn")),
        {
          input: {
            "input.$": "$.dynamicInput",
            "AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID.$": "$$.Execution.Id",
          },
          name: sfn.Data.stringAt("$.dynamicName"),
          integrationPattern: sfn.ServiceIntegrationPattern.SYNC,
        },
      ),
      resultPath: "$.workflowResult",
    })

    new sfn.StateMachine(this, "SampleStateMachine", {
      definition: stepFunctionsTask,
    });
  }
}

Error Log

None.

Environment

  • CLI Version : 1.22.0 (build 309ac1b)
  • Framework Version:
    • @aws-cdk/aws-stepfunctions-tasks: 1.22.0
    • @aws-cdk/aws-stepfunctions: 1.22.0
    • @aws-cdk/core: 1.22.0
  • OS : Mac OS Mojave [10.14.6 (18G2022)]
  • Language : TypeScript

Other

No other details


This is 🐛 Bug Report

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:12
  • Comments:10 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
sabarnaccommented, Jan 23, 2022

I used the following code to remove the default policy statements that the Step Function CDK generates for the state machine when providing a dynamic ARN.

private readonly policyActionsToFilter = [
    "states:StartExecution",
    "states:DescribeExecution",
    "states:StopExecution",
  ]

private UNSAFE__hackStateMachineDefaultPolicyDocument = (stateMachine: StateMachine) => {
    const stateMachineDefaultPolicyDocument = (stateMachine.role as any).defaultPolicy.document;
    stateMachineDefaultPolicyDocument.statements = stateMachineDefaultPolicyDocument.statements.filter(
      (statement: any) => this.policyActionsToFilter.every((action) => !statement.action.includes(action)),
    );
  };

After this, then you can add in your own policy statement for what other state machine ARNs the current one is allowed to call. Make sure to provide policy statements for all the actions that were removed.

0reactions
hutchy2570commented, Jul 19, 2022

Changes are needed to the workaround from @sabarnac to work with CDK 2.32.0 (action is now _action, and is of type OrderedSet so we need to access the internal array with _action.direct() to do the .includes() check).

private readonly policyActionsToFilter = [
    "states:StartExecution",
    "states:DescribeExecution",
    "states:StopExecution",
  ]

private UNSAFE__hackStateMachineDefaultPolicyDocument = (stateMachine: StateMachine) => {
    const stateMachineDefaultPolicyDocument = (stateMachine.role as any).defaultPolicy.document;
    stateMachineDefaultPolicyDocument.statements = stateMachineDefaultPolicyDocument.statements.filter(
      (statement: any) => this.policyActionsToFilter.every((action) => !statement._action.direct().includes(action)),
    );
  };
Read more comments on GitHub >

github_iconTop Results From Across the Web

New – Step Functions Support for Dynamic Parallelism
The Parallel state can be used to execute in parallel a fixed number of branches defined in the state machine. Now, Step Functions...
Read more >
Manage Amazon Step Functions Executions as an Integrated ...
For a state machine that calls StartExecution for a single nested workflow execution, use an IAM policy that limits permissions to that state...
Read more >
Batch Send Data to Child/Nested Step Function State Machine ...
The limit here is based on your whole AWS account per region. So you still also got that limit if you split.
Read more >
3 Pitfalls of AWS Step Functions and How You Can Avoid Them
Step Functions is an incredible workflow service from AWS. ... That means all data you load in your state machine and pass across ......
Read more >
Notes from Complete guide to AWS Step Functions - Cloudash
Fail - terminates the state machine and mark it as failure. Parallel state: parallel states can be nested; you can only transition to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found