@@ -208,6 +208,20 @@ export interface AutoScalingGroupProps extends CommonAutoScalingGroupProps {
208
208
* @default A role will automatically be created, it can be accessed via the `role` property
209
209
*/
210
210
readonly role ?: iam . IRole ;
211
+
212
+ /**
213
+ * Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes.
214
+ *
215
+ * Each instance that is launched has an associated root device volume,
216
+ * either an Amazon EBS volume or an instance store volume.
217
+ * You can use block device mappings to specify additional EBS volumes or
218
+ * instance store volumes to attach to an instance when it is launched.
219
+ *
220
+ * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html
221
+ *
222
+ * @default - Uses the block device mapping of the AMI
223
+ */
224
+ readonly blockDevices ?: BlockDevice [ ] ;
211
225
}
212
226
213
227
abstract class AutoScalingGroupBase extends Resource implements IAutoScalingGroup {
@@ -416,6 +430,29 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
416
430
userData : userDataToken ,
417
431
associatePublicIpAddress : props . associatePublicIpAddress ,
418
432
spotPrice : props . spotPrice ,
433
+ blockDeviceMappings : ( props . blockDevices !== undefined ? props . blockDevices . map < CfnLaunchConfiguration . BlockDeviceMappingProperty > (
434
+ ( { deviceName, volume, mappingEnabled} ) => {
435
+ const { virtualName, ebsDevice : ebs } = volume ;
436
+
437
+ if ( ebs ) {
438
+ const { iops, volumeType} = ebs ;
439
+
440
+ if ( ! iops ) {
441
+ if ( volumeType === EbsDeviceVolumeType . IO1 ) {
442
+ throw new Error ( 'iops property is required with volumeType: EbsDeviceVolumeType.IO1' ) ;
443
+ }
444
+ } else if ( volumeType !== EbsDeviceVolumeType . IO1 ) {
445
+ this . node . addWarning ( 'iops will be ignored without volumeType: EbsDeviceVolumeType.IO1' ) ;
446
+ }
447
+ }
448
+
449
+ return {
450
+ deviceName,
451
+ ebs,
452
+ virtualName,
453
+ noDevice : mappingEnabled !== undefined ? ! mappingEnabled : undefined ,
454
+ } ;
455
+ } ) : undefined ) ,
419
456
} ) ;
420
457
421
458
launchConfig . node . addDependency ( this . role ) ;
@@ -864,3 +901,159 @@ export interface MetricTargetTrackingProps extends BaseTargetTrackingProps {
864
901
*/
865
902
readonly targetValue : number ;
866
903
}
904
+
905
+ export interface BlockDevice {
906
+ /**
907
+ * The device name exposed to the EC2 instance
908
+ *
909
+ * @example '/dev/sdh', 'xvdh'
910
+ *
911
+ * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html
912
+ */
913
+ readonly deviceName : string ;
914
+
915
+ /**
916
+ * Defines the block device volume, to be either an Amazon EBS volume or an ephemeral instance store volume
917
+ *
918
+ * @example BlockDeviceVolume.ebs(15), BlockDeviceVolume.ephemeral(0)
919
+ *
920
+ */
921
+ readonly volume : BlockDeviceVolume ;
922
+
923
+ /**
924
+ * If false, the device mapping will be suppressed.
925
+ * If set to false for the root device, the instance might fail the Amazon EC2 health check.
926
+ * Amazon EC2 Auto Scaling launches a replacement instance if the instance fails the health check.
927
+ *
928
+ * @default true - device mapping is left untouched
929
+ */
930
+ readonly mappingEnabled ?: boolean ;
931
+ }
932
+
933
+ export interface EbsDeviceOptionsBase {
934
+ /**
935
+ * Indicates whether to delete the volume when the instance is terminated.
936
+ *
937
+ * @default - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
938
+ */
939
+ readonly deleteOnTermination ?: boolean ;
940
+
941
+ /**
942
+ * The number of I/O operations per second (IOPS) to provision for the volume.
943
+ *
944
+ * Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1}
945
+ *
946
+ * The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS,
947
+ * you need at least 100 GiB storage on the volume.
948
+ *
949
+ * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
950
+ */
951
+ readonly iops ?: number ;
952
+
953
+ /**
954
+ * The EBS volume type
955
+ * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
956
+ *
957
+ * @default {@link EbsDeviceVolumeType.GP2 }
958
+ */
959
+ readonly volumeType ?: EbsDeviceVolumeType ;
960
+ }
961
+
962
+ export interface EbsDeviceOptions extends EbsDeviceOptionsBase {
963
+ /**
964
+ * Specifies whether the EBS volume is encrypted.
965
+ * Encrypted EBS volumes can only be attached to instances that support Amazon EBS encryption
966
+ *
967
+ * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#EBSEncryption_supported_instances
968
+ *
969
+ * @default false
970
+ */
971
+ readonly encrypted ?: boolean ;
972
+ }
973
+
974
+ export interface EbsDeviceSnapshotOptions extends EbsDeviceOptionsBase {
975
+ /**
976
+ * The volume size, in Gibibytes (GiB)
977
+ *
978
+ * If you specify volumeSize, it must be equal or greater than the size of the snapshot.
979
+ *
980
+ * @default - The snapshot size
981
+ */
982
+ readonly volumeSize ?: number ;
983
+ }
984
+
985
+ export interface EbsDeviceProps extends EbsDeviceOptionsBase , EbsDeviceSnapshotOptions {
986
+ readonly snapshotId ?: string ;
987
+ }
988
+
989
+ /**
990
+ * Describes a block device mapping for an Auto Scaling group.
991
+ */
992
+ export class BlockDeviceVolume {
993
+ /**
994
+ * Creates a new Elastic Block Storage device
995
+ *
996
+ * @param volumeSize The volume size, in Gibibytes (GiB)
997
+ * @param options additional device options
998
+ */
999
+ public static ebs ( volumeSize : number , options : EbsDeviceOptions = { } ) : BlockDeviceVolume {
1000
+ return new this ( { ...options , volumeSize} ) ;
1001
+ }
1002
+
1003
+ /**
1004
+ * Creates a new Elastic Block Storage device from an existing snapshot
1005
+ *
1006
+ * @param snapshotId The snapshot ID of the volume to use
1007
+ * @param options additional device options
1008
+ */
1009
+ public static ebsFromSnapshot ( snapshotId : string , options : EbsDeviceSnapshotOptions = { } ) : BlockDeviceVolume {
1010
+ return new this ( { ...options , snapshotId} ) ;
1011
+ }
1012
+
1013
+ /**
1014
+ * Creates a virtual, ephemeral device.
1015
+ * The name will be in the form ephemeral{volumeIndex}.
1016
+ *
1017
+ * @param volumeIndex the volume index. Must be equal or greater than 0
1018
+ */
1019
+ public static ephemeral ( volumeIndex : number ) {
1020
+ if ( volumeIndex < 0 ) {
1021
+ throw new Error ( `volumeIndex must be a number starting from 0, got "${ volumeIndex } "` ) ;
1022
+ }
1023
+
1024
+ return new this ( undefined , `ephemeral${ volumeIndex } ` ) ;
1025
+ }
1026
+
1027
+ protected constructor ( public readonly ebsDevice ?: EbsDeviceProps , public readonly virtualName ?: string ) {
1028
+ }
1029
+ }
1030
+
1031
+ /**
1032
+ * Supported EBS volume types for {@link AutoScalingGroupProps.blockDevices}
1033
+ */
1034
+ export enum EbsDeviceVolumeType {
1035
+ /**
1036
+ * Magnetic
1037
+ */
1038
+ STANDARD = 'standard' ,
1039
+
1040
+ /**
1041
+ * Provisioned IOPS SSD
1042
+ */
1043
+ IO1 = 'io1' ,
1044
+
1045
+ /**
1046
+ * General Purpose SSD
1047
+ */
1048
+ GP2 = 'gp2' ,
1049
+
1050
+ /**
1051
+ * Throughput Optimized HDD
1052
+ */
1053
+ ST1 = 'st1' ,
1054
+
1055
+ /**
1056
+ * Cold HDD
1057
+ */
1058
+ SC1 = 'sc1' ,
1059
+ }
0 commit comments