Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ec2): support placementGroup for ec2.Instance #30293

Merged
merged 14 commits into from
May 22, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { App, Stack } from 'aws-cdk-lib';
import {
Instance, InstanceType, MachineImage, Vpc,
PlacementGroup, PlacementGroupStrategy,
InstanceClass, InstanceSize, SubnetType,
} from 'aws-cdk-lib/aws-ec2';
import * as integ from '@aws-cdk/integ-tests-alpha';

const app = new App();
const stack = new Stack(app, 'ec2-instance-placementgroup-stack');

// create a placementGroup
const pg = new PlacementGroup(stack, 'test-pg', {
strategy: PlacementGroupStrategy.SPREAD,
});

// create a vpc with one public subnet only
const vpc = new Vpc(stack, 'VPC', {
subnetConfiguration: [
{
name: 'public',
subnetType: SubnetType.PUBLIC,
},
],
natGateways: 0,
});

// create a Instance with placementGroup support
new Instance(stack, 'Instance', {
vpc,
instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.NANO),
machineImage: MachineImage.latestAmazonLinux2023(),
placementGroup: pg,
});

new integ.IntegTest(app, 'Ec2InstancePlacementGroup', {
testCases: [stack],
});
15 changes: 15 additions & 0 deletions packages/aws-cdk-lib/aws-ec2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,21 @@ const host = new ec2.BastionHostLinux(this, 'BastionHost', {
});
```

### Placement Group

Specify `placementGroup` to enable the placement group support:

```ts fixture=with-vpc
declare const pg: ec2.PlacementGroup;

new Instance(stack, 'Instance', {
vpc,
instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.NANO),
machineImage: MachineImage.latestAmazonLinux2023(),
placementGroup: pg,
});
```

### Block Devices

To add EBS block device mappings, specify the `blockDevices` property. The following example sets the EBS-backed
Expand Down
9 changes: 9 additions & 0 deletions packages/aws-cdk-lib/aws-ec2/lib/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { InstanceType } from './instance-types';
import { IKeyPair } from './key-pair';
import { CpuCredits } from './launch-template';
import { IMachineImage, OperatingSystemType } from './machine-image';
import { IPlacementGroup } from './placement-group';
import { instanceBlockDeviceMappings } from './private/ebs-util';
import { ISecurityGroup, SecurityGroup } from './security-group';
import { UserData } from './user-data';
Expand Down Expand Up @@ -315,6 +316,13 @@ export interface InstanceProps {
* @default false
*/
readonly ebsOptimized?: boolean;

/**
* The placement group that you want to launch the instance into.
*
* @default - no placement group will be used for this instance.
*/
readonly placementGroup?: IPlacementGroup;
}

/**
Expand Down Expand Up @@ -486,6 +494,7 @@ export class Instance extends Resource implements IInstance {
monitoring: props.detailedMonitoring,
creditSpecification: props.creditSpecification ? { cpuCredits: props.creditSpecification } : undefined,
ebsOptimized: props.ebsOptimized,
placementGroupName: props.placementGroup?.placementGroupName,
});
this.instance.node.addDependency(this.role);

Expand Down
33 changes: 33 additions & 0 deletions packages/aws-cdk-lib/aws-ec2/test/instance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
KeyPair,
KeyPairType,
CpuCredits,
PlacementGroup,
} from '../lib';

let stack: Stack;
Expand Down Expand Up @@ -210,6 +211,38 @@ describe('instance', () => {
PropagateTagsToVolumeOnCreation: true,
});
});
// placementGroup
describe('placementGroup', () => {
test('can set placementGroup', () => {
// WHEN
// create a new placementgroup
const pg1 = new PlacementGroup(stack, 'myPlacementGroup1');
new PlacementGroup(stack, 'myPlacementGroup2');
new Instance(stack, 'Instance1', {
vpc,
machineImage: new AmazonLinuxImage(),
instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.LARGE),
placementGroup: pg1,
});
new Instance(stack, 'Instance2', {
vpc,
machineImage: new AmazonLinuxImage(),
instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.LARGE),
placementGroup: PlacementGroup.fromPlacementGroupName(stack, 'importedPlacementGroup', 'myPlacementGroup2'),
});

const t = Template.fromStack(stack);
// THEN
t.hasResourceProperties('AWS::EC2::Instance', {
PlacementGroupName: {
'Fn::GetAtt': ['myPlacementGroup180969E8B', 'GroupName'],
},
});
t.hasResourceProperties('AWS::EC2::Instance', {
PlacementGroupName: 'myPlacementGroup2',
});
});
});
describe('blockDeviceMappings', () => {
test('can set blockDeviceMappings', () => {
// WHEN
Expand Down
Loading