From 3e9e0a8696630c9368adf012aff1fb919e398164 Mon Sep 17 00:00:00 2001 From: Charles Holmes <88447527+CharlesHolmes@users.noreply.github.com> Date: Fri, 10 May 2024 14:12:06 -0500 Subject: [PATCH] fix(ecs): require task pidMode for Linux-based Fargate tasks, not host (#30020) ### Issue # (if applicable) Closes #29995. ### Reason for this change Only the `task` option is allowed for [`pidMode`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-pidmode) on Linux-based Fargate tasks. ### Description of changes This PR builds on the changes introduced in #29670 but fixes the handling of `pidMode` so that it matches the behavior allowed by CloudFormation and described in the [AWS User Guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-pidmode). ### Description of how you validated changes Updated the existing tests so that `task` is the only allowable `pidMode` setting if a Fargate task's OS is Linux-based. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-ecs-integ-runtime.template.json | 2 +- .../aws-ecs/test/fargate/integ.runtime.ts | 2 +- packages/aws-cdk-lib/aws-ecs/README.md | 5 +-- .../aws-ecs/lib/base/task-definition.ts | 13 +++++--- .../lib/fargate/fargate-task-definition.ts | 16 ++++++--- .../aws-ecs/lib/runtime-platform.ts | 11 +++++-- .../test/fargate/fargate-service.test.ts | 2 +- .../fargate/fargate-task-definition.test.ts | 33 +++++++++++++++---- 8 files changed, 63 insertions(+), 21 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/fargate/integ.runtime.js.snapshot/aws-ecs-integ-runtime.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/fargate/integ.runtime.js.snapshot/aws-ecs-integ-runtime.template.json index 0108491f8601d..d28247b3480d7 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/fargate/integ.runtime.js.snapshot/aws-ecs-integ-runtime.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/fargate/integ.runtime.js.snapshot/aws-ecs-integ-runtime.template.json @@ -570,7 +570,7 @@ "Family": "awsecsintegruntimeTaskDefGraviton28E28B263", "Memory": "1024", "NetworkMode": "awsvpc", - "PidMode": "host", + "PidMode": "task", "RequiresCompatibilities": [ "FARGATE" ], diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/fargate/integ.runtime.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/fargate/integ.runtime.ts index 8f224e13e86cd..385ca2e8cdcd2 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/fargate/integ.runtime.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/fargate/integ.runtime.ts @@ -27,7 +27,7 @@ const taskDefinitiongraviton2 = new ecs.FargateTaskDefinition(stack, 'TaskDefGra }, cpu: 256, memoryLimitMiB: 1024, - pidMode: ecs.PidMode.HOST, + pidMode: ecs.PidMode.TASK, }); taskDefinitionwindows.addContainer('windowsservercore', { diff --git a/packages/aws-cdk-lib/aws-ecs/README.md b/packages/aws-cdk-lib/aws-ecs/README.md index 3dcad8549d0a0..f0669e3adcc66 100644 --- a/packages/aws-cdk-lib/aws-ecs/README.md +++ b/packages/aws-cdk-lib/aws-ecs/README.md @@ -372,12 +372,13 @@ const fargateTaskDefinition = new ecs.FargateTaskDefinition(this, 'TaskDef', { }, memoryLimitMiB: 512, cpu: 256, - pidMode: ecs.PidMode.HOST, + pidMode: ecs.PidMode.TASK, }); ``` **Note:** `pidMode` is only supported for tasks that are hosted on AWS Fargate if the tasks are using platform version 1.4.0 -or later (Linux). This isn't supported for Windows containers on Fargate. +or later (Linux). Only the `task` option is supported for Linux containers. `pidMode` isn't supported for Windows containers on Fargate. +If `pidMode` is specified for a Fargate task, then `runtimePlatform.operatingSystemFamily` must also be specified. To add containers to a task definition, call `addContainer()`: diff --git a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts index c079f1aae02a3..7ab075ae777ce 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts @@ -194,8 +194,11 @@ export interface TaskDefinitionProps extends CommonTaskDefinitionProps { * The process namespace to use for the containers in the task. * * Only supported for tasks that are hosted on AWS Fargate if the tasks - * are using platform version 1.4.0 or later (Linux). - * Not supported in Windows containers. + * are using platform version 1.4.0 or later (Linux). Only the TASK option + * is supported for Linux-based Fargate containers. Not supported in Windows + * containers. If pidMode is specified for a Fargate task, then + * runtimePlatform.operatingSystemFamily must also be specified. For more + * information, see [Task Definition Parameters](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_definition_pidmode). * * @default - PidMode used by the task is not specified */ @@ -378,8 +381,10 @@ export class TaskDefinition extends TaskDefinitionBase { * The process namespace to use for the containers in the task. * * Only supported for tasks that are hosted on AWS Fargate if the tasks - * are using platform version 1.4.0 or later (Linux). - * Not supported in Windows containers. + * are using platform version 1.4.0 or later (Linux). Not supported in + * Windows containers. If pidMode is specified for a Fargate task, + * then runtimePlatform.operatingSystemFamily must also be specified. For more + * information, see [Task Definition Parameters](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_definition_pidmode). */ public readonly pidMode?: PidMode; diff --git a/packages/aws-cdk-lib/aws-ecs/lib/fargate/fargate-task-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/fargate/fargate-task-definition.ts index 34d0bed643aa2..e6bc7876daa04 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/fargate/fargate-task-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/fargate/fargate-task-definition.ts @@ -83,8 +83,11 @@ export interface FargateTaskDefinitionProps extends CommonTaskDefinitionProps { * The process namespace to use for the containers in the task. * * Only supported for tasks that are hosted on AWS Fargate if the tasks - * are using platform version 1.4.0 or later (Linux). - * Not supported in Windows containers. + * are using platform version 1.4.0 or later (Linux). Only the TASK option + * is supported for Linux-based Fargate containers. Not supported in + * Windows containers. If pidMode is specified for a Fargate task, then + * runtimePlatform.operatingSystemFamily must also be specified. For more + * information, see [Task Definition Parameters](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_definition_pidmode). * * @default - PidMode used by the task is not specified */ @@ -168,11 +171,16 @@ export class FargateTaskDefinition extends TaskDefinition implements IFargateTas } if (props.pidMode) { + if (!props.runtimePlatform?.operatingSystemFamily) { + throw new Error('Specifying \'pidMode\' requires that operating system family also be provided.'); + } if (props.runtimePlatform?.operatingSystemFamily?.isWindows()) { throw new Error('\'pidMode\' is not supported for Windows containers.'); } - if (!Token.isUnresolved(props.pidMode) && props.pidMode !== PidMode.HOST) { - throw new Error(`\'pidMode\' can only be set to \'${PidMode.HOST}\' for Fargate containers, got: \'${props.pidMode}\'.`); + if (!Token.isUnresolved(props.pidMode) + && props.runtimePlatform?.operatingSystemFamily?.isLinux() + && props.pidMode !== PidMode.TASK) { + throw new Error(`\'pidMode\' can only be set to \'${PidMode.TASK}\' for Linux Fargate containers, got: \'${props.pidMode}\'.`); } } diff --git a/packages/aws-cdk-lib/aws-ecs/lib/runtime-platform.ts b/packages/aws-cdk-lib/aws-ecs/lib/runtime-platform.ts index 250e64a1f9ca4..e5fb42f475d08 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/runtime-platform.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/runtime-platform.ts @@ -90,10 +90,17 @@ export class OperatingSystemFamily { private constructor(public readonly _operatingSystemFamily: string) { } /** - * Returns true if the operating system family is Windows + * Indicates whether the operating system family is Windows */ public isWindows(): boolean { - return this._operatingSystemFamily?.toLowerCase().startsWith('windows') ? true : false; + return this._operatingSystemFamily?.toLowerCase().startsWith('windows'); + } + + /** + * Indicates whether the operating system family is Linux + */ + public isLinux(): boolean { + return this._operatingSystemFamily?.toLowerCase().startsWith('linux'); } } diff --git a/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts b/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts index 0ecd027501019..1775d5ed2eb6e 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts @@ -758,7 +758,7 @@ describe('fargate service', () => { }, memoryLimitMiB: 512, cpu: 256, - pidMode: ecs.PidMode.HOST, + pidMode: ecs.PidMode.TASK, }); // WHEN diff --git a/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-task-definition.test.ts b/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-task-definition.test.ts index def9ba61aaea8..be93c76e2b65e 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-task-definition.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-task-definition.test.ts @@ -60,7 +60,7 @@ describe('fargate task definition', () => { cpuArchitecture: ecs.CpuArchitecture.X86_64, operatingSystemFamily: ecs.OperatingSystemFamily.LINUX, }, - pidMode: ecs.PidMode.HOST, + pidMode: ecs.PidMode.TASK, }); taskDefinition.addVolume({ @@ -85,7 +85,7 @@ describe('fargate task definition', () => { Family: 'myApp', Memory: '1024', NetworkMode: 'awsvpc', - PidMode: 'host', + PidMode: 'task', RequiresCompatibilities: [ ecs.LaunchType.FARGATE, ], @@ -164,6 +164,24 @@ describe('fargate task definition', () => { // THEN }); + test('throws when pidMode is specified without an operating system family', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + // THEN + expect(() => { + new ecs.FargateTaskDefinition(stack, 'FargateTaskDef', { + pidMode: ecs.PidMode.TASK, + runtimePlatform: { + cpuArchitecture: ecs.CpuArchitecture.X86_64, + }, + cpu: 1024, + memoryLimitMiB: 2048, + }); + }).toThrow(/Specifying 'pidMode' requires that operating system family also be provided./); + }); + test('throws when pidMode is specified on Windows', () => { // GIVEN const stack = new cdk.Stack(); @@ -172,7 +190,7 @@ describe('fargate task definition', () => { // THEN expect(() => { new ecs.FargateTaskDefinition(stack, 'FargateTaskDef', { - pidMode: ecs.PidMode.HOST, + pidMode: ecs.PidMode.TASK, runtimePlatform: { operatingSystemFamily: ecs.OperatingSystemFamily.WINDOWS_SERVER_2019_CORE, cpuArchitecture: ecs.CpuArchitecture.X86_64, @@ -183,7 +201,7 @@ describe('fargate task definition', () => { }).toThrow(/'pidMode' is not supported for Windows containers./); }); - test('throws when pidMode is not host', () => { + test('throws when pidMode is not task', () => { // GIVEN const stack = new cdk.Stack(); @@ -191,9 +209,12 @@ describe('fargate task definition', () => { // THEN expect(() => { new ecs.FargateTaskDefinition(stack, 'FargateTaskDef', { - pidMode: ecs.PidMode.TASK, + pidMode: ecs.PidMode.HOST, + runtimePlatform: { + operatingSystemFamily: ecs.OperatingSystemFamily.LINUX, + }, }); - }).toThrow(/'pidMode' can only be set to 'host' for Fargate containers, got: 'task'./); + }).toThrow(/'pidMode' can only be set to 'task' for Linux Fargate containers, got: 'host'./); }); }); describe('When configuredAtLaunch in the Volume', ()=> {