-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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): blockDevice property #4781
Changes from all commits
dd3d349
bc46cf2
9cb186c
ad0f214
3dbc018
8127688
8511de7
775018c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -448,29 +448,12 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements | |
userData: userDataToken, | ||
associatePublicIpAddress: props.associatePublicIpAddress, | ||
spotPrice: props.spotPrice, | ||
blockDeviceMappings: (props.blockDevices !== undefined ? props.blockDevices.map<CfnLaunchConfiguration.BlockDeviceMappingProperty>( | ||
({deviceName, volume, mappingEnabled}) => { | ||
const {virtualName, ebsDevice: ebs} = volume; | ||
|
||
if (ebs) { | ||
const {iops, volumeType} = ebs; | ||
|
||
if (!iops) { | ||
if (volumeType === EbsDeviceVolumeType.IO1) { | ||
throw new Error('iops property is required with volumeType: EbsDeviceVolumeType.IO1'); | ||
} | ||
} else if (volumeType !== EbsDeviceVolumeType.IO1) { | ||
this.node.addWarning('iops will be ignored without volumeType: EbsDeviceVolumeType.IO1'); | ||
} | ||
} | ||
|
||
return { | ||
deviceName, | ||
ebs, | ||
virtualName, | ||
noDevice: mappingEnabled !== undefined ? !mappingEnabled : undefined, | ||
}; | ||
}) : undefined), | ||
blockDeviceMappings: (props.blockDevices !== undefined ? | ||
ec2.synthesizeBlockDeviceMappings(this, props.blockDevices).map<CfnLaunchConfiguration.BlockDeviceMappingProperty>( | ||
({ deviceName, ebs, virtualName, noDevice }) => ({ | ||
deviceName, ebs, virtualName, noDevice: noDevice ? true : false | ||
}) | ||
) : undefined), | ||
}); | ||
|
||
launchConfig.node.addDependency(this.role); | ||
|
@@ -938,158 +921,34 @@ export interface MetricTargetTrackingProps extends BaseTargetTrackingProps { | |
readonly targetValue: number; | ||
} | ||
|
||
export interface BlockDevice { | ||
/** | ||
* The device name exposed to the EC2 instance | ||
* | ||
* @example '/dev/sdh', 'xvdh' | ||
* | ||
* @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html | ||
*/ | ||
readonly deviceName: string; | ||
|
||
/** | ||
* Defines the block device volume, to be either an Amazon EBS volume or an ephemeral instance store volume | ||
* | ||
* @example BlockDeviceVolume.ebs(15), BlockDeviceVolume.ephemeral(0) | ||
* | ||
*/ | ||
readonly volume: BlockDeviceVolume; | ||
|
||
/** | ||
* If false, the device mapping will be suppressed. | ||
* If set to false for the root device, the instance might fail the Amazon EC2 health check. | ||
* Amazon EC2 Auto Scaling launches a replacement instance if the instance fails the health check. | ||
* | ||
* @default true - device mapping is left untouched | ||
*/ | ||
readonly mappingEnabled?: boolean; | ||
} | ||
|
||
export interface EbsDeviceOptionsBase { | ||
/** | ||
* Indicates whether to delete the volume when the instance is terminated. | ||
* | ||
* @default - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS) | ||
*/ | ||
readonly deleteOnTermination?: boolean; | ||
|
||
/** | ||
* The number of I/O operations per second (IOPS) to provision for the volume. | ||
* | ||
* Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1} | ||
* | ||
* The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS, | ||
* you need at least 100 GiB storage on the volume. | ||
* | ||
* @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html | ||
*/ | ||
readonly iops?: number; | ||
|
||
/** | ||
* The EBS volume type | ||
* @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html | ||
* | ||
* @default {@link EbsDeviceVolumeType.GP2} | ||
*/ | ||
readonly volumeType?: EbsDeviceVolumeType; | ||
} | ||
|
||
export interface EbsDeviceOptions extends EbsDeviceOptionsBase { | ||
/** | ||
* Specifies whether the EBS volume is encrypted. | ||
* Encrypted EBS volumes can only be attached to instances that support Amazon EBS encryption | ||
* | ||
* @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#EBSEncryption_supported_instances | ||
* | ||
* @default false | ||
*/ | ||
readonly encrypted?: boolean; | ||
} | ||
|
||
export interface EbsDeviceSnapshotOptions extends EbsDeviceOptionsBase { | ||
/** | ||
* The volume size, in Gibibytes (GiB) | ||
* | ||
* If you specify volumeSize, it must be equal or greater than the size of the snapshot. | ||
* | ||
* @default - The snapshot size | ||
*/ | ||
readonly volumeSize?: number; | ||
} | ||
|
||
export interface EbsDeviceProps extends EbsDeviceSnapshotOptions { | ||
readonly snapshotId?: string; | ||
} | ||
|
||
export class BlockDeviceVolume extends ec2.BlockDeviceVolume {} | ||
export interface BlockDevice extends ec2.BlockDevice {} | ||
export interface EbsDeviceOptions extends ec2.EbsDeviceOptions {} | ||
export interface EbsDeviceOptionsBase extends ec2.EbsDeviceOptionsBase {} | ||
export interface EbsDeviceProps extends ec2.EbsDeviceProps {} | ||
export interface EbsDeviceSnapshotOptions extends ec2.EbsDeviceSnapshotOptions {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's an issue with the interfaces. JSII complains if I attempt to export them:
Copy-pasta time? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. I agree it's not great, but it's practical, and importantly: non-breaking. |
||
/** | ||
* Describes a block device mapping for an Auto Scaling group. | ||
*/ | ||
export class BlockDeviceVolume { | ||
/** | ||
* Creates a new Elastic Block Storage device | ||
* | ||
* @param volumeSize The volume size, in Gibibytes (GiB) | ||
* @param options additional device options | ||
*/ | ||
public static ebs(volumeSize: number, options: EbsDeviceOptions = {}): BlockDeviceVolume { | ||
return new this({...options, volumeSize}); | ||
} | ||
|
||
/** | ||
* Creates a new Elastic Block Storage device from an existing snapshot | ||
* | ||
* @param snapshotId The snapshot ID of the volume to use | ||
* @param options additional device options | ||
*/ | ||
public static ebsFromSnapshot(snapshotId: string, options: EbsDeviceSnapshotOptions = {}): BlockDeviceVolume { | ||
return new this({...options, snapshotId}); | ||
} | ||
|
||
/** | ||
* Creates a virtual, ephemeral device. | ||
* The name will be in the form ephemeral{volumeIndex}. | ||
* | ||
* @param volumeIndex the volume index. Must be equal or greater than 0 | ||
*/ | ||
public static ephemeral(volumeIndex: number) { | ||
if (volumeIndex < 0) { | ||
throw new Error(`volumeIndex must be a number starting from 0, got "${volumeIndex}"`); | ||
} | ||
|
||
return new this(undefined, `ephemeral${volumeIndex}`); | ||
} | ||
|
||
protected constructor(public readonly ebsDevice?: EbsDeviceProps, public readonly virtualName?: string) { | ||
} | ||
} | ||
|
||
/** | ||
* Supported EBS volume types for {@link AutoScalingGroupProps.blockDevices} | ||
* Supported EBS volume types for blockDevices | ||
*/ | ||
export enum EbsDeviceVolumeType { | ||
/** | ||
* Magnetic | ||
*/ | ||
STANDARD = 'standard', | ||
|
||
STANDARD = "standard", | ||
/** | ||
* Provisioned IOPS SSD | ||
*/ | ||
IO1 = 'io1', | ||
|
||
IO1 = "io1", | ||
/** | ||
* General Purpose SSD | ||
*/ | ||
GP2 = 'gp2', | ||
|
||
GP2 = "gp2", | ||
/** | ||
* Throughput Optimized HDD | ||
*/ | ||
ST1 = 'st1', | ||
|
||
ST1 = "st1", | ||
/** | ||
* Cold HDD | ||
*/ | ||
SC1 = 'sc1', | ||
SC1 = "sc1" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not thrilled about this breaking change, but I couldn't find a way to cleanly deprecate
asg.BlockDevice
, as it would require the following type forAutoScalingGroupProps
:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't
asg.BlockDevice
just be more-or-less a copy ofec2.BlockDevice
?I agree, not ideal, but at least not a breaking change.