From c3f339d76c657216a7149909be9556ebe06a2b5a Mon Sep 17 00:00:00 2001 From: Xia Zhao <78883180+xazhao@users.noreply.github.com> Date: Mon, 29 Jan 2024 17:10:13 -0800 Subject: [PATCH] =?UTF-8?q?feat(batch):=20add=20fargate=20Runtime=20Platfo?= =?UTF-8?q?rm=20properties=20to=20ECS=20Fargate=20C=E2=80=A6=20(#28841)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The property [RuntimePlatform](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-batch-jobdefinition-containerproperties.html#cfn-batch-jobdefinition-containerproperties-runtimeplatform) is not present in the AWS Batch ECS Fargate Job Definition. This PR adds flatten properties fargateCpuArchitecture and fargateOperatingSystemFamily to the ECS Fargate Job Definition in AWS Batch. Closes #26484. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...efaultTestDeployAssertE5BAAC9B.assets.json | 2 +- .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 11 ++++-- .../stack.assets.json | 6 ++-- .../stack.template.json | 6 +++- .../tree.json | 20 ++++++----- .../test/integ.ecs-job-definition.ts | 2 ++ packages/aws-cdk-lib/aws-batch/README.md | 15 ++++++++ .../aws-batch/lib/ecs-container-definition.ts | 36 +++++++++++++++++++ .../aws-batch/test/ecs-job-definition.test.ts | 21 +++++++++++ 11 files changed, 105 insertions(+), 18 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets.json index e4db2badc242c..0dee86e8f3ad8 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets.json @@ -1,5 +1,5 @@ { - "version": "32.0.0", + "version": "36.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/cdk.out index f0b901e7c06e5..1f0068d32659a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"32.0.0"} \ No newline at end of file +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/integ.json index 6039a8d046450..15cfdc292a2cf 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "32.0.0", + "version": "36.0.0", "testCases": { "BatchEcsJobDefinitionTest/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/manifest.json index f03b75f4b6728..d4e5db68eb0de 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "32.0.0", + "version": "36.0.0", "artifacts": { "stack.assets": { "type": "cdk:asset-manifest", @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "stack.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}/44f37496af0bd2235d6a2c7ceed3f438eb5fa8c898a3d4b7773bd7fdb113b176.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/80ca79d29007dc0a645c6568c47e0730a748e22b27eaba47a7336b97d459edcc.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -246,7 +247,10 @@ "/stack/ECSFargateJobDefn/Resource": [ { "type": "aws:cdk:logicalId", - "data": "ECSFargateJobDefn327BE725" + "data": "ECSFargateJobDefn327BE725", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] } ], "/stack/EcsDockerContainer/ExecutionRole/Resource": [ @@ -295,6 +299,7 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.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}", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/stack.assets.json index 979f37004cfdc..be9330c4ed096 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/stack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/stack.assets.json @@ -1,7 +1,7 @@ { - "version": "32.0.0", + "version": "36.0.0", "files": { - "44f37496af0bd2235d6a2c7ceed3f438eb5fa8c898a3d4b7773bd7fdb113b176": { + "80ca79d29007dc0a645c6568c47e0730a748e22b27eaba47a7336b97d459edcc": { "source": { "path": "stack.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "44f37496af0bd2235d6a2c7ceed3f438eb5fa8c898a3d4b7773bd7fdb113b176.json", + "objectKey": "80ca79d29007dc0a645c6568c47e0730a748e22b27eaba47a7336b97d459edcc.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/stack.template.json index 11f2f5d11a342..07857e0e45000 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/stack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/stack.template.json @@ -828,7 +828,11 @@ "Type": "VCPU", "Value": "16" } - ] + ], + "RuntimePlatform": { + "CpuArchitecture": "ARM64", + "OperatingSystemFamily": "LINUX" + } }, "JobDefinitionName": "foofoo", "Parameters": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/tree.json index f1c82c6fd1f5c..a6452a3856934 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.js.snapshot/tree.json @@ -1033,7 +1033,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-batch-alpha.EcsEc2ContainerDefinition", + "fqn": "aws-cdk-lib.aws_batch.EcsEc2ContainerDefinition", "version": "0.0.0" } }, @@ -1173,7 +1173,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-batch-alpha.EcsJobDefinition", + "fqn": "aws-cdk-lib.aws_batch.EcsJobDefinition", "version": "0.0.0" } }, @@ -1295,7 +1295,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-batch-alpha.EcsFargateContainerDefinition", + "fqn": "aws-cdk-lib.aws_batch.EcsFargateContainerDefinition", "version": "0.0.0" } }, @@ -1337,6 +1337,10 @@ }, "networkConfiguration": { "assignPublicIp": "DISABLED" + }, + "runtimePlatform": { + "cpuArchitecture": "ARM64", + "operatingSystemFamily": "LINUX" } }, "jobDefinitionName": "foofoo", @@ -1380,7 +1384,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-batch-alpha.EcsJobDefinition", + "fqn": "aws-cdk-lib.aws_batch.EcsJobDefinition", "version": "0.0.0" } }, @@ -1564,7 +1568,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-batch-alpha.EcsEc2ContainerDefinition", + "fqn": "aws-cdk-lib.aws_batch.EcsEc2ContainerDefinition", "version": "0.0.0" } }, @@ -1616,7 +1620,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-batch-alpha.EcsJobDefinition", + "fqn": "aws-cdk-lib.aws_batch.EcsJobDefinition", "version": "0.0.0" } }, @@ -1655,7 +1659,7 @@ "path": "BatchEcsJobDefinitionTest/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.55" + "version": "10.3.0" } }, "DeployAssert": { @@ -1701,7 +1705,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.55" + "version": "10.3.0" } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.ts index e29af1f658043..ec2ac7fdeaec8 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.ecs-job-definition.ts @@ -60,6 +60,8 @@ new batch.EcsJobDefinition(stack, 'ECSFargateJobDefn', { memory: Size.mebibytes(32768), ephemeralStorageSize: Size.gibibytes(100), fargatePlatformVersion: FargatePlatformVersion.LATEST, + fargateCpuArchitecture: ecs.CpuArchitecture.ARM64, + fargateOperatingSystemFamily: ecs.OperatingSystemFamily.LINUX, }), jobDefinitionName: 'foofoo', parameters: { diff --git a/packages/aws-cdk-lib/aws-batch/README.md b/packages/aws-cdk-lib/aws-batch/README.md index a579bd0bc2386..1a2acd741c867 100644 --- a/packages/aws-cdk-lib/aws-batch/README.md +++ b/packages/aws-cdk-lib/aws-batch/README.md @@ -479,6 +479,21 @@ jobDefn.container.addVolume(batch.EcsVolume.efs({ })); ``` +### Running an ECS workflow with Fargate container + +```ts +const jobDefn = new batch.EcsJobDefinition(this, 'JobDefn', { + container: new batch.EcsFargateContainerDefinition(this, 'myFargateContainer', { + image: ecs.ContainerImage.fromRegistry('public.ecr.aws/amazonlinux/amazonlinux:latest'), + memory: cdk.Size.mebibytes(2048), + cpu: 256, + ephemeralStorageSize: cdk.Size.gibibytes(100), + fargateCpuArchitecture: ecs.CpuArchitecture.ARM64, + fargateOperatingSystemFamily: ecs.OperatingSystemFamily.LINUX, + }), +}); +``` + ### Secrets You can expose SecretsManager Secret ARNs or SSM Parameters to your container as environment variables. diff --git a/packages/aws-cdk-lib/aws-batch/lib/ecs-container-definition.ts b/packages/aws-cdk-lib/aws-batch/lib/ecs-container-definition.ts index 136adedc77a0d..8d5369d7c88d9 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/ecs-container-definition.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/ecs-container-definition.ts @@ -979,6 +979,20 @@ export interface IEcsFargateContainerDefinition extends IEcsContainerDefinition * @default - 20 GiB */ readonly ephemeralStorageSize?: Size; + + /** + * The vCPU architecture of Fargate Runtime. + * + * @default - X86_64 + */ + readonly fargateCpuArchitecture?: ecs.CpuArchitecture; + + /** + * The operating system for the compute environment. + * + * @default - LINUX + */ + readonly fargateOperatingSystemFamily?: ecs.OperatingSystemFamily; } /** @@ -1009,6 +1023,20 @@ export interface EcsFargateContainerDefinitionProps extends EcsContainerDefiniti * @default - 20 GiB */ readonly ephemeralStorageSize?: Size; + + /** + * The vCPU architecture of Fargate Runtime. + * + * @default - X86_64 + */ + readonly fargateCpuArchitecture?: ecs.CpuArchitecture; + + /** + * The operating system for the compute environment. + * + * @default - LINUX + */ + readonly fargateOperatingSystemFamily?: ecs.OperatingSystemFamily; } /** @@ -1018,12 +1046,16 @@ export class EcsFargateContainerDefinition extends EcsContainerDefinitionBase im public readonly fargatePlatformVersion?: ecs.FargatePlatformVersion; public readonly assignPublicIp?: boolean; public readonly ephemeralStorageSize?: Size; + public readonly fargateCpuArchitecture?: ecs.CpuArchitecture; + public readonly fargateOperatingSystemFamily?: ecs.OperatingSystemFamily; constructor(scope: Construct, id: string, props: EcsFargateContainerDefinitionProps) { super(scope, id, props); this.assignPublicIp = props.assignPublicIp; this.fargatePlatformVersion = props.fargatePlatformVersion; this.ephemeralStorageSize = props.ephemeralStorageSize; + this.fargateCpuArchitecture = props.fargateCpuArchitecture; + this.fargateOperatingSystemFamily = props.fargateOperatingSystemFamily; // validates ephemeralStorageSize is within limits if (props.ephemeralStorageSize) { @@ -1050,6 +1082,10 @@ export class EcsFargateContainerDefinition extends EcsContainerDefinitionBase im networkConfiguration: { assignPublicIp: this.assignPublicIp ? 'ENABLED' : 'DISABLED', }, + runtimePlatform: { + cpuArchitecture: this.fargateCpuArchitecture?._cpuArchitecture, + operatingSystemFamily: this.fargateOperatingSystemFamily?._operatingSystemFamily, + }, }; }; } diff --git a/packages/aws-cdk-lib/aws-batch/test/ecs-job-definition.test.ts b/packages/aws-cdk-lib/aws-batch/test/ecs-job-definition.test.ts index 20b2caadec4d9..9967bb09f688e 100644 --- a/packages/aws-cdk-lib/aws-batch/test/ecs-job-definition.test.ts +++ b/packages/aws-cdk-lib/aws-batch/test/ecs-job-definition.test.ts @@ -63,6 +63,27 @@ test('EcsJobDefinition uses Compatibility.FARGATE for Fargate containers', () => }); }); +test('EcsJobDefinition uses runtimePlatform for Fargate containers', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new EcsJobDefinition(stack, 'ECSJobDefn', { + container: new EcsFargateContainerDefinition(stack, 'EcsContainer', { + cpu: 256, + image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), + memory: Size.mebibytes(2048), + fargateCpuArchitecture: ecs.CpuArchitecture.ARM64, + fargateOperatingSystemFamily: ecs.OperatingSystemFamily.LINUX, + }), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Batch::JobDefinition', { + PlatformCapabilities: [Compatibility.FARGATE], + }); +}); + test('can be imported from ARN', () => { // GIVEN const stack = new Stack();