From 8036feabb82fd02e284812800c2b778a6e3d4dec Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Sat, 30 Nov 2024 12:46:15 -0600 Subject: [PATCH 1/8] feat: add all ecs task properties for overrides --- .../lib/ecs-task-properties.ts | 26 ++++++++ .../aws-events-targets/lib/ecs-task.ts | 65 ++++++++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task-properties.ts b/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task-properties.ts index 4c37724b00dc4..52f1e29e6af7c 100644 --- a/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task-properties.ts +++ b/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task-properties.ts @@ -56,3 +56,29 @@ export interface TaskEnvironmentVariable { */ readonly value: string; } + +/** + * Override ephemeral storage for the task. + */ +export interface EphemeralStorageOverride { + /** + * The total amount, in GiB, of ephemeral storage to set for the task. + */ + readonly sizeInGiB: number; +} + +/** + * Override inference accelerators for the task. + */ +export interface InferenceAcceleratorOverride { + /** + * The Elastic Inference accelerator device name to override for the task. + * This parameter must match a `deviceName` specified in the task definition. + */ + readonly deviceName: string; + + /** + * The Elastic Inference accelerator type to use. + */ + readonly deviceType: string; +} diff --git a/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts b/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts index 886622d0215a0..505978ab44626 100644 --- a/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts +++ b/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts @@ -1,5 +1,5 @@ import { Construct } from 'constructs'; -import { ContainerOverride } from './ecs-task-properties'; +import { ContainerOverride, EphemeralStorageOverride, InferenceAcceleratorOverride } from './ecs-task-properties'; import { addToDeadLetterQueueResourcePolicy, bindBaseTargetConfig, singletonEventRole, TargetBaseProps } from './util'; import * as ec2 from '../../aws-ec2'; import * as ecs from '../../aws-ecs'; @@ -50,6 +50,54 @@ export interface EcsTaskProps extends TargetBaseProps { */ readonly containerOverrides?: ContainerOverride[]; + /** + * The CPU override for the task. + * + * @default - The task definition's CPU value + */ + readonly cpu?: string; + + /** + * The ephemeral storage setting override for the task. + * + * NOTE: This parameter is only supported for tasks hosted on Fargate that use the following platform versions: + * - Linux platform version 1.4.0 or later. + * - Windows platform version 1.0.0 or later. + * + * @default - The task definition's ephemeral storage value + */ + readonly ephemeralStorage?: EphemeralStorageOverride; + + /** + * The execution role for the task. + * + * The Amazon Resource Name (ARN) of the task execution role override for the task. + * + * @default - The task definition's execution role + */ + readonly executionRole?: iam.IRole; + + /** + * The Elastic Inference accelerator override for the task. + * + * @default - The task definition's inference accelerator overrides + */ + readonly inferenceAcceleratorOverrides?: InferenceAcceleratorOverride[]; + + /** + * The memory override for the task. + * + * @default - The task definition's memory value + */ + readonly memory?: string; + + /** + * The IAM role for the task. + * + * @default - The task definition's task role + */ + readonly taskRole?: iam.IRole; + /** * In what subnets to place the task's ENIs * @@ -224,7 +272,20 @@ export class EcsTask implements events.IRuleTarget { const role = this.role; const containerOverrides = this.props.containerOverrides && this.props.containerOverrides .map(({ containerName, ...overrides }) => ({ name: containerName, ...overrides })); - const input = { containerOverrides }; + + // See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskOverride.html + const input = { + // In prior versions, containerOverrides was passed even when undefined, so we always set it for backward compatibility. + containerOverrides, + + ...(this.props.cpu && { cpu: this.props.cpu }), + ...(this.props.ephemeralStorage && { ephemeralStorage: this.props.ephemeralStorage }), + ...(this.props.executionRole?.roleArn && { executionRole: this.props.executionRole.roleArn }), + ...(this.props.inferenceAcceleratorOverrides && { inferenceAcceleratorOverrides: this.props.inferenceAcceleratorOverrides }), + ...(this.props.memory && { memory: this.props.memory }), + ...(this.props.taskRole?.roleArn && { taskRole: this.props.taskRole.roleArn }), + }; + const taskCount = this.taskCount; const taskDefinitionArn = this.taskDefinition.taskDefinitionArn; const propagateTags = this.propagateTags; From c42d4969cb4e68f2de63d46bcf86fed53b8c2751 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Sat, 30 Nov 2024 12:50:02 -0600 Subject: [PATCH 2/8] refactor: move input to a separate private method --- .../lib/ecs-task-properties.ts | 2 + .../aws-events-targets/lib/ecs-task.ts | 42 ++++++++++++------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task-properties.ts b/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task-properties.ts index 52f1e29e6af7c..ffc40a066f8e0 100644 --- a/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task-properties.ts +++ b/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task-properties.ts @@ -63,6 +63,8 @@ export interface TaskEnvironmentVariable { export interface EphemeralStorageOverride { /** * The total amount, in GiB, of ephemeral storage to set for the task. + * + * The minimum supported value is 20 GiB and the maximum supported value is 200 GiB. */ readonly sizeInGiB: number; } diff --git a/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts b/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts index 505978ab44626..2c69e6265d609 100644 --- a/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts +++ b/packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts @@ -270,27 +270,12 @@ export class EcsTask implements events.IRuleTarget { public bind(_rule: events.IRule, _id?: string): events.RuleTargetConfig { const arn = this.cluster.clusterArn; const role = this.role; - const containerOverrides = this.props.containerOverrides && this.props.containerOverrides - .map(({ containerName, ...overrides }) => ({ name: containerName, ...overrides })); - - // See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskOverride.html - const input = { - // In prior versions, containerOverrides was passed even when undefined, so we always set it for backward compatibility. - containerOverrides, - - ...(this.props.cpu && { cpu: this.props.cpu }), - ...(this.props.ephemeralStorage && { ephemeralStorage: this.props.ephemeralStorage }), - ...(this.props.executionRole?.roleArn && { executionRole: this.props.executionRole.roleArn }), - ...(this.props.inferenceAcceleratorOverrides && { inferenceAcceleratorOverrides: this.props.inferenceAcceleratorOverrides }), - ...(this.props.memory && { memory: this.props.memory }), - ...(this.props.taskRole?.roleArn && { taskRole: this.props.taskRole.roleArn }), - }; - const taskCount = this.taskCount; const taskDefinitionArn = this.taskDefinition.taskDefinitionArn; const propagateTags = this.propagateTags; const tagList = this.tags; const enableExecuteCommand = this.enableExecuteCommand; + const input = this.createInput(); const subnetSelection = this.props.subnetSelection || { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }; @@ -337,6 +322,31 @@ export class EcsTask implements events.IRuleTarget { }; } + private createInput(): Record { + const containerOverrides = this.props.containerOverrides && this.props.containerOverrides + .map(({ containerName, ...overrides }) => ({ name: containerName, ...overrides })); + + if (this.props.ephemeralStorage) { + const ephemeralStorage = this.props.ephemeralStorage; + if (ephemeralStorage.sizeInGiB < 20 || ephemeralStorage.sizeInGiB > 200) { + throw new Error('Ephemeral storage size must be between 20 GiB and 200 GiB.'); + } + } + + // See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskOverride.html + return { + // In prior versions, containerOverrides was passed even when undefined, so we always set it for backward compatibility. + containerOverrides, + + ...(this.props.cpu && { cpu: this.props.cpu }), + ...(this.props.ephemeralStorage && { ephemeralStorage: this.props.ephemeralStorage }), + ...(this.props.executionRole?.roleArn && { executionRole: this.props.executionRole.roleArn }), + ...(this.props.inferenceAcceleratorOverrides && { inferenceAcceleratorOverrides: this.props.inferenceAcceleratorOverrides }), + ...(this.props.memory && { memory: this.props.memory }), + ...(this.props.taskRole?.roleArn && { taskRole: this.props.taskRole.roleArn }), + }; + } + private createEventRolePolicyStatements(): iam.PolicyStatement[] { // check if there is a taskdefinition revision (arn will end with : followed by digits) included in the arn already let needsRevisionWildcard = false; From 6050489683d7503c1ea92c852ff87a39f8d06299 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Sat, 30 Nov 2024 12:54:10 -0600 Subject: [PATCH 3/8] feat: add unit tests for ephemeral storage --- .../test/ecs/event-rule-target.test.ts | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts b/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts index 74f3b9024d70d..8e5b0cae188bb 100644 --- a/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts +++ b/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts @@ -1193,3 +1193,53 @@ test('Imported task definition with revision uses original arn for policy resour const template = Template.fromStack(stack); template.hasResource('AWS::IAM::Policy', { Properties: policyMatch }); }); + +test('throws an error when ephemeral storage size is less than 20 GiB', () => { + // GIVEN + const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef'); + taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromRegistry('henk'), + }); + + const rule = new events.Rule(stack, 'Rule', { + schedule: events.Schedule.expression('rate(1 min)'), + }); + const target = new targets.EcsTask({ + cluster, + taskDefinition, + ephemeralStorage: { + sizeInGiB: 10, // Less than minimum 20 GiB + }, + }); + + // WHEN + // THEN + expect(() => { + rule.addTarget(target); + }).toThrow(/Ephemeral storage size must be between 20 GiB and 200 GiB/); +}); + +test('throws an error when ephemeral storage size is greater than 200 GiB', () => { + // GIVEN + const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef'); + taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromRegistry('henk'), + }); + + const rule = new events.Rule(stack, 'Rule', { + schedule: events.Schedule.expression('rate(1 min)'), + }); + const target = new targets.EcsTask({ + cluster, + taskDefinition, + ephemeralStorage: { + sizeInGiB: 201, // Greater than maximum 200 GiB + }, + }); + + // WHEN + // THEN + expect(() => { + rule.addTarget(target); + }).toThrow(/Ephemeral storage size must be between 20 GiB and 200 GiB/); +}); From ddf3a135127d92762e2da1d18a95ffb9ec0f7c93 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Sat, 30 Nov 2024 12:59:53 -0600 Subject: [PATCH 4/8] feat: test all inputs --- .../test/ecs/event-rule-target.test.ts | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts b/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts index 8e5b0cae188bb..25ced3411c36c 100644 --- a/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts +++ b/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts @@ -1243,3 +1243,100 @@ test('throws an error when ephemeral storage size is greater than 200 GiB', () = rule.addTarget(target); }).toThrow(/Ephemeral storage size must be between 20 GiB and 200 GiB/); }); + +test('it can override all possible ecs task properties via the input property', () => { + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromRegistry('henk'), + memoryLimitMiB: 256, + }); + + const rule = new events.Rule(stack, 'Rule', { + schedule: events.Schedule.expression('rate(1 min)'), + }); + + // WHEN + rule.addTarget(new targets.EcsTask({ + cluster, + taskDefinition, + taskCount: 1, + + // All possible overrides + // see https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskOverride.html + containerOverrides: [{ + containerName: 'TheContainer', + command: ['echo', events.EventField.fromPath('$.detail.event')], + }], + cpu: '1024', + ephemeralStorage: { + sizeInGiB: 100, + }, + executionRole: new iam.Role(stack, 'ExecutionRoleOverride', { + assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), + }), + inferenceAcceleratorOverrides: [{ + deviceName: 'device-name', + deviceType: 'device-type', + }], + memory: '2048', + taskRole: new iam.Role(stack, 'TaskRoleOverride', { + assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), + }), + })); + + // THEN + const template = Template.fromStack(stack); + debugger; + Template.fromStack(stack).hasResourceProperties('AWS::Events::Rule', { + Targets: [ + { + Arn: { + 'Fn::GetAtt': [ + 'EcsCluster97242B84', + 'Arn', + ], + }, + EcsParameters: { + TaskCount: 1, + TaskDefinitionArn: { + Ref: 'TaskDef54694570', + }, + }, + Id: 'Target0', + InputTransformer: { + InputPathsMap: { + 'detail-event': '$.detail.event', + }, + InputTemplate: { + 'Fn::Join': [ + '', + [ + '{"containerOverrides":[{"name":"TheContainer","command":["echo",]}],"cpu":"1024","ephemeralStorage":{"sizeInGiB":100},"executionRole":"', + { + 'Fn::GetAtt': [ + 'ExecutionRoleOverrideE576BCB8', + 'Arn', + ], + }, + '","inferenceAcceleratorOverrides":[{"deviceName":"device-name","deviceType":"device-type"}],"memory":"2048","taskRole":"', + { + 'Fn::GetAtt': [ + 'TaskRoleOverride9910DE20', + 'Arn', + ], + }, + '"}', + ], + ], + }, + }, + RoleArn: { + 'Fn::GetAtt': [ + 'TaskDefEventsRoleFB3B67B8', + 'Arn', + ], + }, + }, + ], + }); +}); From b3870721f0ef5eb5c32cf282226c3117361019ae Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Sun, 1 Dec 2024 10:18:56 -0700 Subject: [PATCH 5/8] fix: update ec2 integration test --- .../EcsTestDefaultTestDeployAssert8B2741C4.assets.json | 2 +- .../aws-ecs-integ-ecs.assets.json | 6 +++--- .../aws-ecs-integ-ecs.template.json | 4 ++-- .../test/ecs/integ.event-ec2-task.js.snapshot/cdk.out | 2 +- .../test/ecs/integ.event-ec2-task.js.snapshot/integ.json | 2 +- .../ecs/integ.event-ec2-task.js.snapshot/manifest.json | 4 ++-- .../test/ecs/integ.event-ec2-task.js.snapshot/tree.json | 8 ++++---- .../aws-events-targets/test/ecs/integ.event-ec2-task.ts | 2 ++ 8 files changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/EcsTestDefaultTestDeployAssert8B2741C4.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/EcsTestDefaultTestDeployAssert8B2741C4.assets.json index a8157b72463ac..4f50d17c7e584 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/EcsTestDefaultTestDeployAssert8B2741C4.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/EcsTestDefaultTestDeployAssert8B2741C4.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.0", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/aws-ecs-integ-ecs.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/aws-ecs-integ-ecs.assets.json index d3154cd6e7128..e881bc3eb3509 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/aws-ecs-integ-ecs.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/aws-ecs-integ-ecs.assets.json @@ -1,7 +1,7 @@ { - "version": "36.0.0", + "version": "38.0.1", "files": { - "a45a7e9ee8f6a0851fc55369fe78d110df956cb96319d5c3d73d3d818d94c041": { + "d3a7b59d3e307c6d0d563cccec7f894f7ef5132ecf6541dd5c72be3003d34eba": { "source": { "path": "aws-ecs-integ-ecs.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "a45a7e9ee8f6a0851fc55369fe78d110df956cb96319d5c3d73d3d818d94c041.json", + "objectKey": "d3a7b59d3e307c6d0d563cccec7f894f7ef5132ecf6541dd5c72be3003d34eba.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/aws-ecs-integ-ecs.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/aws-ecs-integ-ecs.template.json index 27b833b65a416..7b6c49faa547d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/aws-ecs-integ-ecs.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/aws-ecs-integ-ecs.template.json @@ -1028,7 +1028,7 @@ } }, "Id": "Target0", - "Input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}]}", + "Input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}],\"cpu\":\"512\",\"memory\":\"512\"}", "RoleArn": { "Fn::GetAtt": [ "TaskDefEventsRoleFB3B67B8", @@ -1078,4 +1078,4 @@ ] } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/cdk.out index 1f0068d32659a..c6e612584e352 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"36.0.0"} \ No newline at end of file +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/integ.json index bc94f6a9998c9..77e6d65db17d4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "36.0.0", + "version": "38.0.1", "testCases": { "EcsTest/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/manifest.json index dec09707d31a5..4c90b21c629f4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "36.0.0", + "version": "38.0.1", "artifacts": { "aws-ecs-integ-ecs.assets": { "type": "cdk:asset-manifest", @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/a45a7e9ee8f6a0851fc55369fe78d110df956cb96319d5c3d73d3d818d94c041.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/d3a7b59d3e307c6d0d563cccec7f894f7ef5132ecf6541dd5c72be3003d34eba.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/tree.json index 333a699b5a393..ba80e22eebdbc 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.js.snapshot/tree.json @@ -987,7 +987,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.3.0" + "version": "10.4.2" } }, "LifecycleHookDrainHook": { @@ -1719,7 +1719,7 @@ ] } }, - "input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}]}" + "input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}],\"cpu\":\"0.5\",\"memory\":\"512\"}" } ] } @@ -1770,7 +1770,7 @@ "path": "EcsTest/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.3.0" + "version": "10.4.2" } }, "DeployAssert": { @@ -1816,7 +1816,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.3.0" + "version": "10.4.2" } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.ts index ba7fb097c036c..94160c2c2566c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-ec2-task.ts @@ -38,6 +38,8 @@ rule.addTarget(new targets.EcsTask({ cluster, taskDefinition, taskCount: 1, + cpu: '512', + memory: '512', containerOverrides: [{ containerName: 'TheContainer', environment: [ From 9c657aeedd5f77c059ca301970e0bb0bb3236046 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Sun, 1 Dec 2024 10:30:59 -0700 Subject: [PATCH 6/8] fix: updatfargate integration test --- ...csFargateTestDefaultTestDeployAssert36341BFB.assets.json | 2 +- .../aws-ecs-integ-fargate.assets.json | 6 +++--- .../aws-ecs-integ-fargate.template.json | 4 ++-- .../test/ecs/integ.event-fargate-task.js.snapshot/cdk.out | 2 +- .../ecs/integ.event-fargate-task.js.snapshot/integ.json | 2 +- .../ecs/integ.event-fargate-task.js.snapshot/manifest.json | 4 ++-- .../test/ecs/integ.event-fargate-task.js.snapshot/tree.json | 6 +++--- .../aws-events-targets/test/ecs/integ.event-fargate-task.ts | 2 ++ 8 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/EcsFargateTestDefaultTestDeployAssert36341BFB.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/EcsFargateTestDefaultTestDeployAssert36341BFB.assets.json index 6c6f0fc27e8fb..a04e9d2b60d30 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/EcsFargateTestDefaultTestDeployAssert36341BFB.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/EcsFargateTestDefaultTestDeployAssert36341BFB.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.0", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/aws-ecs-integ-fargate.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/aws-ecs-integ-fargate.assets.json index 107b257630581..fabd9252c6f74 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/aws-ecs-integ-fargate.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/aws-ecs-integ-fargate.assets.json @@ -1,7 +1,7 @@ { - "version": "36.0.0", + "version": "38.0.1", "files": { - "ed00054536ff19a8bffb0b7da9fe14588ca286680bef3e6d6a7b7a3d810e12e7": { + "d35ba88d2cda11f4ae4860da6c640f935334423192fa10a545e98772c820bef3": { "source": { "path": "aws-ecs-integ-fargate.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "ed00054536ff19a8bffb0b7da9fe14588ca286680bef3e6d6a7b7a3d810e12e7.json", + "objectKey": "d35ba88d2cda11f4ae4860da6c640f935334423192fa10a545e98772c820bef3.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/aws-ecs-integ-fargate.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/aws-ecs-integ-fargate.template.json index d1cacab077806..14e0516d68344 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/aws-ecs-integ-fargate.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/aws-ecs-integ-fargate.template.json @@ -831,7 +831,7 @@ } }, "Id": "Target0", - "Input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}]}", + "Input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}],\"cpu\":\"512\",\"memory\":\"512\"}", "RoleArn": { "Fn::GetAtt": [ "TaskDefEventsRoleFB3B67B8", @@ -959,4 +959,4 @@ ] } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/cdk.out index 1f0068d32659a..c6e612584e352 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"36.0.0"} \ No newline at end of file +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/integ.json index b3291a6475699..f2162fa393d8e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "36.0.0", + "version": "38.0.1", "testCases": { "EcsFargateTest/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/manifest.json index 10123bd66a76c..e827d8af86c61 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "36.0.0", + "version": "38.0.1", "artifacts": { "aws-ecs-integ-fargate.assets": { "type": "cdk:asset-manifest", @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/ed00054536ff19a8bffb0b7da9fe14588ca286680bef3e6d6a7b7a3d810e12e7.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/d35ba88d2cda11f4ae4860da6c640f935334423192fa10a545e98772c820bef3.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/tree.json index 359ad51d7246a..b39a7cf615e4d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.js.snapshot/tree.json @@ -1455,7 +1455,7 @@ ] } }, - "input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}]}" + "input": "{\"containerOverrides\":[{\"name\":\"TheContainer\",\"environment\":[{\"name\":\"I_WAS_TRIGGERED\",\"value\":\"From CloudWatch Events\"}]}],\"cpu\":\"1024\",\"ephemeralStorage\":{\"sizeInGiB\":21},\"memory\":\"2048\"}" }, { "id": "Target1", @@ -1588,7 +1588,7 @@ "path": "EcsFargateTest/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.3.0" + "version": "10.4.2" } }, "DeployAssert": { @@ -1634,7 +1634,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.3.0" + "version": "10.4.2" } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.ts index 89e5aae6ee65f..6b677b19b99aa 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-events-targets/test/ecs/integ.event-fargate-task.ts @@ -47,6 +47,8 @@ rule.addTarget(new targets.EcsTask({ taskDefinition, taskCount: 1, enableExecuteCommand: true, + cpu: '512', + memory: '512', containerOverrides: [{ containerName: 'TheContainer', environment: [ From b65c237670b8209ca799bc8d8524711c1302df13 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Sun, 1 Dec 2024 10:41:55 -0700 Subject: [PATCH 7/8] docs: add README --- .../aws-cdk-lib/aws-events-targets/README.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/aws-cdk-lib/aws-events-targets/README.md b/packages/aws-cdk-lib/aws-events-targets/README.md index f3680dba9cf45..7755aae482603 100644 --- a/packages/aws-cdk-lib/aws-events-targets/README.md +++ b/packages/aws-cdk-lib/aws-events-targets/README.md @@ -564,6 +564,33 @@ rule.addTarget(new targets.EcsTask({ })); ``` +### Overriding Values in the Task Definition + +You can override values in the task definition by setting the corresponding properties in the `EcsTaskProps`. All +values in the [`TaskOverrides` API](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskOverride.html) are +supported. + +```ts +import * as ecs from 'aws-cdk-lib/aws-ecs'; + +declare const cluster: ecs.ICluster; +declare const taskDefinition: ecs.TaskDefinition; + +const rule = new events.Rule(this, 'Rule', { + schedule: events.Schedule.rate(cdk.Duration.hours(1)), +}); + +rule.addTarget(new targets.EcsTask({ + cluster, + taskDefinition, + taskCount: 1, + + // Overrides the cpu and memory values in the task definition + cpu: '512', + memory: '512', +})); +``` + ## Schedule a Redshift query (serverless or cluster) Use the `RedshiftQuery` target to schedule an Amazon Redshift Query. From 7e60f8792532ad073ce82a32ec3bb057e0abf362 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Fri, 7 Feb 2025 08:35:39 -0700 Subject: [PATCH 8/8] fix: test.each --- .../test/ecs/event-rule-target.test.ts | 32 +++---------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts b/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts index 86639b0a69425..b383ecace3e1e 100644 --- a/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts +++ b/packages/aws-cdk-lib/aws-events-targets/test/ecs/event-rule-target.test.ts @@ -1194,32 +1194,10 @@ test('Imported task definition with revision uses original arn for policy resour template.hasResource('AWS::IAM::Policy', { Properties: policyMatch }); }); -test('throws an error when ephemeral storage size is less than 20 GiB', () => { - // GIVEN - const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef'); - taskDefinition.addContainer('TheContainer', { - image: ecs.ContainerImage.fromRegistry('henk'), - }); - - const rule = new events.Rule(stack, 'Rule', { - schedule: events.Schedule.expression('rate(1 min)'), - }); - const target = new targets.EcsTask({ - cluster, - taskDefinition, - ephemeralStorage: { - sizeInGiB: 10, // Less than minimum 20 GiB - }, - }); - - // WHEN - // THEN - expect(() => { - rule.addTarget(target); - }).toThrow(/Ephemeral storage size must be between 20 GiB and 200 GiB/); -}); - -test('throws an error when ephemeral storage size is greater than 200 GiB', () => { +test.each([ + [10, 'less than minimum'], + [201, 'greater than maximum'], +])('throws an error when ephemeral storage size is %s 20 GiB (%s)', (sizeInGiB: number) => { // GIVEN const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef'); taskDefinition.addContainer('TheContainer', { @@ -1233,7 +1211,7 @@ test('throws an error when ephemeral storage size is greater than 200 GiB', () = cluster, taskDefinition, ephemeralStorage: { - sizeInGiB: 201, // Greater than maximum 200 GiB + sizeInGiB, }, });