Skip to content

Commit

Permalink
Merge branch 'main' into 22184-r2
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Nov 25, 2022
2 parents 7196f1c + d13b64a commit a86ee31
Show file tree
Hide file tree
Showing 15 changed files with 654 additions and 30 deletions.
30 changes: 30 additions & 0 deletions packages/@aws-cdk/aws-autoscaling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,36 @@ autoScalingGroup.scaleOnSchedule('AllowDownscalingAtNight', {
});
```

### Block Devices

This type specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes.

#### GP3 Volumes

You can only specify the `throughput` on GP3 volumes.

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

const autoScalingGroup = new autoscaling.AutoScalingGroup(this, 'ASG', {
vpc,
instanceType,
machineImage,
blockDevices: [{
{
deviceName: 'gp3-volume',
volume: autoscaling.BlockDeviceVolume.ebs(15, {
volumeType: autoscaling.EbsDeviceVolumeType.GP3,
throughput: 125,
}),
},
}],
// ...
});
```

## Configuring Instances using CloudFormation Init

It is possible to use the CloudFormation Init mechanism to configure the
Expand Down
26 changes: 25 additions & 1 deletion packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2167,7 +2167,31 @@ function synthesizeBlockDeviceMappings(construct: Construct, blockDevices: Block
}

