Skip to content

Commit

Permalink
add platform version validation for ephemeralStorageGiB and pidMode
Browse files Browse the repository at this point in the history
  • Loading branch information
lpizzinidev committed Apr 13, 2024
1 parent 93ff856 commit dd6b0ae
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 11 deletions.
12 changes: 11 additions & 1 deletion packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,15 @@ export class TaskDefinition extends TaskDefinitionBase {
*/
public readonly ephemeralStorageGiB?: number;

/**
* 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.
*/
public readonly pidMode?: PidMode;

/**
* The container definitions.
*/
Expand Down Expand Up @@ -455,6 +464,7 @@ export class TaskDefinition extends TaskDefinitionBase {
}

this.ephemeralStorageGiB = props.ephemeralStorageGiB;
this.pidMode = props.pidMode;

// validate the cpu and memory size for the Windows operation system family.
if (props.runtimePlatform?.operatingSystemFamily?.isWindows()) {
Expand Down Expand Up @@ -487,7 +497,7 @@ export class TaskDefinition extends TaskDefinitionBase {
cpu: props.cpu,
memory: props.memoryMiB,
ipcMode: props.ipcMode,
pidMode: props.pidMode,
pidMode: this.pidMode,
inferenceAccelerators: Lazy.any({
produce: () =>
!isFargateCompatible(this.compatibility) ? this.renderInferenceAccelerators() : undefined,
Expand Down
28 changes: 18 additions & 10 deletions packages/aws-cdk-lib/aws-ecs/lib/fargate/fargate-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,23 @@ export class FargateService extends BaseService implements IFargateService {
throw new Error('Only one of SecurityGroup or SecurityGroups can be populated.');
}

// Platform versions not supporting referencesSecretJsonField, ephemeralStorageGiB, or pidMode on a task definition
const unsupportedPlatformVersions = [
FargatePlatformVersion.VERSION1_0,
FargatePlatformVersion.VERSION1_1,
FargatePlatformVersion.VERSION1_2,
FargatePlatformVersion.VERSION1_3,
];
const isUnsupportedPlatformVersion = props.platformVersion && unsupportedPlatformVersions.includes(props.platformVersion);

if (props.taskDefinition.ephemeralStorageGiB && isUnsupportedPlatformVersion) {
throw new Error(`The ephemeralStorageGiB feature requires platform version ${FargatePlatformVersion.VERSION1_4} or later, got ${props.platformVersion}.`);
}

if (props.taskDefinition.pidMode && isUnsupportedPlatformVersion) {
throw new Error(`The pidMode feature requires platform version ${FargatePlatformVersion.VERSION1_4} or later, got ${props.platformVersion}.`);
}

super(scope, id, {
...props,
desiredCount: props.desiredCount,
Expand All @@ -153,9 +170,7 @@ export class FargateService extends BaseService implements IFargateService {
}

this.node.addValidation({
validate: () => this.taskDefinition.referencesSecretJsonField
&& props.platformVersion
&& SECRET_JSON_FIELD_UNSUPPORTED_PLATFORM_VERSIONS.includes(props.platformVersion)
validate: () => this.taskDefinition.referencesSecretJsonField && isUnsupportedPlatformVersion
? [`The task definition of this service uses at least one container that references a secret JSON field. This feature requires platform version ${FargatePlatformVersion.VERSION1_4} or later.`]
: [],
});
Expand Down Expand Up @@ -214,10 +229,3 @@ export enum FargatePlatformVersion {
*/
VERSION1_0 = '1.0.0',
}

const SECRET_JSON_FIELD_UNSUPPORTED_PLATFORM_VERSIONS = [
FargatePlatformVersion.VERSION1_0,
FargatePlatformVersion.VERSION1_1,
FargatePlatformVersion.VERSION1_2,
FargatePlatformVersion.VERSION1_3,
];
87 changes: 87 additions & 0 deletions packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { testDeprecated } from '@aws-cdk/cdk-build-tools';
import { Annotations, Match, Template } from '../../../assertions';
import * as appscaling from '../../../aws-applicationautoscaling';
import * as batch from '../../../aws-batch';
import * as cloudwatch from '../../../aws-cloudwatch';
import * as ec2 from '../../../aws-ec2';
import * as elbv2 from '../../../aws-elasticloadbalancingv2';
Expand Down Expand Up @@ -685,6 +686,92 @@ describe('fargate service', () => {
}).toThrow(/one essential container/);
});

test('errors when platform version does not support containers which references secret JSON field', () => {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'MyVpc', {});
const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef', {
runtimePlatform: {
operatingSystemFamily: ecs.OperatingSystemFamily.LINUX,
cpuArchitecture: ecs.CpuArchitecture.ARM64,
},
memoryLimitMiB: 512,
cpu: 256,
});

// Errors on validation, not on construction.
new ecs.FargateService(stack, 'FargateService', {
cluster,
taskDefinition,
platformVersion: ecs.FargatePlatformVersion.VERSION1_2,
});

taskDefinition.addContainer('main', {
image: ecs.ContainerImage.fromRegistry('somecontainer'),
secrets: {
envName: batch.Secret.fromSecretsManager(new secretsmanager.Secret(stack, 'testSecret'), 'secretField'),
},
});

// THEN
expect(() => {
Template.fromStack(stack);
}).toThrow(/This feature requires platform version/);
});

test('errors when platform version does not support ephemeralStorageGiB', () => {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'MyVpc', {});
const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef', {
runtimePlatform: {
operatingSystemFamily: ecs.OperatingSystemFamily.LINUX,
cpuArchitecture: ecs.CpuArchitecture.ARM64,
},
memoryLimitMiB: 512,
cpu: 256,
ephemeralStorageGiB: 100,
});

// WHEN
// THEN
expect(() => {
new ecs.FargateService(stack, 'FargateService', {
cluster,
taskDefinition,
platformVersion: ecs.FargatePlatformVersion.VERSION1_2,
});
}).toThrow(/The ephemeralStorageGiB feature requires platform version/);
});

test('errors when platform version does not support pidMode', () => {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'MyVpc', {});
const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef', {
runtimePlatform: {
operatingSystemFamily: ecs.OperatingSystemFamily.LINUX,
cpuArchitecture: ecs.CpuArchitecture.ARM64,
},
memoryLimitMiB: 512,
cpu: 256,
pidMode: ecs.PidMode.HOST,
});

// WHEN
// THEN
expect(() => {
new ecs.FargateService(stack, 'FargateService', {
cluster,
taskDefinition,
platformVersion: ecs.FargatePlatformVersion.VERSION1_2,
});
}).toThrow(/The pidMode feature requires platform version/);
});

test('allows adding the default container after creating the service', () => {
// GIVEN
const stack = new cdk.Stack();
Expand Down

0 comments on commit dd6b0ae

Please sign in to comment.