Skip to content

Commit aebb331

Browse files
authored
feat(events-targets): allow all ECS TaskOverrides (#32344)
### Issue #32217 Closes #32217. ### Reason for this change ECS targets can override any item in the [`TaskOverride` structure](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskOverride.html) via the `input` parameter, according to [the docs](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-targets.html#targets-specifics-ecs-task). However, today, only the `containerOverrides` option is exposed: https://github.com/aws/aws-cdk/blob/1b7265bf5cc623b2e362266c96ce866df539581f/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts#L225-L227 ### Description of changes This PR adds all `TaskOverride` properties to the `input` parameter. ### Description of how you validated changes I add unit tests. I also updated the existing integration tests to include additional overrides. I validated them in my AWS account. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent a0fa042 commit aebb331

20 files changed

+286
-31
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/EcsTestDefaultTestDeployAssert8B2741C4.assets.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/aws-ecs-integ-ecs.assets.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/aws-ecs-integ-ecs.template.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@
10281028
}
10291029
},
10301030
"Id": "Target0",
1031-
"Input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}]}",
1031+
"Input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}],\"cpu\":\"512\",\"memory\":\"512\"}",
10321032
"RoleArn": {
10331033
"Fn::GetAtt": [
10341034
"TaskDefEventsRoleFB3B67B8",
@@ -1078,4 +1078,4 @@
10781078
]
10791079
}
10801080
}
1081-
}
1081+
}

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/cdk.out

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/integ.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/manifest.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/tree.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.ts

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ rule.addTarget(new targets.EcsTask({
4343
cluster,
4444
taskDefinition,
4545
taskCount: 1,
46+
cpu: '512',
47+
memory: '512',
4648
containerOverrides: [{
4749
containerName: 'TheContainer',
4850
environment: [

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/EcsFargateTestDefaultTestDeployAssert36341BFB.assets.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/aws-ecs-integ-fargate.assets.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/aws-ecs-integ-fargate.template.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@
831831
}
832832
},
833833
"Id": "Target0",
834-
"Input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}]}",
834+
"Input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}],\"cpu\":\"512\",\"memory\":\"512\"}",
835835
"RoleArn": {
836836
"Fn::GetAtt": [
837837
"TaskDefEventsRoleFB3B67B8",
@@ -959,4 +959,4 @@
959959
]
960960
}
961961
}
962-
}
962+
}

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/cdk.out

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/integ.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/manifest.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/tree.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.ts

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ rule.addTarget(new targets.EcsTask({
4747
taskDefinition,
4848
taskCount: 1,
4949
enableExecuteCommand: true,
50+
cpu: '512',
51+
memory: '512',
5052
containerOverrides: [{
5153
containerName: 'TheContainer',
5254
environment: [

packages/aws-cdk-lib/aws-events-targets/README.md

+27
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,33 @@ rule.addTarget(new targets.EcsTask({
564564
}));
565565
```
566566

567+
### Overriding Values in the Task Definition
568+
569+
You can override values in the task definition by setting the corresponding properties in the `EcsTaskProps`. All
570+
values in the [`TaskOverrides` API](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskOverride.html) are
571+
supported.
572+
573+
```ts
574+
import * as ecs from 'aws-cdk-lib/aws-ecs';
575+
576+
declare const cluster: ecs.ICluster;
577+
declare const taskDefinition: ecs.TaskDefinition;
578+
579+
const rule = new events.Rule(this, 'Rule', {
580+
schedule: events.Schedule.rate(cdk.Duration.hours(1)),
581+
});
582+
583+
rule.addTarget(new targets.EcsTask({
584+
cluster,
585+
taskDefinition,
586+
taskCount: 1,
587+
588+
// Overrides the cpu and memory values in the task definition
589+
cpu: '512',
590+
memory: '512',
591+
}));
592+
```
593+
567594
## Schedule a Redshift query (serverless or cluster)
568595

569596
Use the `RedshiftQuery` target to schedule an Amazon Redshift Query.

packages/aws-cdk-lib/aws-events-targets/lib/ecs-task-properties.ts

+28
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,31 @@ export interface TaskEnvironmentVariable {
5656
*/
5757
readonly value: string;
5858
}
59+
60+
/**
61+
* Override ephemeral storage for the task.
62+
*/
63+
export interface EphemeralStorageOverride {
64+
/**
65+
* The total amount, in GiB, of ephemeral storage to set for the task.
66+
*
67+
* The minimum supported value is 20 GiB and the maximum supported value is 200 GiB.
68+
*/
69+
readonly sizeInGiB: number;
70+
}
71+
72+
/**
73+
* Override inference accelerators for the task.
74+
*/
75+
export interface InferenceAcceleratorOverride {
76+
/**
77+
* The Elastic Inference accelerator device name to override for the task.
78+
* This parameter must match a `deviceName` specified in the task definition.
79+
*/
80+
readonly deviceName: string;
81+
82+
/**
83+
* The Elastic Inference accelerator type to use.
84+
*/
85+
readonly deviceType: string;
86+
}

packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts

+75-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Construct } from 'constructs';
2-
import { ContainerOverride } from './ecs-task-properties';
2+
import { ContainerOverride, EphemeralStorageOverride, InferenceAcceleratorOverride } from './ecs-task-properties';
33
import { addToDeadLetterQueueResourcePolicy, bindBaseTargetConfig, singletonEventRole, TargetBaseProps } from './util';
44
import * as ec2 from '../../aws-ec2';
55
import * as ecs from '../../aws-ecs';
@@ -50,6 +50,54 @@ export interface EcsTaskProps extends TargetBaseProps {
5050
*/
5151
readonly containerOverrides?: ContainerOverride[];
5252

53+
/**
54+
* The CPU override for the task.
55+
*
56+
* @default - The task definition's CPU value
57+
*/
58+
readonly cpu?: string;
59+
60+
/**
61+
* The ephemeral storage setting override for the task.
62+
*
63+
* NOTE: This parameter is only supported for tasks hosted on Fargate that use the following platform versions:
64+
* - Linux platform version 1.4.0 or later.
65+
* - Windows platform version 1.0.0 or later.
66+
*
67+
* @default - The task definition's ephemeral storage value
68+
*/
69+
readonly ephemeralStorage?: EphemeralStorageOverride;
70+
71+
/**
72+
* The execution role for the task.
73+
*
74+
* The Amazon Resource Name (ARN) of the task execution role override for the task.
75+
*
76+
* @default - The task definition's execution role
77+
*/
78+
readonly executionRole?: iam.IRole;
79+
80+
/**
81+
* The Elastic Inference accelerator override for the task.
82+
*
83+
* @default - The task definition's inference accelerator overrides
84+
*/
85+
readonly inferenceAcceleratorOverrides?: InferenceAcceleratorOverride[];
86+
87+
/**
88+
* The memory override for the task.
89+
*
90+
* @default - The task definition's memory value
91+
*/
92+
readonly memory?: string;
93+
94+
/**
95+
* The IAM role for the task.
96+
*
97+
* @default - The task definition's task role
98+
*/
99+
readonly taskRole?: iam.IRole;
100+
53101
/**
54102
* In what subnets to place the task's ENIs
55103
*
@@ -222,14 +270,12 @@ export class EcsTask implements events.IRuleTarget {
222270
public bind(_rule: events.IRule, _id?: string): events.RuleTargetConfig {
223271
const arn = this.cluster.clusterArn;
224272
const role = this.role;
225-
const containerOverrides = this.props.containerOverrides && this.props.containerOverrides
226-
.map(({ containerName, ...overrides }) => ({ name: containerName, ...overrides }));
227-
const input = { containerOverrides };
228273
const taskCount = this.taskCount;
229274
const taskDefinitionArn = this.taskDefinition.taskDefinitionArn;
230275
const propagateTags = this.propagateTags;
231276
const tagList = this.tags;
232277
const enableExecuteCommand = this.enableExecuteCommand;
278+
const input = this.createInput();
233279

234280
const subnetSelection = this.props.subnetSelection || { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS };
235281

@@ -276,6 +322,31 @@ export class EcsTask implements events.IRuleTarget {
276322
};
277323
}
278324

325+
private createInput(): Record<string, any> {
326+
const containerOverrides = this.props.containerOverrides && this.props.containerOverrides
327+
.map(({ containerName, ...overrides }) => ({ name: containerName, ...overrides }));
328+
329+
if (this.props.ephemeralStorage) {
330+
const ephemeralStorage = this.props.ephemeralStorage;
331+
if (ephemeralStorage.sizeInGiB < 20 || ephemeralStorage.sizeInGiB > 200) {
332+
throw new Error('Ephemeral storage size must be between 20 GiB and 200 GiB.');
333+
}
334+
}
335+
336+
// See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskOverride.html
337+
return {
338+
// In prior versions, containerOverrides was passed even when undefined, so we always set it for backward compatibility.
339+
containerOverrides,
340+
341+
...(this.props.cpu && { cpu: this.props.cpu }),
342+
...(this.props.ephemeralStorage && { ephemeralStorage: this.props.ephemeralStorage }),
343+
...(this.props.executionRole?.roleArn && { executionRole: this.props.executionRole.roleArn }),
344+
...(this.props.inferenceAcceleratorOverrides && { inferenceAcceleratorOverrides: this.props.inferenceAcceleratorOverrides }),
345+
...(this.props.memory && { memory: this.props.memory }),
346+
...(this.props.taskRole?.roleArn && { taskRole: this.props.taskRole.roleArn }),
347+
};
348+
}
349+
279350
private createEventRolePolicyStatements(): iam.PolicyStatement[] {
280351
// check if there is a taskdefinition revision (arn will end with : followed by digits) included in the arn already
281352
let needsRevisionWildcard = false;

0 commit comments

Comments
 (0)