if (ebs) {
const { iops, volumeType } = ebs;
const { iops, volumeType, throughput } = ebs;

if (throughput) {
const throughputRange = { Min: 125, Max: 1000 };
const { Min, Max } = throughputRange;

if (volumeType != EbsDeviceVolumeType.GP3) {
throw new Error('throughput property requires volumeType: EbsDeviceVolumeType.GP3');
}

if (throughput < Min || throughput > Max) {
throw new Error(
`throughput property takes a minimum of ${Min} and a maximum of ${Max}`,
);
}

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) {
Expand Down
8 changes: 8 additions & 0 deletions packages/@aws-cdk/aws-autoscaling/lib/volume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ export interface EbsDeviceOptionsBase {
* @default {@link EbsDeviceVolumeType.GP2}
*/
readonly volumeType?: EbsDeviceVolumeType;

/**
* The throughput that the volume supports, in MiB/s
* Takes a minimum of 125 and maximum of 1000.
* @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
* @default - 125 MiB/s. Only valid on gp3 volumes.
*/
readonly throughput?: number;
}

/**
Expand Down
79 changes: 79 additions & 0 deletions packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,12 @@ describe('auto scaling group', () => {
}, {
deviceName: 'none',
volume: autoscaling.BlockDeviceVolume.noDevice(),
}, {
deviceName: 'gp3-with-throughput',
volume: autoscaling.BlockDeviceVolume.ebs(15, {
volumeType: autoscaling.EbsDeviceVolumeType.GP3,
throughput: 350,
}),
}],
});

Expand Down Expand Up @@ -739,6 +745,14 @@ describe('auto scaling group', () => {
DeviceName: 'none',
NoDevice: true,
},
{
DeviceName: 'gp3-with-throughput',
Ebs: {
VolumeSize: 15,
VolumeType: 'gp3',
Throughput: 350,
},
},
],
});
});
Expand Down Expand Up @@ -809,6 +823,71 @@ describe('auto scaling group', () => {
}).toThrow(/maxInstanceLifetime must be between 1 and 365 days \(inclusive\)/);
});

test.each([124, 1001])('throws if throughput is set less than 125 or more than 1000', (throughput) => {
const stack = new cdk.Stack();
const vpc = mockVpc(stack);

expect(() => {
new autoscaling.AutoScalingGroup(stack, 'MyStack', {
machineImage: new ec2.AmazonLinuxImage(),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO),
vpc,
maxInstanceLifetime: cdk.Duration.days(0),
blockDevices: [{
deviceName: 'ebs',
volume: autoscaling.BlockDeviceVolume.ebs(15, {
volumeType: autoscaling.EbsDeviceVolumeType.GP3,
throughput,
}),
}],
});
}).toThrow(/throughput property takes a minimum of 125 and a maximum of 1000/);
});

test.each([
...Object.values(autoscaling.EbsDeviceVolumeType).filter((v) => v !== 'gp3'),
])('throws if throughput is set on any volume type other than GP3', (volumeType) => {
const stack = new cdk.Stack();
const vpc = mockVpc(stack);

expect(() => {
new autoscaling.AutoScalingGroup(stack, 'MyStack', {
machineImage: new ec2.AmazonLinuxImage(),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO),
vpc,
maxInstanceLifetime: cdk.Duration.days(0),
blockDevices: [{
deviceName: 'ebs',
volume: autoscaling.BlockDeviceVolume.ebs(15, {
volumeType: volumeType,
throughput: 150,
}),
}],
});
}).toThrow(/throughput property requires volumeType: EbsDeviceVolumeType.GP3/);
});

test('throws if throughput / iops ratio is greater than 0.25', () => {
const stack = new cdk.Stack();
const vpc = mockVpc(stack);
expect(() => {
new autoscaling.AutoScalingGroup(stack, 'MyStack', {
machineImage: new ec2.AmazonLinuxImage(),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO),
vpc,
maxInstanceLifetime: cdk.Duration.days(0),
blockDevices: [{
deviceName: 'ebs',
volume: autoscaling.BlockDeviceVolume.ebs(15, {
volumeType: autoscaling.EbsDeviceVolumeType.GP3,
throughput: 751,
iops: 3000,
}),
}],
});
}).toThrow('Throughput (MiBps) to iops ratio of 0.25033333333333335 is too high; maximum is 0.25 MiBps per iops');
});

test('can configure instance monitoring', () => {
// GIVEN
const stack = new cdk.Stack();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"version": "20.0.0",
"version": "21.0.0",
"files": {
"cb1b7cc4cd8286ab836dcbb42f408e2c39d60c34a017d1dac4b998c1891d843b": {
"2ca8f144c3e288148d58c9b9e86c9034f6a72b09cecffac3a5d406f8f53d5b18": {
"source": {
"path": "aws-cdk-asg-integ.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "cb1b7cc4cd8286ab836dcbb42f408e2c39d60c34a017d1dac4b998c1891d843b.json",
"objectKey": "2ca8f144c3e288148d58c9b9e86c9034f6a72b09cecffac3a5d406f8f53d5b18.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,130 @@
"IgnoreUnmodifiedGroupSizeProperties": true
}
}
},
"AsgWithGp3BlockdeviceInstanceSecurityGroup54D76206": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "aws-cdk-asg-integ/AsgWithGp3Blockdevice/InstanceSecurityGroup",
"SecurityGroupEgress": [
{
"CidrIp": "0.0.0.0/0",
"Description": "Allow all outbound traffic by default",
"IpProtocol": "-1"
}
],
"Tags": [
{
"Key": "Name",
"Value": "aws-cdk-asg-integ/AsgWithGp3Blockdevice"
}
],
"VpcId": {
"Ref": "VPCB9E5F0B4"
}
}
},
"AsgWithGp3BlockdeviceInstanceRoleF52FB39B": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
],
"Version": "2012-10-17"
},
"Tags": [
{
"Key": "Name",
"Value": "aws-cdk-asg-integ/AsgWithGp3Blockdevice"
}
]
}
},
"AsgWithGp3BlockdeviceInstanceProfile2FC414A5": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Roles": [
{
"Ref": "AsgWithGp3BlockdeviceInstanceRoleF52FB39B"
}
]
}
},
"AsgWithGp3BlockdeviceLaunchConfig24411F5E": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Properties": {
"ImageId": {
"Ref": "SsmParameterValueawsserviceamiamazonlinuxlatestamznamihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter"
},
"InstanceType": "t3.micro",
"BlockDeviceMappings": [
{
"DeviceName": "ebs",
"Ebs": {
"DeleteOnTermination": true,
"Encrypted": true,
"Throughput": 125,
"VolumeSize": 15,
"VolumeType": "gp3"
}
}
],
"IamInstanceProfile": {
"Ref": "AsgWithGp3BlockdeviceInstanceProfile2FC414A5"
},
"SecurityGroups": [
{
"Fn::GetAtt": [
"AsgWithGp3BlockdeviceInstanceSecurityGroup54D76206",
"GroupId"
]
}
],
"UserData": {
"Fn::Base64": "#!/bin/bash"
}
},
"DependsOn": [
"AsgWithGp3BlockdeviceInstanceRoleF52FB39B"
]
},
"AsgWithGp3BlockdeviceASGE82AA487": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Properties": {
"MaxSize": "10",
"MinSize": "0",
"DesiredCapacity": "5",
"LaunchConfigurationName": {
"Ref": "AsgWithGp3BlockdeviceLaunchConfig24411F5E"
},
"Tags": [
{
"Key": "Name",
"PropagateAtLaunch": true,
"Value": "aws-cdk-asg-integ/AsgWithGp3Blockdevice"
}
],
"VPCZoneIdentifier": [
{
"Ref": "VPCPrivateSubnet1Subnet8BCA10E0"
},
{
"Ref": "VPCPrivateSubnet2SubnetCFCDAA7A"
}
]
},
"UpdatePolicy": {
"AutoScalingScheduledAction": {
"IgnoreUnmodifiedGroupSizeProperties": true
}
}
}
},
"Parameters": {
Expand All @@ -636,6 +760,10 @@
"Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
"Default": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-arm64-gp2"
},
"SsmParameterValueawsserviceamiamazonlinuxlatestamznamihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter": {
"Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
"Default": "/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2"
},
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/cdk-bootstrap/hnb659fds/version",
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"20.0.0"}
{"version":"21.0.0"}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "20.0.0",
"version": "21.0.0",
"testCases": {
"integ.asg-lt": {
"stacks": [
Expand Down
Loading

0 comments on commit a86ee31

Please sign in to comment.