From 80ffce0f9b5d00dc49061e07220fc4e658b6740a Mon Sep 17 00:00:00 2001 From: Mark Whelan <7407040+MrMarkW@users.noreply.github.com> Date: Tue, 24 May 2022 09:40:08 -0500 Subject: [PATCH 1/4] feat: Add support for gp3 iops, throughput --- README.md | 23 +++++++++++++- bin/create-ebs-volume | 33 +++++++++++++------- bin/ebs-autoscale | 19 ++++++------ config/ebs-autoscale.json | 16 +++++----- install.sh | 63 +++++++++++++++++++++++++++++++++++++-- 5 files changed, 124 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index c5c94e7..8099942 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ aws ec2 run-instances --image-id ami-5253c32d \ --iam-instance-profile Name=MyInstanceProfileWithProperPermissions ``` -that installs required packages and runs the initialization script. By default this creates a mount point of `/scratch` on a encrypted 100GB EBS volume. To change the mount point, edit the [cloud-init script](templates/cloud-init-userdata.yaml) file and supply additional options to the install script to suit your specific needs. Install options are shown below. +that installs required packages and runs the initialization script. By default this creates a mount point of `/scratch` on a encrypted 200GB gp3 EBS volume. To change the mount point, edit the [cloud-init script](templates/cloud-init-userdata.yaml) file and supply additional options to the install script to suit your specific needs. Install options are shown below. ```text Install Amazon EBS Autoscale @@ -70,6 +70,27 @@ Options -t, --volume-type VOLUMETYPE EBS volume type to use. (Default: gp3) + --volume-iops VOLUMEIOPS + Volume IOPS for gp3, io1, io2 (default: 3000) + + --volume-throughput VOLUMETHOUGHPUT + Volume throughput for gp3 (default: 125) + + --min-ebs-volume-size SIZE_GB + Mimimum size in GB of new volumes created by the instance. + (Default: 150) + + --max-ebs-volume-size SIZE_GB + Maximum size in GB of new volumes created by the instance. + (Default: 1500) + + --max-total-created-size SIZE_GB + Maximum total size in GB of all volumes created by the instance. + (Default: 8000) + + --max-attached-volumes N + Maximum number of attached volumes. (Default: 16) + ``` ## A note on the IAM Instance Profile diff --git a/bin/create-ebs-volume b/bin/create-ebs-volume index b599069..8f41936 100755 --- a/bin/create-ebs-volume +++ b/bin/create-ebs-volume @@ -44,13 +44,17 @@ Required Options - -t, --type Type of volume. (Default: gp2) + -t, --type Type of volume. (Default: config.volume.type) - -i, --iops IOPS for volume. Only valid if type=io1. (Default: 3000) + -i, --iops N + IOPS for volume. Only valid if type=io1, io2, gp3. (Default: config.volume.iops) + + --throughput N + The throughput for a volume, with a maximum of 1,000 MiB/s. (Default: config.volume.throughput) --not-encrypted Flag to make the volume un-encyrpted. Default is to create an encrypted volume - + --max-total-created-size SIZE_GB Maximum total size in GB of all volumes created by the instance. (Default: config.limits.max_logical_volume_size) @@ -78,8 +82,9 @@ function error() { TYPE=$(get_config_value .volume.type) IOPS=$(get_config_value .volume.iops) +THROUGHPUT=$(get_config_value .volume.throughput) ENCRYPTED=$(get_config_value .volume.encrypted) -MAX_TOTAL_EBS_SIZE=$(get_config_value .limits.max_logical_volume_size) +MAX_LOGICAL_VOLUME_SIZE=$(get_config_value .limits.max_logical_volume_size) MAX_ATTACHED_VOLUMES=$(get_config_value .limits.max_ebs_volume_count) MAX_CREATED_VOLUMES=$MAX_ATTACHED_VOLUMES @@ -99,10 +104,18 @@ while (( "$#" )); do IOPS=$2 shift 2 ;; + --throughput) + THROUGHPUT=$2 + shift 2 + ;; --not-encrypted) unset ENCRYPTED shift ;; + --max-total-created-size) + MAX_LOGICAL_VOLUME_SIZE=$2 + shift 2 + ;; --max-attached-volumes) MAX_ATTACHED_VOLUMES=$2 shift 2 @@ -111,10 +124,6 @@ while (( "$#" )); do MAX_CREATED_VOLUMES=$2 shift 2 ;; - --max-total-created-size) - MAX_TOTAL_EBS_SIZE=$2 - shift 2 - ;; -v|--verbose) VERBOSE=1 shift @@ -227,8 +236,8 @@ function create_and_attach_volume() { done # check how much EBS storage this instance has created - if [ "$total_created_size" -ge "$MAX_TOTAL_EBS_SIZE" ]; then - error "maximum total ebs volume size reached ($MAX_TOTAL_EBS_SIZE)" + if [ "$total_created_size" -ge "$MAX_LOGICAL_VOLUME_SIZE" ]; then + error "maximum total ebs volume size reached ($MAX_LOGICAL_VOLUME_SIZE)" fi # check how many volumes this instance has created @@ -251,7 +260,9 @@ function create_and_attach_volume() { # create the volume local tmpfile=$(mktemp /tmp/ebs-autoscale.create-volume.XXXXXXXXXX) local volume_opts="--size $SIZE --volume-type $TYPE" - if [ "$TYPE" == "io1" ]; then volume_opts="$volume_opts --iops $IOPS"; fi + local IOPS_TYPES = ['io1','io2','gp3'] + if [[ " ${IOPS_TYPES[*]} " =~ " ${TYPE} " ]]; then volume_opts="$volume_opts --iops $IOPS"; fi + if [ "$TYPE" == "gp3" ]; then volume_opts="$volume_opts --throughput $THROUGHPUT"; fi if [ "$ENCRYPTED" == "1" ]; then volume_opts="$volume_opts --encrypted"; fi local timestamp=$(date "+%F %T UTC%z") # YYYY-mm-dd HH:MM:SS UTC+0000 diff --git a/bin/ebs-autoscale b/bin/ebs-autoscale index 17494d2..5d91f6a 100755 --- a/bin/ebs-autoscale +++ b/bin/ebs-autoscale @@ -32,6 +32,7 @@ initialize +MIN_EBS_VOLUME_SIZE=$(get_config_value .limits.min_ebs_volume_size) MAX_EBS_VOLUME_SIZE=$(get_config_value .limits.max_ebs_volume_size) MAX_LOGICAL_VOLUME_SIZE=$(get_config_value .limits.max_logical_volume_size) MAX_EBS_VOLUME_COUNT=$(get_config_value .limits.max_ebs_volume_count) @@ -118,29 +119,29 @@ calc_new_size() { # new volume sizes increase as the number of attached volumes increase local num_devices=$1 #local num_devices=$(get_num_devices) - local new_size=150 + local new_size=$MIN_EBS_VOLUME_SIZE if [ "$num_devices" -ge "4" ] && [ "$num_devices" -le "6" ]; then - if [ "$MAX_EBS_VOLUME_SIZE" -ge "299" ]; then + if [ "$MAX_EBS_VOLUME_SIZE" -ge "299" ] && [ "$MIN_EBS_VOLUME_SIZE" -le "299" ]; then new_size=300 + elif [ "$MIN_EBS_VOLUME_SIZE" -ge "299" ] + new_size=$MIN_EBS_VOLUME_SIZE else new_size=$MAX_EBS_VOLUME_SIZE fi elif [ "$num_devices" -gt "6" ] && [ "$num_devices" -le "10" ]; then - if [ "$MAX_EBS_VOLUME_SIZE" -ge "999" ]; then + if [ "$MAX_EBS_VOLUME_SIZE" -ge "999" ] && [ "$MIN_EBS_VOLUME_SIZE" -le "999" ]; then new_size=1000 + elif [ "$MIN_EBS_VOLUME_SIZE" -ge "999" ] + new_size=$MIN_EBS_VOLUME_SIZE else new_size=$MAX_EBS_VOLUME_SIZE fi elif [ "$num_devices" -gt "10" ]; then - if [ "$MAX_EBS_VOLUME_SIZE" -ge "1499" ]; then - new_size=1500 - else - new_size=$MAX_EBS_VOLUME_SIZE - fi + new_size=$MAX_EBS_VOLUME_SIZE else if [ "$MAX_EBS_VOLUME_SIZE" -ge "149" ]; then - new_size=150 + new_size=$MIN_EBS_VOLUME_SIZE else new_size=$MAX_EBS_VOLUME_SIZE fi diff --git a/config/ebs-autoscale.json b/config/ebs-autoscale.json index 1e62c30..a522d2a 100644 --- a/config/ebs-autoscale.json +++ b/config/ebs-autoscale.json @@ -2,22 +2,24 @@ "mountpoint": "%%MOUNTPOINT%%", "filesystem": "%%FILESYSTEM%%", "lvm": { - "volume_group": "autoscale_vg", - "logical_volume": "autoscale_lv" + "volume_group": "autoscale_vg", + "logical_volume": "autoscale_lv" }, "volume": { "type": "%%VOLUMETYPE%%", - "iops": 3000, + "iops": "%%VOLUMEIOPS%%", + "throughput": "%%VOLUMETHOUGHPUT%%", "encrypted": 1 }, "detection_interval": 2, "limits": { - "max_ebs_volume_size": 1500, - "max_logical_volume_size": 8000, - "max_ebs_volume_count": 16 + "min_ebs_volume_size": "%%MINEBSVOLUMESIZE%%", + "max_ebs_volume_size": "%%MAXEBSVOLUMESIZE%%", + "max_logical_volume_size": "%%MAXLOGICALVOLUMESIZE%%", + "max_ebs_volume_count": "%%MAXATTACHEDVOLUMES%%" }, "logging": { "log_file": "/var/log/ebs-autoscale.log", "log_interval": 300 } -} +} \ No newline at end of file diff --git a/install.sh b/install.sh index 0674c33..6d88d98 100644 --- a/install.sh +++ b/install.sh @@ -56,7 +56,28 @@ Options -t, --volume-type VOLUMETYPE Volume type (default: gp3) - -s, --initial-size SIZE + --volume-iops VOLUMEIOPS + Volume IOPS for gp3, io1, io2 (default: 3000) + + --volume-throughput VOLUMETHOUGHPUT + Volume throughput for gp3 (default: 125) + + --min-ebs-volume-size SIZE_GB + Mimimum size in GB of new volumes created by the instance. + (Default: 150) + + --max-ebs-volume-size SIZE_GB + Maximum size in GB of new volumes created by the instance. + (Default: 1500) + + --max-total-created-size SIZE_GB + Maximum total size in GB of all volumes created by the instance. + (Default: 8000) + + --max-attached-volumes N + Maximum number of attached volumes. (Default: 16) + + -s, --initial-size SIZE_GB Initial size of the volume in GB. (Default: 200) Only used if --initial-device is NOT specified. @@ -64,8 +85,16 @@ EOF ) MOUNTPOINT=/scratch +# defaults to set into ebs-autoscale.json SIZE=200 VOLUMETYPE=gp3 +VOLUMEIOPS=3000 +VOLUMETHOUGHPUT=125 +MIN_EBS_VOLUME_SIZE=150 +MAX_EBS_VOLUME_SIZE=1500 +MAX_LOGICAL_VOLUME_SIZE=8000 +MAX_ATTACHED_VOLUMES=16 + DEVICE="" FILE_SYSTEM=btrfs BASEDIR=$(dirname $0) @@ -87,6 +116,30 @@ while (( "$#" )); do VOLUMETYPE=$2 shift 2 ;; + --volume-iops) + VOLUMEIOPS=$2 + shift 2 + ;; + --volume-throughput) + VOLUMETHOUGHPUT=$2 + shift 2 + ;; + --min-ebs-volume-size) + MIN_EBS_VOLUME_SIZE=$2 + shift 2 + ;; + --max-ebs-volume-size) + MAX_EBS_VOLUME_SIZE=$2 + shift 2 + ;; + --max-total-created-size) + MAX_LOGICAL_VOLUME_SIZE=$2 + shift 2 + ;; + --max-attached-volumes) + MAX_ATTACHED_VOLUMES=$2 + shift 2 + ;; -d|--initial-device) DEVICE=$2 shift 2 @@ -150,7 +203,13 @@ cp ${BASEDIR}/config/ebs-autoscale.logrotate /etc/logrotate.d/ebs-autoscale cat ${BASEDIR}/config/ebs-autoscale.json | \ sed -e "s#%%MOUNTPOINT%%#${MOUNTPOINT}#" | \ sed -e "s#%%VOLUMETYPE%%#${VOLUMETYPE}#" | \ + sed -e "s#%%VOLUMEIOPS%%#${VOLUMEIOPS}#" | \ + sed -e "s#%%VOLUMETHOUGHPUT%%#${VOLUMETHOUGHPUT}#" | \ sed -e "s#%%FILESYSTEM%%#${FILE_SYSTEM}#" \ + sed -e "s#%%MINEBSVOLUMESIZE%%#${MIN_EBS_VOLUME_SIZE}#" \ + sed -e "s#%%MAXEBSVOLUMESIZE%%#${MAX_EBS_VOLUME_SIZE}#" \ + sed -e "s#%%MAXLOGICALVOLUMESIZE%%#${MAX_LOGICAL_VOLUME_SIZE}#" \ + sed -e "s#%%MAXATTACHEDVOLUMES%%#${MAX_ATTACHED_VOLUMES}#" \ > /etc/ebs-autoscale.json ## Create filesystem @@ -163,7 +222,7 @@ fi # If a device is not given, or if the device is not valid if [ -z "${DEVICE}" ] || [ ! -b "${DEVICE}" ]; then - DEVICE=$(create-ebs-volume --size $SIZE --type $VOLUMETYPE) + DEVICE=$(create-ebs-volume --size $SIZE) fi # create and mount the BTRFS filesystem From db009b9d76eb7b77467540d9ec1c53635b65965a Mon Sep 17 00:00:00 2001 From: Bryan Lajoie Date: Mon, 1 Aug 2022 20:43:21 -0700 Subject: [PATCH 2/4] fix gp3 autoscale --- bin/create-ebs-volume | 2 +- install.sh | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/create-ebs-volume b/bin/create-ebs-volume index 8f41936..db23f7f 100755 --- a/bin/create-ebs-volume +++ b/bin/create-ebs-volume @@ -260,7 +260,7 @@ function create_and_attach_volume() { # create the volume local tmpfile=$(mktemp /tmp/ebs-autoscale.create-volume.XXXXXXXXXX) local volume_opts="--size $SIZE --volume-type $TYPE" - local IOPS_TYPES = ['io1','io2','gp3'] + local IOPS_TYPES=( io1 io2 gp3 ) if [[ " ${IOPS_TYPES[*]} " =~ " ${TYPE} " ]]; then volume_opts="$volume_opts --iops $IOPS"; fi if [ "$TYPE" == "gp3" ]; then volume_opts="$volume_opts --throughput $THROUGHPUT"; fi if [ "$ENCRYPTED" == "1" ]; then volume_opts="$volume_opts --encrypted"; fi diff --git a/install.sh b/install.sh index 6d88d98..ce245a6 100644 --- a/install.sh +++ b/install.sh @@ -205,10 +205,10 @@ cat ${BASEDIR}/config/ebs-autoscale.json | \ sed -e "s#%%VOLUMETYPE%%#${VOLUMETYPE}#" | \ sed -e "s#%%VOLUMEIOPS%%#${VOLUMEIOPS}#" | \ sed -e "s#%%VOLUMETHOUGHPUT%%#${VOLUMETHOUGHPUT}#" | \ - sed -e "s#%%FILESYSTEM%%#${FILE_SYSTEM}#" \ - sed -e "s#%%MINEBSVOLUMESIZE%%#${MIN_EBS_VOLUME_SIZE}#" \ - sed -e "s#%%MAXEBSVOLUMESIZE%%#${MAX_EBS_VOLUME_SIZE}#" \ - sed -e "s#%%MAXLOGICALVOLUMESIZE%%#${MAX_LOGICAL_VOLUME_SIZE}#" \ + sed -e "s#%%FILESYSTEM%%#${FILE_SYSTEM}#" | \ + sed -e "s#%%MINEBSVOLUMESIZE%%#${MIN_EBS_VOLUME_SIZE}#" | \ + sed -e "s#%%MAXEBSVOLUMESIZE%%#${MAX_EBS_VOLUME_SIZE}#" | \ + sed -e "s#%%MAXLOGICALVOLUMESIZE%%#${MAX_LOGICAL_VOLUME_SIZE}#" | \ sed -e "s#%%MAXATTACHEDVOLUMES%%#${MAX_ATTACHED_VOLUMES}#" \ > /etc/ebs-autoscale.json @@ -222,7 +222,7 @@ fi # If a device is not given, or if the device is not valid if [ -z "${DEVICE}" ] || [ ! -b "${DEVICE}" ]; then - DEVICE=$(create-ebs-volume --size $SIZE) + DEVICE=$(create-ebs-volume --size $SIZE --type $VOLUMETYPE) fi # create and mount the BTRFS filesystem From 21c5074ba4e1eb73444d38b980e3e6876eed505b Mon Sep 17 00:00:00 2001 From: Bryan Lajoie Date: Fri, 9 Sep 2022 16:56:18 -0700 Subject: [PATCH 3/4] fix typo in bash, elif --- bin/ebs-autoscale | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/ebs-autoscale b/bin/ebs-autoscale index 5d91f6a..33edcb6 100755 --- a/bin/ebs-autoscale +++ b/bin/ebs-autoscale @@ -124,7 +124,7 @@ calc_new_size() { if [ "$num_devices" -ge "4" ] && [ "$num_devices" -le "6" ]; then if [ "$MAX_EBS_VOLUME_SIZE" -ge "299" ] && [ "$MIN_EBS_VOLUME_SIZE" -le "299" ]; then new_size=300 - elif [ "$MIN_EBS_VOLUME_SIZE" -ge "299" ] + elif [ "$MIN_EBS_VOLUME_SIZE" -ge "299" ]; then new_size=$MIN_EBS_VOLUME_SIZE else new_size=$MAX_EBS_VOLUME_SIZE @@ -132,7 +132,7 @@ calc_new_size() { elif [ "$num_devices" -gt "6" ] && [ "$num_devices" -le "10" ]; then if [ "$MAX_EBS_VOLUME_SIZE" -ge "999" ] && [ "$MIN_EBS_VOLUME_SIZE" -le "999" ]; then new_size=1000 - elif [ "$MIN_EBS_VOLUME_SIZE" -ge "999" ] + elif [ "$MIN_EBS_VOLUME_SIZE" -ge "999" ]; then new_size=$MIN_EBS_VOLUME_SIZE else new_size=$MAX_EBS_VOLUME_SIZE From 3d2a656c3e2cba7643b115602f17a283ddb5abb6 Mon Sep 17 00:00:00 2001 From: Bryan Lajoie Date: Wed, 14 Sep 2022 16:30:54 -0700 Subject: [PATCH 4/4] adding support for --initial-utilization-threshold, to limit scalining if desired --- bin/ebs-autoscale | 5 +++-- config/ebs-autoscale.json | 3 ++- install.sh | 11 ++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/bin/ebs-autoscale b/bin/ebs-autoscale index 33edcb6..05325ee 100755 --- a/bin/ebs-autoscale +++ b/bin/ebs-autoscale @@ -36,6 +36,7 @@ MIN_EBS_VOLUME_SIZE=$(get_config_value .limits.min_ebs_volume_size) MAX_EBS_VOLUME_SIZE=$(get_config_value .limits.max_ebs_volume_size) MAX_LOGICAL_VOLUME_SIZE=$(get_config_value .limits.max_logical_volume_size) MAX_EBS_VOLUME_COUNT=$(get_config_value .limits.max_ebs_volume_count) +INITIAL_UTILIZATION_THRESHOLD=$(get_config_value .limits.initial_utilization_threshold) FILE_SYSTEM=$(get_config_value .filesystem) @@ -99,7 +100,7 @@ calc_threshold() { # as more ebs volumes are added, the threshold level increases local num_devices=$1 - local threshold=50 + local threshold=${INITIAL_UTILIZATION_THRESHOLD} if [ "$num_devices" -ge "4" ] && [ "$num_devices" -le "6" ]; then threshold=80 @@ -108,7 +109,7 @@ calc_threshold() { elif [ "$num_devices" -gt "10" ]; then threshold=90 else - threshold=50 + threshold=${INITIAL_UTILIZATION_THRESHOLD} fi echo ${threshold} diff --git a/config/ebs-autoscale.json b/config/ebs-autoscale.json index a522d2a..a8507de 100644 --- a/config/ebs-autoscale.json +++ b/config/ebs-autoscale.json @@ -16,7 +16,8 @@ "min_ebs_volume_size": "%%MINEBSVOLUMESIZE%%", "max_ebs_volume_size": "%%MAXEBSVOLUMESIZE%%", "max_logical_volume_size": "%%MAXLOGICALVOLUMESIZE%%", - "max_ebs_volume_count": "%%MAXATTACHEDVOLUMES%%" + "max_ebs_volume_count": "%%MAXATTACHEDVOLUMES%%", + "initial_utilization_threshold": "%%INITIALUTILIZATIONTHRESHOLD%%" }, "logging": { "log_file": "/var/log/ebs-autoscale.log", diff --git a/install.sh b/install.sh index ce245a6..c4e933c 100644 --- a/install.sh +++ b/install.sh @@ -77,6 +77,9 @@ Options --max-attached-volumes N Maximum number of attached volumes. (Default: 16) + --initial-utilization-threshold N + Initial disk utilization treshold for scale-up. (Default: 50) + -s, --initial-size SIZE_GB Initial size of the volume in GB. (Default: 200) Only used if --initial-device is NOT specified. @@ -94,6 +97,7 @@ MIN_EBS_VOLUME_SIZE=150 MAX_EBS_VOLUME_SIZE=1500 MAX_LOGICAL_VOLUME_SIZE=8000 MAX_ATTACHED_VOLUMES=16 +INITIAL_UTILIZATION_THRESHOLD=50 DEVICE="" FILE_SYSTEM=btrfs @@ -140,6 +144,10 @@ while (( "$#" )); do MAX_ATTACHED_VOLUMES=$2 shift 2 ;; + --initial-utilization-threshold) + INITIAL_UTILIZATION_THRESHOLD=$2 + shift 2 + ;; -d|--initial-device) DEVICE=$2 shift 2 @@ -209,7 +217,8 @@ cat ${BASEDIR}/config/ebs-autoscale.json | \ sed -e "s#%%MINEBSVOLUMESIZE%%#${MIN_EBS_VOLUME_SIZE}#" | \ sed -e "s#%%MAXEBSVOLUMESIZE%%#${MAX_EBS_VOLUME_SIZE}#" | \ sed -e "s#%%MAXLOGICALVOLUMESIZE%%#${MAX_LOGICAL_VOLUME_SIZE}#" | \ - sed -e "s#%%MAXATTACHEDVOLUMES%%#${MAX_ATTACHED_VOLUMES}#" \ + sed -e "s#%%MAXATTACHEDVOLUMES%%#${MAX_ATTACHED_VOLUMES}#" | \ + sed -e "s#%%INITIALUTILIZATIONTHRESHOLD%%#${INITIAL_UTILIZATION_THRESHOLD}#" \ > /etc/ebs-autoscale.json ## Create filesystem