aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.37k stars 3.78k forks source link

[stepfunctions]: Adjusting parameters in ContainerOverride of EcsRunTask #24057

Open MieladN opened 1 year ago

MieladN commented 1 year ago

Describe the bug

The EcsRunTask construct only accepts an array of strings as override commands. It cannot produce substitutable output like "Command.$": "$.commands" that's needed to read the override command from the execution input. This is a limitation of the CDK implementation, not of the ECS optimized integration itself. Using the 'CallAwsService' construct allows you to get around this, but the CallAwsService doesn't allow you to set the IntegrationPattern as RUN_JOB (.sync).

In simpler terms:

Using Amazon States language, you can set the ContainerOverride field for an EcsRunTask, for example, as

"Command.$": "States.Array($.Foo,$.Bar,$.FooBar)"

However, if you use CDK, this is not possible, because there is no method to adjust parameters in the ContainerOverride method.

CDK code will always generate:

"Command": "States.Array($.Foo,$.Bar,$.FooBar)"

missing the .$ after Command.

Expected Behavior

What I expect is for there to be a way to adjust previously set parameters for the ContainerOverride. (As a side, having the ability to set a new execution role for the container override would also be incredibly useful).

Currently, neither of the two are possible. ContainerOverride's 'command' only accepts JsonPath.listAt. However, it doesn't accept JsonPath.stringAt() or JsonPath.Array().

Current Behavior

If you try to set the container field as

   const FooBar = new tasks.EcsRunTask(this, 'Foobar', {
      containerOverrides: [{
         command: JsonPath.array(('States.Array($.Foo,$.Bar,$.Foo,$.Bar,$.Foo)'),
       }],

There'll be a red squiggly line under command, saying: Type 'string' is not assignable to type 'string[]'

If you put square brackets around it:

   const FooBar = new tasks.EcsRunTask(this, 'Foobar', {
      containerOverrides: [{
         command: [JsonPath.array(('States.Array($.Foo,$.Bar,$.Foo,$.Bar,$.Foo)')],
       }],

You get an error saying:

''Cannot use JsonPath fields in an array, they must be used in objects''

Possible Solution

No response

Additional Information/Context

-

CDK CLI Version

2.63.2

Framework Version

No response

Node.js Version

v19.4.0

OS

MacOS

Language

Typescript

Language Version

No response

Other information

No response

khushail commented 1 year ago

Hi @MieladN , thanks for mentioning this. We are classifying this as a feature request as we don't support this right now. I am marking this issue as p2, which means that we are unable to work on this immediately.

We use +1s to help prioritize our work, and are happy to revaluate this issue based on community feedback. You can reach out to the cdk.dev community on Slack to solicit support for reprioritization.

mKeRix commented 11 months ago

I ran into the same issue just now and could create a workaround for myself by using the same method call that JsonPath.listAt makes underneath directly (circumventing its validator). In Golang it ends up looking like this: awscdk.Token_AsList(awsstepfunctions.JsonPath_Array(jsii.String(awsstepfunctions.JsonPath_StringAt("$.foobar")))). I believe in Typescript it should look like this in the end: Token.asList(JsonPath.array(JsonPath.stringAt("$.foobar")))

Belair34 commented 1 month ago

Also, for the record: OP had a concern about using CallAwsService as a workaround, but it not supporting .sync. The alternative to this is using a CustomState and for the "Resource" parameter specifying it like this: Resource: 'arn:aws:states:::ecs:runTask.sync' This is another workaround, but I would go with the response above.