Skip to content

Commit

Permalink
feat(ec2): support throughput on LaunchTemplate EBS volumes (aws#30716)
Browse files Browse the repository at this point in the history
### Issue # (if applicable)

Fixes aws#24341.

### Reason for this change

You currently can't specify `throughput` on LaunchTemplate EBS volumes.

### Description of changes

This support was simply not included in ec2 when it was added to autoscaling in aws#22441. I have copied that PR's implementation implementation to ec2 and similarly adapted its tests.

### Description of how you validated changes

Unit and integration tests.

### 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*
  • Loading branch information
isker authored and xazhao committed Sep 12, 2024
1 parent 7ccca8d commit f8221f9
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 56 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@
"Type": "AWS::EC2::LaunchTemplate",
"Properties": {
"LaunchTemplateData": {
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"Throughput": 250,
"VolumeSize": 15,
"VolumeType": "gp3"
}
}
],
"MetadataOptions": {
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "enabled",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ const lt = new ec2.LaunchTemplate(stack, 'LT', {
httpTokens: ec2.LaunchTemplateHttpTokens.REQUIRED,
instanceMetadataTags: true,
securityGroup: sg1,
blockDevices: [{
deviceName: '/dev/xvda',
volume: ec2.BlockDeviceVolume.ebs(15, {
volumeType: ec2.EbsDeviceVolumeType.GP3,
throughput: 250,
}),
}],
});

const sg2 = new ec2.SecurityGroup(stack, 'sg2', {
Expand Down
27 changes: 27 additions & 0 deletions packages/aws-cdk-lib/aws-ec2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,33 @@ new ec2.Instance(this, 'Instance', {

```

To specify the throughput value for `gp3` volumes, use the `throughput` property:

```ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;
declare const machineImage: ec2.IMachineImage;

new ec2.Instance(this, 'Instance', {
vpc,
instanceType,
machineImage,

// ...

blockDevices: [
{
deviceName: '/dev/sda1',
volume: ec2.BlockDeviceVolume.ebs(100, {
volumeType: ec2.EbsDeviceVolumeType.GP3,
throughput: 250,
}),
},
],
});

```

#### EBS Optimized Instances

An Amazon EBS–optimized instance uses an optimized configuration stack and provides additional, dedicated capacity for Amazon EBS I/O. This optimization provides the best performance for your EBS volumes by minimizing contention between Amazon EBS I/O and other traffic from your instance.
Expand Down
25 changes: 24 additions & 1 deletion packages/aws-cdk-lib/aws-ec2/lib/private/ebs-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,29 @@ function synthesizeBlockDeviceMappings<RT, NDT>(construct: Construct, blockDevic

if (ebs) {

const { iops, volumeType, kmsKey, ...rest } = ebs;
const { iops, throughput, volumeType, kmsKey, ...rest } = ebs;

if (throughput) {
if (volumeType !== EbsDeviceVolumeType.GP3) {
throw new Error(`'throughput' requires 'volumeType': ${EbsDeviceVolumeType.GP3}, got: ${volumeType}.`);
}

if (!Number.isInteger(throughput)) {
throw new Error(`'throughput' must be an integer, got: ${throughput}.`);
}

if (throughput < 125 || throughput > 1000) {
throw new Error(`'throughput' must be between 125 and 1000, got ${throughput}.`);
}

const maximumThroughputRatio = 0.25;
if (iops) {
const iopsRatio = (throughput / iops);
if (iopsRatio > maximumThroughputRatio) {
throw new Error(`Throughput (MiBps) to iops ratio of ${iopsRatio} is too high; maximum is ${maximumThroughputRatio} MiBps per iops`);
}
}
}

if (!iops) {
if (volumeType === EbsDeviceVolumeType.IO1 || volumeType === EbsDeviceVolumeType.IO2) {
Expand All @@ -43,6 +65,7 @@ function synthesizeBlockDeviceMappings<RT, NDT>(construct: Construct, blockDevic
finalEbs = {
...rest,
iops,
throughput,
volumeType,
kmsKeyId: kmsKey?.keyArn,
};
Expand Down
Loading

0 comments on commit f8221f9

Please sign in to comment.