From bd10ce045cc3b7f7537651ca4f3efb08033c8cbc Mon Sep 17 00:00:00 2001 From: Clay Rosenthal Date: Mon, 10 Mar 2025 14:24:45 -0700 Subject: [PATCH] feat(ec2): Adding placementGroup prop to LaunchTemplate Signed-off-by: Clay Rosenthal --- .../aws-ec2/lib/launch-template.ts | 14 +++++- .../aws-ec2/test/launch-template.test.ts | 47 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts b/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts index 756cda646ce35..f7d0a76029d53 100644 --- a/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts +++ b/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts @@ -4,6 +4,7 @@ import { CfnLaunchTemplate } from './ec2.generated'; import { InstanceType } from './instance-types'; import { IKeyPair } from './key-pair'; import { IMachineImage, MachineImageConfig, OperatingSystemType } from './machine-image'; +import { IPlacementGroup } from './placement-group'; import { launchTemplateBlockDeviceMappings } from './private/ebs-util'; import { ISecurityGroup } from './security-group'; import { UserData } from './user-data'; @@ -441,6 +442,13 @@ export interface LaunchTemplateProps { * @default - No instance profile */ readonly instanceProfile?: iam.IInstanceProfile; + + /** + * The placement group that you want to launch the instance into. + * + * @default - no placement group will be used for this launch template. + */ + readonly placementGroup?: IPlacementGroup; } /** @@ -783,6 +791,9 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr userData: userDataToken, metadataOptions: this.renderMetadataOptions(props), networkInterfaces, + placement: props.placementGroup ? { + groupName: props.placementGroup.placementGroupName, + } : undefined, // Fields not yet implemented: // ========================== @@ -811,7 +822,8 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr // Should be implemented via the Tagging aspect in CDK core. Complication will be that this tagging interface is very unique to LaunchTemplates. // tagSpecification: undefined - // CDK has no abstraction for Placement yet. + // CDK only has placement groups, not placement. + // Specifiying options other than placementGroup is not supported yet. // placement: undefined, }, diff --git a/packages/aws-cdk-lib/aws-ec2/test/launch-template.test.ts b/packages/aws-cdk-lib/aws-ec2/test/launch-template.test.ts index d277cdaaf1bbc..5807388493a7b 100644 --- a/packages/aws-cdk-lib/aws-ec2/test/launch-template.test.ts +++ b/packages/aws-cdk-lib/aws-ec2/test/launch-template.test.ts @@ -28,6 +28,8 @@ import { LaunchTemplate, LaunchTemplateHttpTokens, OperatingSystemType, + PlacementGroup, + PlacementGroupStrategy, SecurityGroup, SpotInstanceInterruption, SpotRequestType, @@ -889,6 +891,51 @@ describe('LaunchTemplate', () => { }, }); }); + + test('Given placementGroup', () => { + // GIVEN + const pg = new PlacementGroup(stack, 'PlacementGroup', { + strategy: PlacementGroupStrategy.CLUSTER, + }); + + // WHEN + new LaunchTemplate(stack, 'Template', { + placementGroup: pg, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::EC2::LaunchTemplate', { + LaunchTemplateData: { + Placement: { + GroupName: { + 'Fn::GetAtt': [ + 'PlacementGroup68E91A0F', + 'GroupName', + ], + }, + }, + }, + }); + }); + + test('Given imported placementGroup', () => { + // GIVEN + const importedPg = PlacementGroup.fromPlacementGroupName(stack, 'ImportedPlacementGroup', 'my-placement-group'); + + // WHEN + new LaunchTemplate(stack, 'Template', { + placementGroup: importedPg, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::EC2::LaunchTemplate', { + LaunchTemplateData: { + Placement: { + GroupName: 'my-placement-group', + }, + }, + }); + }); }); describe('LaunchTemplate marketOptions', () => {