From 17f899d94fa1c5f40e2f837e03e74c5128486bb1 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:16:19 +0900 Subject: [PATCH 01/21] feat(ecs): restart policy --- .../aws-ecs/lib/container-definition.ts | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index a620a3510ef3b..373487a0c8bf1 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -384,6 +384,16 @@ export interface ContainerDefinitionOptions { * An array of ulimits to set in the container. */ readonly ulimits?: Ulimit[]; + + /** + * The restart policy for a container. + * + * When you set up a restart policy, Amazon ECS can restart the container without needing to replace the task. + * + * @default - No restart policy. + * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-restart-policy.html + */ + readonly restartPolicy?: RestartPolicy; } /** @@ -873,6 +883,7 @@ export class ContainerDefinition extends Construct { resourceRequirements: (!this.props.gpuCount && this.inferenceAcceleratorResources.length == 0 ) ? undefined : renderResourceRequirements(this.props.gpuCount, this.inferenceAcceleratorResources), systemControls: this.props.systemControls && renderSystemControls(this.props.systemControls), + restartPolicy: this.props.restartPolicy && renderRestartPolicy(this.props.restartPolicy), }; } } @@ -1495,3 +1506,38 @@ function renderSystemControls(systemControls: SystemControl[]): CfnTaskDefinitio value: sc.value, })); } + +/** + * The restart policy for a container + */ +export interface RestartPolicy { + /** + * A list of exit codes that Amazon ECS will ignore and not attempt a restart on. + * + * You can specify a maximum of 50 container exit codes. + * + * @default - No exit codes are ignored. + */ + readonly ignoredExitCodes?: number[]; + + /** + * A period of time that the container must run for before a restart can be attempted. + * + * A container can be restarted only once every `restartAttemptPeriod` seconds. + * If a container isn't able to run for this time period and exits early, it will not be restarted. + * + * You can set a minimum `restartAttemptPeriod` of 60 seconds and a maximum `restartAttemptPeriod` + * of 1800 seconds. + * + * @default Duration.seconds(300) + */ + readonly restartAttemptPeriod?: cdk.Duration; +} + +function renderRestartPolicy(restartPolicy: RestartPolicy): CfnTaskDefinition.RestartPolicy[] { + return { + Enabled: true, + IgnoredExitCodes: restartPolicy.ignoredExitCodes, + RestartAttemptPeriod: restartPolicy.restartAttemptPeriod?.toSeconds(), + }; +} From 3fba75eb3c7bfb7167e2362f76303415c281bd30 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:57:45 +0900 Subject: [PATCH 02/21] validations --- packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index 373487a0c8bf1..9fb1fea0c2657 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -1535,6 +1535,14 @@ export interface RestartPolicy { } function renderRestartPolicy(restartPolicy: RestartPolicy): CfnTaskDefinition.RestartPolicy[] { + if (restartPolicy.ignoredExitCodes && restartPolicy.ignoredExitCodes.length > 50) { + throw new Error(`You can specify a maximum of 50 container exit codes, got: ${restartPolicy.ignoredExitCodes.length}`); + } + if (restartPolicy.restartAttemptPeriod + && (restartPolicy.restartAttemptPeriod.toSeconds() < 60 || restartPolicy.restartAttemptPeriod.toSeconds() > 1800) + ) { + throw new Error('The restartAttemptPeriod must be between 60 seconds and 1800 seconds'); + } return { Enabled: true, IgnoredExitCodes: restartPolicy.ignoredExitCodes, From ff68e428cd05b6438f5a1d962cceacfbfc20e470 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 16:05:34 +0900 Subject: [PATCH 03/21] type --- packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index 9fb1fea0c2657..6f09947d6888b 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -883,7 +883,7 @@ export class ContainerDefinition extends Construct { resourceRequirements: (!this.props.gpuCount && this.inferenceAcceleratorResources.length == 0 ) ? undefined : renderResourceRequirements(this.props.gpuCount, this.inferenceAcceleratorResources), systemControls: this.props.systemControls && renderSystemControls(this.props.systemControls), - restartPolicy: this.props.restartPolicy && renderRestartPolicy(this.props.restartPolicy), + restartPolicy: this.props.restartPolicy && renderRestartPolicy(this.props.restartPoli), }; } } @@ -1534,7 +1534,7 @@ export interface RestartPolicy { readonly restartAttemptPeriod?: cdk.Duration; } -function renderRestartPolicy(restartPolicy: RestartPolicy): CfnTaskDefinition.RestartPolicy[] { +function renderRestartPolicy(restartPolicy: RestartPolicy): CfnTaskDefinition.RestartPolicy { if (restartPolicy.ignoredExitCodes && restartPolicy.ignoredExitCodes.length > 50) { throw new Error(`You can specify a maximum of 50 container exit codes, got: ${restartPolicy.ignoredExitCodes.length}`); } From 7b5c831b5afe717a7b966ed7fd7adc47652fc829 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 16:23:50 +0900 Subject: [PATCH 04/21] validation for firelens --- packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts b/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts index ccea834c0a23d..f8ee31ee6ef7a 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts @@ -222,6 +222,11 @@ export class FirelensLogRouter extends ContainerDefinition { */ constructor(scope: Construct, id: string, props: FirelensLogRouterProps) { super(scope, id, props); + + if (props.restartPolicy) { + throw new Error('Firelens log router container cannot have restart policy'); + } + const options = props.firelensConfig.options; if (options) { if ((options.configFileValue && options.configFileType === undefined) || (options.configFileValue === undefined && options.configFileType)) { From 49aec6bcba6c2b6171d8d96ca14d9e9c27d318ab Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 16:24:27 +0900 Subject: [PATCH 05/21] typo --- packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index 6f09947d6888b..4bdeeef89a780 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -883,7 +883,7 @@ export class ContainerDefinition extends Construct { resourceRequirements: (!this.props.gpuCount && this.inferenceAcceleratorResources.length == 0 ) ? undefined : renderResourceRequirements(this.props.gpuCount, this.inferenceAcceleratorResources), systemControls: this.props.systemControls && renderSystemControls(this.props.systemControls), - restartPolicy: this.props.restartPolicy && renderRestartPolicy(this.props.restartPoli), + restartPolicy: this.props.restartPolicy && renderRestartPolicy(this.props.restartPolicy), }; } } From 241af7fc309df0c39b63d67e428c85ba1bb84425 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 16:47:24 +0900 Subject: [PATCH 06/21] change msg --- packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index 4bdeeef89a780..377defb3ac130 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -1541,7 +1541,7 @@ function renderRestartPolicy(restartPolicy: RestartPolicy): CfnTaskDefinition.Re if (restartPolicy.restartAttemptPeriod && (restartPolicy.restartAttemptPeriod.toSeconds() < 60 || restartPolicy.restartAttemptPeriod.toSeconds() > 1800) ) { - throw new Error('The restartAttemptPeriod must be between 60 seconds and 1800 seconds'); + throw new Error(`The restartAttemptPeriod must be between 60 seconds and 1800 seconds, got ${restartPolicy.restartAttemptPeriod.toSeconds()} seconds`); } return { Enabled: true, From 4316df5907d58bae25dfb18fb86d742d8b822c09 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 17:08:09 +0900 Subject: [PATCH 07/21] unit tests --- .../aws-ecs/test/container-definition.test.ts | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts index 96d357fba7242..538b8f1920095 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts @@ -2758,4 +2758,117 @@ describe('container definition', () => { // THEN expect(() => new ecs.ContainerDefinition(stack, 'Container', containerDefinitionProps)).toThrow(/Only one credential spec is allowed per container definition/); }); + + test('can specify restart policy', () => { + // GIVEN + const stack = new cdk.Stack(); + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + + // WHEN + new ecs.ContainerDefinition(stack, 'Container', { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + taskDefinition, + restartPolicy: { + ignoredExitCodes: [1, 2, 3], + restartAttemptPeriod: cdk.Duration.seconds(360), + }, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', { + ContainerDefinitions: [ + { + Essential: true, + Image: '/aws/aws-example-app', + Name: 'Container', + RestartPolicy: { + Enabled: true, + IgnoredExitCodes: [1, 2, 3], + RestartAttemptPeriod: 360, + }, + }, + ], + }); + }); + + test('can specify restart policy with an empty object', () => { + // GIVEN + const stack = new cdk.Stack(); + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + + // WHEN + new ecs.ContainerDefinition(stack, 'Container', { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + taskDefinition, + restartPolicy: {}, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', { + ContainerDefinitions: [ + { + Essential: true, + Image: '/aws/aws-example-app', + Name: 'Container', + RestartPolicy: { + Enabled: true, + }, + }, + ], + }); + }); + + test('throws when there are more than 50 in ignoredExitCodes', () => { + // GIVEN + const stack = new cdk.Stack(); + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + + // WHEN + const ignoredExitCodes = Array.from({ length: 51 }, (_, i) => i); + + // THEN + expect(() => { + new ecs.ContainerDefinition(stack, 'Container', { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + taskDefinition, + restartPolicy: { + ignoredExitCodes, + }, + }); + }).toThrow(/You can specify a maximum of 50 container exit codes, got: 51/); + }); + + test('throws when restartAttemptPeriod is greater than 1800 seconds', () => { + // GIVEN + const stack = new cdk.Stack(); + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + + // THEN + expect(() => { + new ecs.ContainerDefinition(stack, 'Container', { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + taskDefinition, + restartPolicy: { + restartAttemptPeriod: cdk.Duration.seconds(1801), + }, + }); + }).toThrow(/The restartAttemptPeriod must be between 60 seconds and 1800 seconds, got 1801 seconds/); + }); + + test('throws when restartAttemptPeriod is less than 60 seconds', () => { + // GIVEN + const stack = new cdk.Stack(); + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + + // THEN + expect(() => { + new ecs.ContainerDefinition(stack, 'Container', { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + taskDefinition, + restartPolicy: { + restartAttemptPeriod: cdk.Duration.seconds(59), + }, + }); + }).toThrow(/The restartAttemptPeriod must be between 60 seconds and 1800 seconds, got 59 seconds/); + }); }); From f2979cc6d14b94a2e0931176d8f69a6594e7c757 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 18:41:50 +0900 Subject: [PATCH 08/21] add unit test --- .../aws-ecs/lib/firelens-log-router.ts | 2 +- .../aws-ecs/test/firelens-log-driver.test.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts b/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts index f8ee31ee6ef7a..440e2e3553d91 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts @@ -224,7 +224,7 @@ export class FirelensLogRouter extends ContainerDefinition { super(scope, id, props); if (props.restartPolicy) { - throw new Error('Firelens log router container cannot have restart policy'); + throw new Error('Firelens log router container cannot have restartPolicy'); } const options = props.firelensConfig.options; diff --git a/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts b/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts index 57dda00535cdb..af8891a51b7ec 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts @@ -443,5 +443,20 @@ describe('firelens log driver', () => { ], }); }); + + test('throws when restartPolicy is set', () => { + // THEN + expect(() => { + td.addFirelensLogRouter('log_router', { + image: ecs.obtainDefaultFluentBitECRImage(td, undefined, '2.1.0'), + firelensConfig: { + type: ecs.FirelensLogRouterType.FLUENTBIT, + }, + restartPolicy: { + ignoredExitCodes: [1, 2, 3], + }, + }); + }).toThrow(/Firelens log router container cannot have restartPolicy/); + }); }); }); From d8bba117a0fe064debb03df4b923613618699fd5 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 19:57:24 +0900 Subject: [PATCH 09/21] README --- packages/aws-cdk-lib/aws-ecs/README.md | 29 ++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/aws-cdk-lib/aws-ecs/README.md b/packages/aws-cdk-lib/aws-ecs/README.md index f0669e3adcc66..318e8acd55a9e 100644 --- a/packages/aws-cdk-lib/aws-ecs/README.md +++ b/packages/aws-cdk-lib/aws-ecs/README.md @@ -619,6 +619,35 @@ taskDefinition.addContainer('container', { }); ``` +### Restart policy + +To set a restart policy for the container, use the `restartPolicy`. + +```ts +declare const taskDefinition: ecs.TaskDefinition; + +taskDefinition.addContainer('container', { + image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), + memoryLimitMiB: 1024, + restartPolicy: { + ignoredExitCodes: [1, 2, 3], + restartAttemptPeriod: cdk.Duration.seconds(360), + }, +}); +``` + +You can also just enable the restart policy with default settings. + +```ts +declare const taskDefinition: ecs.TaskDefinition; + +taskDefinition.addContainer('container', { + image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), + memoryLimitMiB: 1024, + restartPolicy: {}, +}); +``` + ## Docker labels You can add labels to the container with the `dockerLabels` property or with the `addDockerLabel` method: From 463a1ec4c5701b3b663cc2b851cbb3d8f8fffdae Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:01:15 +0900 Subject: [PATCH 10/21] add integ tests without snapshots --- ...ask-definition-container-restart-policy.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts new file mode 100644 index 0000000000000..4c3f6980e85da --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts @@ -0,0 +1,22 @@ +import * as cdk from 'aws-cdk-lib'; +import * as ecs from 'aws-cdk-lib/aws-ecs'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-ecs-task-definition-container-restart-policy'); + +const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef', {}); + +taskDefinition.addContainer('Container', { + image: ecs.ContainerImage.fromRegistry('public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest'), + restartPolicy: { + ignoredExitCodes: [1, 2, 3], + restartAttemptPeriod: cdk.Duration.seconds(360), + }, +}); + +new IntegTest(app, 'TaskDefinitionContainerRestartPolicy', { + testCases: [stack], +}); + +app.synth(); \ No newline at end of file From 062c162557102b9cc64f67224a65e82ff0215181 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:56:02 +0900 Subject: [PATCH 11/21] change msg --- packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts | 2 +- packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index 377defb3ac130..f468352d6f716 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -1536,7 +1536,7 @@ export interface RestartPolicy { function renderRestartPolicy(restartPolicy: RestartPolicy): CfnTaskDefinition.RestartPolicy { if (restartPolicy.ignoredExitCodes && restartPolicy.ignoredExitCodes.length > 50) { - throw new Error(`You can specify a maximum of 50 container exit codes, got: ${restartPolicy.ignoredExitCodes.length}`); + throw new Error(`Only up to 50 can be specified for ignoredExitCodes, got: ${restartPolicy.ignoredExitCodes.length}`); } if (restartPolicy.restartAttemptPeriod && (restartPolicy.restartAttemptPeriod.toSeconds() < 60 || restartPolicy.restartAttemptPeriod.toSeconds() > 1800) diff --git a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts index 538b8f1920095..e7d9dea86e828 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts @@ -2835,7 +2835,7 @@ describe('container definition', () => { ignoredExitCodes, }, }); - }).toThrow(/You can specify a maximum of 50 container exit codes, got: 51/); + }).toThrow(/Only up to 50 can be specified for ignoredExitCodes, got: 51/); }); test('throws when restartAttemptPeriod is greater than 1800 seconds', () => { From 65a019b3ab829d93d86336f93a344178d5ba2d07 Mon Sep 17 00:00:00 2001 From: "Kenta Goto (k.goto)" <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 21:13:40 +0900 Subject: [PATCH 12/21] Update README.md --- packages/aws-cdk-lib/aws-ecs/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/README.md b/packages/aws-cdk-lib/aws-ecs/README.md index 318e8acd55a9e..4c27744fab69d 100644 --- a/packages/aws-cdk-lib/aws-ecs/README.md +++ b/packages/aws-cdk-lib/aws-ecs/README.md @@ -628,7 +628,6 @@ declare const taskDefinition: ecs.TaskDefinition; taskDefinition.addContainer('container', { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), - memoryLimitMiB: 1024, restartPolicy: { ignoredExitCodes: [1, 2, 3], restartAttemptPeriod: cdk.Duration.seconds(360), From 594eb7391d0b6df2db1bf012c3de74beb62b1849 Mon Sep 17 00:00:00 2001 From: "Kenta Goto (k.goto)" <24818752+go-to-k@users.noreply.github.com> Date: Tue, 27 Aug 2024 21:13:47 +0900 Subject: [PATCH 13/21] Update README.md --- packages/aws-cdk-lib/aws-ecs/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/README.md b/packages/aws-cdk-lib/aws-ecs/README.md index 4c27744fab69d..23778541c5250 100644 --- a/packages/aws-cdk-lib/aws-ecs/README.md +++ b/packages/aws-cdk-lib/aws-ecs/README.md @@ -642,7 +642,6 @@ declare const taskDefinition: ecs.TaskDefinition; taskDefinition.addContainer('container', { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), - memoryLimitMiB: 1024, restartPolicy: {}, }); ``` From f9179dc1d3dcfed05083e831c9e4432ed4e46307 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:28:16 +0900 Subject: [PATCH 14/21] comments --- packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index f468352d6f716..d37b5ca4b178d 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -390,6 +390,8 @@ export interface ContainerDefinitionOptions { * * When you set up a restart policy, Amazon ECS can restart the container without needing to replace the task. * + * You can't enable a restart policy for a Firelens log router container. + * * @default - No restart policy. * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-restart-policy.html */ From 66a3db5facee0c2b31f78ece6d9f3d98eb56e957 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:34:11 +0900 Subject: [PATCH 15/21] change properties to flat integ style --- ...ask-definition-container-restart-policy.ts | 7 +- packages/aws-cdk-lib/aws-ecs/README.md | 21 ++--- .../aws-ecs/lib/container-definition.ts | 78 +++++++++---------- .../aws-ecs/lib/firelens-log-router.ts | 4 +- .../aws-ecs/test/container-definition.test.ts | 65 ++++++++++------ .../aws-ecs/test/firelens-log-driver.test.ts | 8 +- 6 files changed, 93 insertions(+), 90 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts index 4c3f6980e85da..d0edf035c2c05 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts @@ -9,10 +9,9 @@ const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef', {}); taskDefinition.addContainer('Container', { image: ecs.ContainerImage.fromRegistry('public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest'), - restartPolicy: { - ignoredExitCodes: [1, 2, 3], - restartAttemptPeriod: cdk.Duration.seconds(360), - }, + enableRestartPolicy: true, + restartIgnoredExitCodes: [1, 2, 3], + restartAttemptPeriod: cdk.Duration.seconds(360), }); new IntegTest(app, 'TaskDefinitionContainerRestartPolicy', { diff --git a/packages/aws-cdk-lib/aws-ecs/README.md b/packages/aws-cdk-lib/aws-ecs/README.md index 23778541c5250..0efa1354df967 100644 --- a/packages/aws-cdk-lib/aws-ecs/README.md +++ b/packages/aws-cdk-lib/aws-ecs/README.md @@ -621,28 +621,17 @@ taskDefinition.addContainer('container', { ### Restart policy -To set a restart policy for the container, use the `restartPolicy`. +To enable a restart policy for the container, set `enableRestartPolicy` to true and also specify +`restartIgnoredExitCodes` and `restartAttemptPeriod` if necessary. ```ts declare const taskDefinition: ecs.TaskDefinition; taskDefinition.addContainer('container', { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), - restartPolicy: { - ignoredExitCodes: [1, 2, 3], - restartAttemptPeriod: cdk.Duration.seconds(360), - }, -}); -``` - -You can also just enable the restart policy with default settings. - -```ts -declare const taskDefinition: ecs.TaskDefinition; - -taskDefinition.addContainer('container', { - image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), - restartPolicy: {}, + enableRestartPolicy: true, + restartIgnoredExitCodes: [1, 2, 3], + restartAttemptPeriod: cdk.Duration.seconds(360), }); ``` diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index d37b5ca4b178d..1e2066faa33d1 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -386,16 +386,42 @@ export interface ContainerDefinitionOptions { readonly ulimits?: Ulimit[]; /** - * The restart policy for a container. + * Enable a restart policy for a container. * * When you set up a restart policy, Amazon ECS can restart the container without needing to replace the task. * * You can't enable a restart policy for a Firelens log router container. * - * @default - No restart policy. + * @default false * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-restart-policy.html */ - readonly restartPolicy?: RestartPolicy; + readonly enableRestartPolicy?: boolean; + + /** + * A list of exit codes that Amazon ECS will ignore and not attempt a restart on. + * + * This property is only used if `enableRestartPolicy` is set to true. + * + * You can specify a maximum of 50 container exit codes. + * + * @default - No exit codes are ignored. + */ + readonly restartIgnoredExitCodes?: number[]; + + /** + * A period of time that the container must run for before a restart can be attempted. + * + * A container can be restarted only once every `restartAttemptPeriod` seconds. + * If a container isn't able to run for this time period and exits early, it will not be restarted. + * + * This property is only used if `enableRestartPolicy` is set to true. + * + * You can set a minimum `restartAttemptPeriod` of 60 seconds and a maximum `restartAttemptPeriod` + * of 1800 seconds. + * + * @default - Duration.seconds(300) if `enableRestartPolicy` is true, otherwise no period. + */ + readonly restartAttemptPeriod?: cdk.Duration; } /** @@ -885,7 +911,8 @@ export class ContainerDefinition extends Construct { resourceRequirements: (!this.props.gpuCount && this.inferenceAcceleratorResources.length == 0 ) ? undefined : renderResourceRequirements(this.props.gpuCount, this.inferenceAcceleratorResources), systemControls: this.props.systemControls && renderSystemControls(this.props.systemControls), - restartPolicy: this.props.restartPolicy && renderRestartPolicy(this.props.restartPolicy), + restartPolicy: this.props.enableRestartPolicy ? + renderRestartPolicy(this.props.restartIgnoredExitCodes, this.props.restartAttemptPeriod) : undefined, }; } } @@ -1509,45 +1536,16 @@ function renderSystemControls(systemControls: SystemControl[]): CfnTaskDefinitio })); } -/** - * The restart policy for a container - */ -export interface RestartPolicy { - /** - * A list of exit codes that Amazon ECS will ignore and not attempt a restart on. - * - * You can specify a maximum of 50 container exit codes. - * - * @default - No exit codes are ignored. - */ - readonly ignoredExitCodes?: number[]; - - /** - * A period of time that the container must run for before a restart can be attempted. - * - * A container can be restarted only once every `restartAttemptPeriod` seconds. - * If a container isn't able to run for this time period and exits early, it will not be restarted. - * - * You can set a minimum `restartAttemptPeriod` of 60 seconds and a maximum `restartAttemptPeriod` - * of 1800 seconds. - * - * @default Duration.seconds(300) - */ - readonly restartAttemptPeriod?: cdk.Duration; -} - -function renderRestartPolicy(restartPolicy: RestartPolicy): CfnTaskDefinition.RestartPolicy { - if (restartPolicy.ignoredExitCodes && restartPolicy.ignoredExitCodes.length > 50) { - throw new Error(`Only up to 50 can be specified for ignoredExitCodes, got: ${restartPolicy.ignoredExitCodes.length}`); +function renderRestartPolicy(restartIgnoredExitCodes?: number[], restartAttemptPeriod?: cdk.Duration): CfnTaskDefinition.RestartPolicy { + if (restartIgnoredExitCodes && restartIgnoredExitCodes.length > 50) { + throw new Error(`Only up to 50 can be specified for restartIgnoredExitCodes, got: ${restartIgnoredExitCodes.length}`); } - if (restartPolicy.restartAttemptPeriod - && (restartPolicy.restartAttemptPeriod.toSeconds() < 60 || restartPolicy.restartAttemptPeriod.toSeconds() > 1800) - ) { - throw new Error(`The restartAttemptPeriod must be between 60 seconds and 1800 seconds, got ${restartPolicy.restartAttemptPeriod.toSeconds()} seconds`); + if (restartAttemptPeriod && (restartAttemptPeriod.toSeconds() < 60 || restartAttemptPeriod.toSeconds() > 1800)) { + throw new Error(`The restartAttemptPeriod must be between 60 seconds and 1800 seconds, got ${restartAttemptPeriod.toSeconds()} seconds`); } return { Enabled: true, - IgnoredExitCodes: restartPolicy.ignoredExitCodes, - RestartAttemptPeriod: restartPolicy.restartAttemptPeriod?.toSeconds(), + IgnoredExitCodes: restartIgnoredExitCodes, + RestartAttemptPeriod: restartAttemptPeriod?.toSeconds(), }; } diff --git a/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts b/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts index 440e2e3553d91..fb7a264cf0a47 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts @@ -223,8 +223,8 @@ export class FirelensLogRouter extends ContainerDefinition { constructor(scope: Construct, id: string, props: FirelensLogRouterProps) { super(scope, id, props); - if (props.restartPolicy) { - throw new Error('Firelens log router container cannot have restartPolicy'); + if (props.enableRestartPolicy) { + throw new Error('Firelens log router container cannot enable restart policy'); } const options = props.firelensConfig.options; diff --git a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts index e7d9dea86e828..c485c566912b4 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts @@ -2768,17 +2768,15 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, - restartPolicy: { - ignoredExitCodes: [1, 2, 3], - restartAttemptPeriod: cdk.Duration.seconds(360), - }, + enableRestartPolicy: true, + restartIgnoredExitCodes: [1, 2, 3], + restartAttemptPeriod: cdk.Duration.seconds(360), }); // THEN Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', { ContainerDefinitions: [ { - Essential: true, Image: '/aws/aws-example-app', Name: 'Container', RestartPolicy: { @@ -2791,7 +2789,7 @@ describe('container definition', () => { }); }); - test('can specify restart policy with an empty object', () => { + test('ignore restart policy when enableRestartPolicy is set to false', () => { // GIVEN const stack = new cdk.Stack(); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); @@ -2800,42 +2798,65 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, - restartPolicy: {}, + enableRestartPolicy: false, + restartIgnoredExitCodes: [1, 2, 3], + restartAttemptPeriod: cdk.Duration.seconds(360), }); // THEN Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', { ContainerDefinitions: [ { - Essential: true, Image: '/aws/aws-example-app', Name: 'Container', - RestartPolicy: { - Enabled: true, - }, + RestartPolicy: Match.absent(), + }, + ], + }); + }); + + test('ignore restart policy when enableRestartPolicy is not specified', () => { + // GIVEN + const stack = new cdk.Stack(); + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + + // WHEN + new ecs.ContainerDefinition(stack, 'Container', { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + taskDefinition, + restartIgnoredExitCodes: [1, 2, 3], + restartAttemptPeriod: cdk.Duration.seconds(360), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', { + ContainerDefinitions: [ + { + Image: '/aws/aws-example-app', + Name: 'Container', + RestartPolicy: Match.absent(), }, ], }); }); - test('throws when there are more than 50 in ignoredExitCodes', () => { + test('throws when there are more than 50 in restartIgnoredExitCodes', () => { // GIVEN const stack = new cdk.Stack(); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); // WHEN - const ignoredExitCodes = Array.from({ length: 51 }, (_, i) => i); + const restartIgnoredExitCodes = Array.from({ length: 51 }, (_, i) => i); // THEN expect(() => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, - restartPolicy: { - ignoredExitCodes, - }, + enableRestartPolicy: true, + restartIgnoredExitCodes, }); - }).toThrow(/Only up to 50 can be specified for ignoredExitCodes, got: 51/); + }).toThrow(/Only up to 50 can be specified for restartIgnoredExitCodes, got: 51/); }); test('throws when restartAttemptPeriod is greater than 1800 seconds', () => { @@ -2848,9 +2869,8 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, - restartPolicy: { - restartAttemptPeriod: cdk.Duration.seconds(1801), - }, + enableRestartPolicy: true, + restartAttemptPeriod: cdk.Duration.seconds(1801), }); }).toThrow(/The restartAttemptPeriod must be between 60 seconds and 1800 seconds, got 1801 seconds/); }); @@ -2865,9 +2885,8 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, - restartPolicy: { - restartAttemptPeriod: cdk.Duration.seconds(59), - }, + enableRestartPolicy: true, + restartAttemptPeriod: cdk.Duration.seconds(59), }); }).toThrow(/The restartAttemptPeriod must be between 60 seconds and 1800 seconds, got 59 seconds/); }); diff --git a/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts b/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts index af8891a51b7ec..6377a62b50281 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts @@ -444,7 +444,7 @@ describe('firelens log driver', () => { }); }); - test('throws when restartPolicy is set', () => { + test('throws when restart policy is enabled', () => { // THEN expect(() => { td.addFirelensLogRouter('log_router', { @@ -452,11 +452,9 @@ describe('firelens log driver', () => { firelensConfig: { type: ecs.FirelensLogRouterType.FLUENTBIT, }, - restartPolicy: { - ignoredExitCodes: [1, 2, 3], - }, + enableRestartPolicy: true, }); - }).toThrow(/Firelens log router container cannot have restartPolicy/); + }).toThrow(/Firelens log router container cannot enable restart policy/); }); }); }); From af0dc1b5dec108ad5f5e52f587678e7c4d5a3369 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:26:36 +0900 Subject: [PATCH 16/21] sample codes sample codes --- .../ec2/integ.task-definition-container-restart-policy.ts | 2 +- packages/aws-cdk-lib/aws-ecs/README.md | 2 +- .../aws-cdk-lib/aws-ecs/test/container-definition.test.ts | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts index d0edf035c2c05..9e1c65360348c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts @@ -10,7 +10,7 @@ const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef', {}); taskDefinition.addContainer('Container', { image: ecs.ContainerImage.fromRegistry('public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest'), enableRestartPolicy: true, - restartIgnoredExitCodes: [1, 2, 3], + restartIgnoredExitCodes: [0, 127], restartAttemptPeriod: cdk.Duration.seconds(360), }); diff --git a/packages/aws-cdk-lib/aws-ecs/README.md b/packages/aws-cdk-lib/aws-ecs/README.md index 0efa1354df967..f44e893b7df5c 100644 --- a/packages/aws-cdk-lib/aws-ecs/README.md +++ b/packages/aws-cdk-lib/aws-ecs/README.md @@ -630,7 +630,7 @@ declare const taskDefinition: ecs.TaskDefinition; taskDefinition.addContainer('container', { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), enableRestartPolicy: true, - restartIgnoredExitCodes: [1, 2, 3], + restartIgnoredExitCodes: [0, 127], restartAttemptPeriod: cdk.Duration.seconds(360), }); ``` diff --git a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts index c485c566912b4..0ee37461bb7f4 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts @@ -2769,7 +2769,7 @@ describe('container definition', () => { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, enableRestartPolicy: true, - restartIgnoredExitCodes: [1, 2, 3], + restartIgnoredExitCodes: [0, 127], restartAttemptPeriod: cdk.Duration.seconds(360), }); @@ -2781,7 +2781,7 @@ describe('container definition', () => { Name: 'Container', RestartPolicy: { Enabled: true, - IgnoredExitCodes: [1, 2, 3], + IgnoredExitCodes: [0, 127], RestartAttemptPeriod: 360, }, }, @@ -2799,7 +2799,7 @@ describe('container definition', () => { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, enableRestartPolicy: false, - restartIgnoredExitCodes: [1, 2, 3], + restartIgnoredExitCodes: [0, 127], restartAttemptPeriod: cdk.Duration.seconds(360), }); @@ -2824,7 +2824,7 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, - restartIgnoredExitCodes: [1, 2, 3], + restartIgnoredExitCodes: [0, 127], restartAttemptPeriod: cdk.Duration.seconds(360), }); From 98e64a61c1bb0185eb7c86f6292cb7e5ce608e5e Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 10 Sep 2024 14:46:10 +0900 Subject: [PATCH 17/21] integ --- ...efaultTestDeployAssert2196C660.assets.json | 19 ++ ...aultTestDeployAssert2196C660.template.json | 36 ++++ ...ition-container-restart-policy.assets.json | 19 ++ ...ion-container-restart-policy.template.json | 88 ++++++++ .../cdk.out | 1 + .../integ.json | 12 ++ .../manifest.json | 119 ++++++++++ .../tree.json | 203 ++++++++++++++++++ ...ask-definition-container-restart-policy.ts | 2 +- .../aws-ecs/lib/container-definition.ts | 8 +- 10 files changed, 502 insertions(+), 5 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/aws-ecs-task-definition-container-restart-policy.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/aws-ecs-task-definition-container-restart-policy.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/tree.json rename packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/{ec2 => base}/integ.task-definition-container-restart-policy.ts (89%) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.assets.json new file mode 100644 index 0000000000000..6f873f91f3dc9 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.5", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/aws-ecs-task-definition-container-restart-policy.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/aws-ecs-task-definition-container-restart-policy.assets.json new file mode 100644 index 0000000000000..0a36b186a379d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/aws-ecs-task-definition-container-restart-policy.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.5", + "files": { + "97915316dcb8359e5f057ea5fcf4f55ce45085f3ffe49edde0737f593ef80c7d": { + "source": { + "path": "aws-ecs-task-definition-container-restart-policy.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "97915316dcb8359e5f057ea5fcf4f55ce45085f3ffe49edde0737f593ef80c7d.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/aws-ecs-task-definition-container-restart-policy.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/aws-ecs-task-definition-container-restart-policy.template.json new file mode 100644 index 0000000000000..000e8aa4c0573 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/aws-ecs-task-definition-container-restart-policy.template.json @@ -0,0 +1,88 @@ +{ + "Resources": { + "TaskDefTaskRole1EDB4A67": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "TaskDef54694570": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": "public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest", + "Name": "Container", + "RestartPolicy": { + "Enabled": true, + "IgnoredExitCodes": [ + 0, + 127 + ], + "RestartAttemptPeriod": 360 + } + } + ], + "Cpu": "256", + "Family": "awsecstaskdefinitioncontainerrestartpolicyTaskDef3A6394C1", + "Memory": "512", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "TaskDefTaskRole1EDB4A67", + "Arn" + ] + } + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/cdk.out new file mode 100644 index 0000000000000..bd5311dc372de --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.5"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/integ.json new file mode 100644 index 0000000000000..ab004c3c26f32 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.5", + "testCases": { + "TaskDefinitionContainerRestartPolicy/DefaultTest": { + "stacks": [ + "aws-ecs-task-definition-container-restart-policy" + ], + "assertionStack": "TaskDefinitionContainerRestartPolicy/DefaultTest/DeployAssert", + "assertionStackName": "TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/manifest.json new file mode 100644 index 0000000000000..d15a60ddd4315 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/manifest.json @@ -0,0 +1,119 @@ +{ + "version": "36.0.5", + "artifacts": { + "aws-ecs-task-definition-container-restart-policy.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-ecs-task-definition-container-restart-policy.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-ecs-task-definition-container-restart-policy": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-ecs-task-definition-container-restart-policy.template.json", + "terminationProtection": false, + "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}/97915316dcb8359e5f057ea5fcf4f55ce45085f3ffe49edde0737f593ef80c7d.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-ecs-task-definition-container-restart-policy.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-ecs-task-definition-container-restart-policy.assets" + ], + "metadata": { + "/aws-ecs-task-definition-container-restart-policy/TaskDef/TaskRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TaskDefTaskRole1EDB4A67" + } + ], + "/aws-ecs-task-definition-container-restart-policy/TaskDef/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TaskDef54694570" + } + ], + "/aws-ecs-task-definition-container-restart-policy/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-ecs-task-definition-container-restart-policy/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-ecs-task-definition-container-restart-policy" + }, + "TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.template.json", + "terminationProtection": false, + "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}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "TaskDefinitionContainerRestartPolicyDefaultTestDeployAssert2196C660.assets" + ], + "metadata": { + "/TaskDefinitionContainerRestartPolicy/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/TaskDefinitionContainerRestartPolicy/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "TaskDefinitionContainerRestartPolicy/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/tree.json new file mode 100644 index 0000000000000..3315ebafbd590 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.js.snapshot/tree.json @@ -0,0 +1,203 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-ecs-task-definition-container-restart-policy": { + "id": "aws-ecs-task-definition-container-restart-policy", + "path": "aws-ecs-task-definition-container-restart-policy", + "children": { + "TaskDef": { + "id": "TaskDef", + "path": "aws-ecs-task-definition-container-restart-policy/TaskDef", + "children": { + "TaskRole": { + "id": "TaskRole", + "path": "aws-ecs-task-definition-container-restart-policy/TaskDef/TaskRole", + "children": { + "ImportTaskRole": { + "id": "ImportTaskRole", + "path": "aws-ecs-task-definition-container-restart-policy/TaskDef/TaskRole/ImportTaskRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-ecs-task-definition-container-restart-policy/TaskDef/TaskRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-ecs-task-definition-container-restart-policy/TaskDef/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ECS::TaskDefinition", + "aws:cdk:cloudformation:props": { + "containerDefinitions": [ + { + "essential": true, + "image": "public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest", + "name": "Container", + "restartPolicy": { + "enabled": true, + "ignoredExitCodes": [ + 0, + 127 + ], + "restartAttemptPeriod": 360 + } + } + ], + "cpu": "256", + "family": "awsecstaskdefinitioncontainerrestartpolicyTaskDef3A6394C1", + "memory": "512", + "networkMode": "awsvpc", + "requiresCompatibilities": [ + "FARGATE" + ], + "taskRoleArn": { + "Fn::GetAtt": [ + "TaskDefTaskRole1EDB4A67", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Container": { + "id": "Container", + "path": "aws-ecs-task-definition-container-restart-policy/TaskDef/Container", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-ecs-task-definition-container-restart-policy/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-ecs-task-definition-container-restart-policy/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "TaskDefinitionContainerRestartPolicy": { + "id": "TaskDefinitionContainerRestartPolicy", + "path": "TaskDefinitionContainerRestartPolicy", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "TaskDefinitionContainerRestartPolicy/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "TaskDefinitionContainerRestartPolicy/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "TaskDefinitionContainerRestartPolicy/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "TaskDefinitionContainerRestartPolicy/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "TaskDefinitionContainerRestartPolicy/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.ts similarity index 89% rename from packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.ts index 9e1c65360348c..b3b295f64bf43 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/ec2/integ.task-definition-container-restart-policy.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-container-restart-policy.ts @@ -5,7 +5,7 @@ import { IntegTest } from '@aws-cdk/integ-tests-alpha'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecs-task-definition-container-restart-policy'); -const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef', {}); +const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef', {}); taskDefinition.addContainer('Container', { image: ecs.ContainerImage.fromRegistry('public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest'), diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index 1e2066faa33d1..02ecaa2a1058d 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -1536,7 +1536,7 @@ function renderSystemControls(systemControls: SystemControl[]): CfnTaskDefinitio })); } -function renderRestartPolicy(restartIgnoredExitCodes?: number[], restartAttemptPeriod?: cdk.Duration): CfnTaskDefinition.RestartPolicy { +function renderRestartPolicy(restartIgnoredExitCodes?: number[], restartAttemptPeriod?: cdk.Duration): CfnTaskDefinition.RestartPolicyProperty { if (restartIgnoredExitCodes && restartIgnoredExitCodes.length > 50) { throw new Error(`Only up to 50 can be specified for restartIgnoredExitCodes, got: ${restartIgnoredExitCodes.length}`); } @@ -1544,8 +1544,8 @@ function renderRestartPolicy(restartIgnoredExitCodes?: number[], restartAttemptP throw new Error(`The restartAttemptPeriod must be between 60 seconds and 1800 seconds, got ${restartAttemptPeriod.toSeconds()} seconds`); } return { - Enabled: true, - IgnoredExitCodes: restartIgnoredExitCodes, - RestartAttemptPeriod: restartAttemptPeriod?.toSeconds(), + enabled: true, + ignoredExitCodes: restartIgnoredExitCodes, + restartAttemptPeriod: restartAttemptPeriod?.toSeconds(), }; } From 2c599132eab5a98ac11b13bec46f3126ba58e4e0 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:58:11 +0900 Subject: [PATCH 18/21] change validations --- .../aws-ecs/lib/container-definition.ts | 17 +++++++++++------ .../aws-ecs/test/container-definition.test.ts | 9 +++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index 02ecaa2a1058d..3f40bf59122c6 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -628,6 +628,8 @@ export class ContainerDefinition extends Construct { if (props.ulimits) { this.addUlimits(...props.ulimits); } + + this.validateRestartPolicy(props.restartIgnoredExitCodes, props.restartAttemptPeriod); } /** @@ -809,6 +811,15 @@ export class ContainerDefinition extends Construct { }; } + private validateRestartPolicy(restartIgnoredExitCodes?: number[], restartAttemptPeriod?: cdk.Duration) { + if (restartIgnoredExitCodes && restartIgnoredExitCodes.length > 50) { + throw new Error(`Only up to 50 can be specified for restartIgnoredExitCodes, got: ${restartIgnoredExitCodes.length}`); + } + if (restartAttemptPeriod && (restartAttemptPeriod.toSeconds() < 60 || restartAttemptPeriod.toSeconds() > 1800)) { + throw new Error(`The restartAttemptPeriod must be between 60 seconds and 1800 seconds, got ${restartAttemptPeriod.toSeconds()} seconds`); + } + } + /** * Whether this container definition references a specific JSON field of a secret * stored in Secrets Manager. @@ -1537,12 +1548,6 @@ function renderSystemControls(systemControls: SystemControl[]): CfnTaskDefinitio } function renderRestartPolicy(restartIgnoredExitCodes?: number[], restartAttemptPeriod?: cdk.Duration): CfnTaskDefinition.RestartPolicyProperty { - if (restartIgnoredExitCodes && restartIgnoredExitCodes.length > 50) { - throw new Error(`Only up to 50 can be specified for restartIgnoredExitCodes, got: ${restartIgnoredExitCodes.length}`); - } - if (restartAttemptPeriod && (restartAttemptPeriod.toSeconds() < 60 || restartAttemptPeriod.toSeconds() > 1800)) { - throw new Error(`The restartAttemptPeriod must be between 60 seconds and 1800 seconds, got ${restartAttemptPeriod.toSeconds()} seconds`); - } return { enabled: true, ignoredExitCodes: restartIgnoredExitCodes, diff --git a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts index 0ee37461bb7f4..e7a0cf489a6e9 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts @@ -2768,6 +2768,7 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, + memoryLimitMiB: 2048, enableRestartPolicy: true, restartIgnoredExitCodes: [0, 127], restartAttemptPeriod: cdk.Duration.seconds(360), @@ -2779,6 +2780,7 @@ describe('container definition', () => { { Image: '/aws/aws-example-app', Name: 'Container', + Memory: 2048, RestartPolicy: { Enabled: true, IgnoredExitCodes: [0, 127], @@ -2798,6 +2800,7 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, + memoryLimitMiB: 2048, enableRestartPolicy: false, restartIgnoredExitCodes: [0, 127], restartAttemptPeriod: cdk.Duration.seconds(360), @@ -2809,6 +2812,7 @@ describe('container definition', () => { { Image: '/aws/aws-example-app', Name: 'Container', + Memory: 2048, RestartPolicy: Match.absent(), }, ], @@ -2824,6 +2828,7 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, + memoryLimitMiB: 2048, restartIgnoredExitCodes: [0, 127], restartAttemptPeriod: cdk.Duration.seconds(360), }); @@ -2834,6 +2839,7 @@ describe('container definition', () => { { Image: '/aws/aws-example-app', Name: 'Container', + Memory: 2048, RestartPolicy: Match.absent(), }, ], @@ -2853,6 +2859,7 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, + memoryLimitMiB: 2048, enableRestartPolicy: true, restartIgnoredExitCodes, }); @@ -2869,6 +2876,7 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, + memoryLimitMiB: 2048, enableRestartPolicy: true, restartAttemptPeriod: cdk.Duration.seconds(1801), }); @@ -2885,6 +2893,7 @@ describe('container definition', () => { new ecs.ContainerDefinition(stack, 'Container', { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, + memoryLimitMiB: 2048, enableRestartPolicy: true, restartAttemptPeriod: cdk.Duration.seconds(59), }); From 8645f07a1716f6f98d7b09c10531064b565ba465 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:30:47 +0900 Subject: [PATCH 19/21] rosetta --- packages/aws-cdk-lib/aws-ecs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/README.md b/packages/aws-cdk-lib/aws-ecs/README.md index f44e893b7df5c..61fbaae1adab9 100644 --- a/packages/aws-cdk-lib/aws-ecs/README.md +++ b/packages/aws-cdk-lib/aws-ecs/README.md @@ -631,7 +631,7 @@ taskDefinition.addContainer('container', { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), enableRestartPolicy: true, restartIgnoredExitCodes: [0, 127], - restartAttemptPeriod: cdk.Duration.seconds(360), + restartAttemptPeriod: Duration.seconds(360), }); ``` From a5e62b94ebf5841a5dc37afef98d208d7f292634 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:42:27 +0900 Subject: [PATCH 20/21] rm validations for firelens --- .../aws-cdk-lib/aws-ecs/lib/container-definition.ts | 2 -- .../aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts | 5 ----- .../aws-ecs/test/firelens-log-driver.test.ts | 13 ------------- 3 files changed, 20 deletions(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index 3f40bf59122c6..7e4f72fc7d83e 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -390,8 +390,6 @@ export interface ContainerDefinitionOptions { * * When you set up a restart policy, Amazon ECS can restart the container without needing to replace the task. * - * You can't enable a restart policy for a Firelens log router container. - * * @default false * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-restart-policy.html */ diff --git a/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts b/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts index fb7a264cf0a47..ccea834c0a23d 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/firelens-log-router.ts @@ -222,11 +222,6 @@ export class FirelensLogRouter extends ContainerDefinition { */ constructor(scope: Construct, id: string, props: FirelensLogRouterProps) { super(scope, id, props); - - if (props.enableRestartPolicy) { - throw new Error('Firelens log router container cannot enable restart policy'); - } - const options = props.firelensConfig.options; if (options) { if ((options.configFileValue && options.configFileType === undefined) || (options.configFileValue === undefined && options.configFileType)) { diff --git a/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts b/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts index 6377a62b50281..57dda00535cdb 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/firelens-log-driver.test.ts @@ -443,18 +443,5 @@ describe('firelens log driver', () => { ], }); }); - - test('throws when restart policy is enabled', () => { - // THEN - expect(() => { - td.addFirelensLogRouter('log_router', { - image: ecs.obtainDefaultFluentBitECRImage(td, undefined, '2.1.0'), - firelensConfig: { - type: ecs.FirelensLogRouterType.FLUENTBIT, - }, - enableRestartPolicy: true, - }); - }).toThrow(/Firelens log router container cannot enable restart policy/); - }); }); }); From 92f3345f169267b5f0f1e269270f3385f68f55b4 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:57:14 +0900 Subject: [PATCH 21/21] change process if enableRestartPolicy is undefined --- .../aws-ecs/lib/container-definition.ts | 36 ++++++--- .../aws-ecs/test/container-definition.test.ts | 74 +++++++++++++++++-- 2 files changed, 93 insertions(+), 17 deletions(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index 7e4f72fc7d83e..ba028210e0bae 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -390,7 +390,7 @@ export interface ContainerDefinitionOptions { * * When you set up a restart policy, Amazon ECS can restart the container without needing to replace the task. * - * @default false + * @default - false unless `restartIgnoredExitCodes` or `restartAttemptPeriod` is set. * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-restart-policy.html */ readonly enableRestartPolicy?: boolean; @@ -398,7 +398,7 @@ export interface ContainerDefinitionOptions { /** * A list of exit codes that Amazon ECS will ignore and not attempt a restart on. * - * This property is only used if `enableRestartPolicy` is set to true. + * This property can't be used if `enableRestartPolicy` is set to false. * * You can specify a maximum of 50 container exit codes. * @@ -412,7 +412,7 @@ export interface ContainerDefinitionOptions { * A container can be restarted only once every `restartAttemptPeriod` seconds. * If a container isn't able to run for this time period and exits early, it will not be restarted. * - * This property is only used if `enableRestartPolicy` is set to true. + * This property can't be used if `enableRestartPolicy` is set to false. * * You can set a minimum `restartAttemptPeriod` of 60 seconds and a maximum `restartAttemptPeriod` * of 1800 seconds. @@ -627,7 +627,7 @@ export class ContainerDefinition extends Construct { this.addUlimits(...props.ulimits); } - this.validateRestartPolicy(props.restartIgnoredExitCodes, props.restartAttemptPeriod); + this.validateRestartPolicy(props.enableRestartPolicy, props.restartIgnoredExitCodes, props.restartAttemptPeriod); } /** @@ -809,7 +809,10 @@ export class ContainerDefinition extends Construct { }; } - private validateRestartPolicy(restartIgnoredExitCodes?: number[], restartAttemptPeriod?: cdk.Duration) { + private validateRestartPolicy(enableRestartPolicy?: boolean, restartIgnoredExitCodes?: number[], restartAttemptPeriod?: cdk.Duration) { + if (enableRestartPolicy === false && (restartIgnoredExitCodes !== undefined || restartAttemptPeriod !== undefined)) { + throw new Error('The restartIgnoredExitCodes and restartAttemptPeriod cannot be specified if enableRestartPolicy is false'); + } if (restartIgnoredExitCodes && restartIgnoredExitCodes.length > 50) { throw new Error(`Only up to 50 can be specified for restartIgnoredExitCodes, got: ${restartIgnoredExitCodes.length}`); } @@ -920,8 +923,7 @@ export class ContainerDefinition extends Construct { resourceRequirements: (!this.props.gpuCount && this.inferenceAcceleratorResources.length == 0 ) ? undefined : renderResourceRequirements(this.props.gpuCount, this.inferenceAcceleratorResources), systemControls: this.props.systemControls && renderSystemControls(this.props.systemControls), - restartPolicy: this.props.enableRestartPolicy ? - renderRestartPolicy(this.props.restartIgnoredExitCodes, this.props.restartAttemptPeriod) : undefined, + restartPolicy: renderRestartPolicy(this.props.enableRestartPolicy, this.props.restartIgnoredExitCodes, this.props.restartAttemptPeriod), }; } } @@ -1545,10 +1547,22 @@ function renderSystemControls(systemControls: SystemControl[]): CfnTaskDefinitio })); } -function renderRestartPolicy(restartIgnoredExitCodes?: number[], restartAttemptPeriod?: cdk.Duration): CfnTaskDefinition.RestartPolicyProperty { +function renderRestartPolicy( + enableRestartPolicy?: boolean, + restartIgnoredExitCodes?: number[], + restartAttemptPeriod?: cdk.Duration, +): CfnTaskDefinition.RestartPolicyProperty | undefined { + if (enableRestartPolicy === undefined && restartIgnoredExitCodes === undefined && restartAttemptPeriod === undefined) { + return; + } + return { - enabled: true, - ignoredExitCodes: restartIgnoredExitCodes, - restartAttemptPeriod: restartAttemptPeriod?.toSeconds(), + // If `enableRestartPolicy` is undefined, we know that `restartIgnoredExitCodes` or restartAttemptPeriod is specified + // according to the above branch, so we treat `enableRestartPolicy` as true. + // The `validateRestartPolicy` function also ensures that `enableRestartPolicy` is not false if `restartIgnoredExitCodes` + // or `restartAttemptPeriod` is specified, so there is no conflict. + enabled: enableRestartPolicy ?? true, + ignoredExitCodes: restartIgnoredExitCodes, // always undefined if `enabled` is false + restartAttemptPeriod: restartAttemptPeriod?.toSeconds(), // always undefined if `enabled` is false }; } diff --git a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts index e7a0cf489a6e9..191f687089dc8 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts @@ -2791,7 +2791,7 @@ describe('container definition', () => { }); }); - test('ignore restart policy when enableRestartPolicy is set to false', () => { + test('restart policy will not be set if not specified', () => { // GIVEN const stack = new cdk.Stack(); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); @@ -2801,9 +2801,6 @@ describe('container definition', () => { image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), taskDefinition, memoryLimitMiB: 2048, - enableRestartPolicy: false, - restartIgnoredExitCodes: [0, 127], - restartAttemptPeriod: cdk.Duration.seconds(360), }); // THEN @@ -2819,7 +2816,7 @@ describe('container definition', () => { }); }); - test('ignore restart policy when enableRestartPolicy is not specified', () => { + test('enable restart policy when enableRestartPolicy is not specified but restartIgnoredExitCodes is specified', () => { // GIVEN const stack = new cdk.Stack(); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); @@ -2830,6 +2827,34 @@ describe('container definition', () => { taskDefinition, memoryLimitMiB: 2048, restartIgnoredExitCodes: [0, 127], + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', { + ContainerDefinitions: [ + { + Image: '/aws/aws-example-app', + Name: 'Container', + Memory: 2048, + RestartPolicy: { + Enabled: true, + IgnoredExitCodes: [0, 127], + }, + }, + ], + }); + }); + + test('enable restart policy when enableRestartPolicy is not specified but restartAttemptPeriod is specified', () => { + // GIVEN + const stack = new cdk.Stack(); + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + + // WHEN + new ecs.ContainerDefinition(stack, 'Container', { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + taskDefinition, + memoryLimitMiB: 2048, restartAttemptPeriod: cdk.Duration.seconds(360), }); @@ -2840,12 +2865,49 @@ describe('container definition', () => { Image: '/aws/aws-example-app', Name: 'Container', Memory: 2048, - RestartPolicy: Match.absent(), + RestartPolicy: { + Enabled: true, + RestartAttemptPeriod: 360, + }, }, ], }); }); + test('throws when enableRestartPolicy is set to false but restartIgnoredExitCodes is specified', () => { + // GIVEN + const stack = new cdk.Stack(); + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + + // THEN + expect(() => { + new ecs.ContainerDefinition(stack, 'Container', { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + taskDefinition, + memoryLimitMiB: 2048, + enableRestartPolicy: false, + restartIgnoredExitCodes: [0, 127], + }); + }).toThrow(/The restartIgnoredExitCodes and restartAttemptPeriod cannot be specified if enableRestartPolicy is false/); + }); + + test('throws when enableRestartPolicy is set to false but restartAttemptPeriod is specified', () => { + // GIVEN + const stack = new cdk.Stack(); + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + + // THEN + expect(() => { + new ecs.ContainerDefinition(stack, 'Container', { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + taskDefinition, + memoryLimitMiB: 2048, + enableRestartPolicy: false, + restartAttemptPeriod: cdk.Duration.seconds(360), + }); + }).toThrow(/The restartIgnoredExitCodes and restartAttemptPeriod cannot be specified if enableRestartPolicy is false/); + }); + test('throws when there are more than 50 in restartIgnoredExitCodes', () => { // GIVEN const stack = new cdk.Stack();