Skip to content

Conversation

Michae1CC
Copy link
Contributor

@Michae1CC Michae1CC commented Aug 28, 2025

Issue # (if applicable)

Closes #35307.

Reason for this change

AWS Step Functions provide users with the ability to synchronously run ECS tasks via the .sync integration pattern, see: https://docs.aws.amazon.com/step-functions/latest/dg/connect-ecs.html. These changes provide CDK users with the ability to provide the task definition ARN as a JSONata/JSONPath in aws_stepfunctions_tasks.EcsRunTask construct with the .sync integration pattern. This current isn't possible since the aws_stepfunctions_tasks.EcsRunTask construct currently requires the task definition to be provided at the time of deploy via aws_ecs.TaskDefinition. This enhancement will benefit users building dynamic ECS workflows in Step Functions.

Description of changes

Note: These changes allow for complete backwards compatibility and do not effect current usages of aws_stepfunction_tasks.EcsRunTaskOptions.

  • A new optional (allows backwards compatibility) parameter taskDefinitionInput with type step_function.TaskInput has been added to the aws_stepfunction_tasks.EcsRunTaskOptions interface. This will provide users with the ability to provide a ECS task definition using a JSONPath/JSONata expression. A validation error is raise if both or neither the taskDefinition and taskDefinitionInput are provided.
  • The _renderTask task has been modified to use the value property of taskDefinitionInput (if the taskDefinitionInput is used) when generating the TaskDefinition. Otherwise the current implementation of generating the TaskDefinition is used when the taskDefinition parameter is provided (to maintain backwards compatibility).
  • The taskDefinitionInput has been typed with step_function.TaskInput to remain consistent with how other aws_stepfunction_tasks constructs handle parameters that may be JSONPath/JSONata expression (example: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_stepfunctions_tasks.SnsPublish.html#message).
  • The parameter name taskDefinitionInput has been chosen over taskDefinitionArn since there is a linter rule which does not allow parameters to be prefixed with "Arn".
  • A validation error is raise if the user attempts to set both taskDefinitionInput and revisionNumber since it is impossible to format in a revisionNumber if a JSONPath/JSONata expression is provided for the taskDefinitionInput.
  • New optional (allows backwards compatibility) parameters networkMode, taskRole and taskExecutionRole are used to configure AWS_VPC networking configuration and IAM permissions respectively when taskDefinitionInput is used. A validation error is thrown if any of these parameters are set when providing a taskDefinition since these parameters should instead be set on the taskDefinition, helping reduce implementation logic/conflating.
  • The networkMode is added since the network mode is currently gleamed from the taskDefinition, this cannot be done with taskDefinitionInput.
  • Currently, the taskRole and taskExecutionRole values set on the taskDefinition are used to create IAM PassRole permissions. The optional taskRole and taskExecutionRole provided through the aws_stepfunction_tasks.EcsRunTaskOptions interface are used to reach parity with this particular feature of the aws_stepfunctions_tasks.EcsRunTask construct.
  • No validation errors are thrown when the taskRole and/or taskExecutionRole is not provided when using the taskDefinitionInput since, strictly speaking, an ECS task requires neither a task role nor a task execution role, see: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/security-ecs-iam-role-overview.html

Describe any new or updated permissions being added

  • If the taskRole and/or taskExecutionRole parameters are provided when using the taskDefinitionInput then the following statement is added to the step function role policy
{
	actions: ['iam:PassRole'],
	resources: ["<TaskRole and/or TaskExecutionRole if provided>"],
	conditions: {
	  StringEquals: {
		'iam:PassedToService': 'ecs-tasks.amazonaws.com',
	  },
	},
}
  • Despite the fact that the 'iam:PassedToService' condition is not present on the 'iam:PassRole' statement generated when using a taskDefinition, this is a huge gain in terms of security since it prevents the step function from potentially passing highly privileged permission to arbitrary principals. The only reason why I have not included the condition changes for the taskDefinition case is because these changes would be breaking and is probably best completed as its own change (if preferable to add the changes here let me know and I'll create a new ticket for it).
  • When using the taskDefinitionInput the following statement is added to the step function role policy
{
  actions: ['ecs:RunTask'],
  resources: ['*'],
  conditions: {
	ArnLike: {
	  'ecs:cluster': this.props.cluster.clusterArn,
	},
  },
}
  • The resource is starred here since the task definition cannot be determined ahead of time if a JSONPath/JSONata expression is provided.
  • Despite the fact that the 'ecs:cluster' condition is not present on the 'ecs:RunTask' statement generated when using a taskDefinition, I think this is also an improvement to security, preventing the step function from running tasks from any ECS cluster. Similarly, the only reason I have not included the condition changes for the taskDefinition case is because these changes would be breaking and is probably best completed as its own change.

Description of how you validated changes

  • I have added my unit tests to validate new features.
  • I have confirmed that the existing integration tests pass without changes.
  • I have added integ.fargate-run-task-taskdef-input the integration test. I have confirmed the step function deployed in this integration test executes and completes successfully.

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@aws-cdk-automation aws-cdk-automation requested a review from a team August 28, 2025 06:41
@github-actions github-actions bot added beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2 labels Aug 28, 2025
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This review is outdated)

@Michae1CC Michae1CC changed the title Allow EcsRunTask to receive dynamically generated task definitions feat(aws-stepfunction-tasks): allow ecsruntask to receive dynamically generated task definitions Aug 28, 2025
@Michae1CC Michae1CC changed the title feat(aws-stepfunction-tasks): allow ecsruntask to receive dynamically generated task definitions feat(stepfunction-tasks): allow ecsruntask to receive dynamically generated task definitions Aug 28, 2025
@aws-cdk-automation aws-cdk-automation dismissed their stale review August 28, 2025 07:13

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@Michae1CC Michae1CC force-pushed the add-dyn-task-def-ecs-runtask branch from 0551852 to 26d64cb Compare August 28, 2025 12:46
@aws-cdk-automation aws-cdk-automation added the pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. label Aug 31, 2025
@kumvprat kumvprat self-assigned this Sep 19, 2025
});
const stack = new cdk.Stack(app, 'aws-sfn-tasks-ecs-fargate-run-tasktask-def');
stack.node.setContext(EC2_RESTRICT_DEFAULT_SECURITY_GROUP, false);
stack.node.setContext(STEPFUNCTIONS_TASKS_FIX_RUN_ECS_TASK_POLICY, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flags below have a default/recommended value true, we should test the setup with the default/recommended value :

Also I think this not needed as the default value would be false for this :
@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy': false,

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is idea to allow the new EcsTask changes to work with the default/recommended values ? Or maybe the this feature overall only works in the case that these flags are turned off?

Tell me if I am missing something here(could be that is is a very specific use-case this is trying to solve)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially just copied these from the other tests within the stack, but yes, my specific tests don't really require me to change these values at all. I've removed these lines to revert these flags back to their default values.

Copy link
Contributor Author

@Michae1CC Michae1CC Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, when I remove the stack.node.setContext(EC2_RESTRICT_DEFAULT_SECURITY_GROUP, false) the build step will fail since the Node runtime for a custom resource lambda resource it creates differs depending on the machine runs the test, see: https://github.com/aws/aws-cdk/actions/runs/17996160888/job/51196012271 .

Performing a text search reveals that a number of other integrations tests do the same thing to, supposedly, circumvent this issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the mapping depends on the region : https://github.com/aws/aws-cdk/actions/runs/17996160888/job/51196012271#step:9:7691

We should use the default/recommended value and run the integration tests to check if the assertions work.
The other tests in the same folder seem to older than the feature flag. Though it's not in the scope of this PR if you want we can revert those tests to use the default values of those flags. (if not we can take that up as another PR as well)

If you need help with running the integration tests you can check this guide : https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md#running-integration-tests

@kumvprat
Copy link
Contributor

Thanks for raising the PR @Michae1CC , added a few inline comments

@Michae1CC
Copy link
Contributor Author

Thanks for raising the PR @Michae1CC , added a few inline comments

Thanks for the review, I've added in your suggestions.

@Michae1CC Michae1CC force-pushed the add-dyn-task-def-ecs-runtask branch from 78a57c3 to f1900d9 Compare September 25, 2025 05:16
@Michae1CC Michae1CC requested a review from kumvprat September 25, 2025 05:56
@kumvprat
Copy link
Contributor

I have questions on the PR description, around the 2 statements in descriptions below :

Despite the fact that the 'iam:PassedToService' condition is not present on the 'iam:PassRole' statement generated when using a taskDefinition, this is a huge gain in terms of security since it prevents the step function from potentially passing highly privileged permission to arbitrary principals.

Despite the fact that the 'ecs:cluster' condition is not present on the 'ecs:RunTask' statement generated when using a taskDefinition, I think this is also an improvement to security, preventing the step function from running tasks from any ECS cluster.

The "not" in both statements is confusing me a bit. The PR does add these specific conditions as Condition in the step-function role policy. Can you provide more details around the reasoning ?

Also can you include the proper document that captures this ECS and step-function integration. That would be helpful as reference for the changes being done. Is this the correct link ?

@Michae1CC
Copy link
Contributor Author

The "not" in both statements is confusing me a bit. The PR does add these specific conditions as Condition in the step-function role policy. Can you provide more details around the reasoning ?

I mean to say that the current implementation does not include IAM condition checks to the iam:PassRole and ecs:RunTask statements (generated for step function execution role to run the tasks when providing a taskDefinition to the construct). My changes do include these condition checks but only when a taskDefinitionInput is provided.

The condition check I've added to the iam:PassRole statements restricts the step function to only passing the role to the ECS service. Without this check, the step function may pass the ECS execution role and/or ECS task execution role to arbitrary principles.

The condition check I've added to the ecs:RunTask statements restricts the step function to only run tasks for the provided ECS cluster. Without this check, the step function may run ECS tasks from an arbitrary ECS cluster.

Also can you include the proper document that captures this ECS and step-function integration. That would be helpful as reference for the changes being done. Is this the correct link ?

Yes that is the correct link.

Copy link
Contributor

@kumvprat kumvprat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation

Can you also add the link in the PR description so that it's easy to understand the context ? (the documentation link that documents details about ECS and step-function integration)

@Michae1CC Michae1CC force-pushed the add-dyn-task-def-ecs-runtask branch from 70352b5 to 4093326 Compare September 27, 2025 05:16
@Michae1CC
Copy link
Contributor Author

Can you also add the link in the PR description so that it's easy to understand the context ? (the documentation link that documents details about ECS and step-function integration)

I've added the link

@ozelalisen ozelalisen added the pr/needs-further-review PR requires additional review from our team specialists due to the scope or complexity of changes. label Sep 29, 2025
@Michae1CC Michae1CC force-pushed the add-dyn-task-def-ecs-runtask branch from 82d4029 to 85ad85f Compare September 30, 2025 01:40
@Michae1CC Michae1CC force-pushed the add-dyn-task-def-ecs-runtask branch from 85ad85f to eb2fb99 Compare September 30, 2025 02:07
@Michae1CC Michae1CC requested a review from kumvprat September 30, 2025 03:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2 pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. pr/needs-further-review PR requires additional review from our team specialists due to the scope or complexity of changes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

aws-stepfunctions-tasks: Provide task definition as JSONata/JSONPath in .sync EcsRunTask
4 participants