| Server IP : 104.21.21.239 / Your IP : 216.73.217.71 Web Server : Apache/2.4.68 (Amazon Linux) OpenSSL/3.5.5 System : Linux ip-172-31-69-123.ec2.internal 6.1.176-223.369.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Jul 24 13:34:27 UTC 2026 x86_64 User : ec2-user ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /opt/aws-scripts/ |
Upload File : |
#!/bin/bash
# two scenarios - either we have gp2 and we check if we do below defined burst balance
# or we have io1 and then we check current consumption and compare against provisioned values
# we can revert back to gp2 if it's really low or increase iops if needed
# if may be interesting to look into decreasing iops provisioning without switching to gp2
# but let's keep it on the safe side for the time being
# Define basic variables
BurstThreshold=30
StartTime=$(TZ=GMT date +%FT%T -d '20 minutes ago')
EndTime=$(TZ=GMT date +%FT%T)
InstancesToCheck=("webworker")
# function to calculate iops consumption
iops () {
Period=1200
ReadIops="$(printf "%.0f\n" "$(aws cloudwatch get-metric-statistics --metric-name VolumeReadOps --namespace AWS/EBS \
--start-time "$1" --end-time "$2" --period ${Period} --statistics Sum --dimensions Name=VolumeId,Value="$3" \
--query Datapoints[0].Sum)")"
WriteIops="$(printf "%.0f\n" "$(aws cloudwatch get-metric-statistics --metric-name VolumeWriteOps --namespace AWS/EBS \
--start-time "$1" --end-time "$2" --period ${Period} --statistics Sum --dimensions Name=VolumeId,Value="$3" \
--query Datapoints[0].Sum)")"
IopsPerSec=$((${ReadIops}/${Period} + ${WriteIops}/${Period}))
return ${IopsPerSec}
}
for instance in ${InstancesToCheck[@]}; do
echo "---------------------------------"
echo "Checking volume for ${instance}"
# Get admins volume
VolType=$(aws ec2 describe-volumes --filters Name=tag:Name,Values="${instance}" --query 'Volumes[].VolumeType' --output text)
echo "Volume type detected: ${VolType}"
VolId=$(aws ec2 describe-volumes --filters Name=tag:Name,Values="${instance}" --query 'Volumes[].Attachments[].VolumeId' --output text)
if [[ -n ${VolId} ]]; then
if [[ ${VolType} == "gp2" ]]; then
echo "Checking burst balance for volume ${VolId}"
# Check volume balance
Balance="$(printf "%.0f\n" "$(aws cloudwatch get-metric-statistics --metric-name BurstBalance --namespace AWS/EBS \
--start-time "${StartTime}" --end-time "${EndTime}" --period 300 --statistics Average --dimensions Name=VolumeId,Value=${VolId} \
--query Datapoints[0].Average)")"
echo "Current burst balance for volume ${VolId} is ${Balance}"
if [[ "${Balance}" -le "${BurstThreshold}" ]]; then
echo "Balance below the threshold, volume change to io1 with 3000 iops"
Result="$(aws ec2 modify-volume --volume-type io1 --iops 3000 --volume-id "${VolId}")"
echo ${Result}
else
echo "Nothing to do on the volume ${VolId}"
fi
else
iops ${StartTime} ${EndTime} ${VolId}
IopsConsumption=$?
echo "Current average IOPS consumption for volume ${VolId} is equal ${IopsConsumption}"
if [[ "${IopsConsumption}" -le "${BurstThreshold}" ]]; then
Result="$(aws ec2 modify-volume --volume-type gp2 --volume-id "${VolId}")"
echo ${Result}
echo "Volume ${VolId} switched back to gp2"
else
VolIops=$(aws ec2 describe-volumes --filters Name=tag:Name,Values="${instance}" --query 'Volumes[].Iops' --output text)
echo "Current IOPS capacity for ${VolId} is equal ${VolIops}"
MaxIops=$(($VolIops/90*100))
if [[ "${IopsConsumption}" -ge "${MaxIops}" ]]; then
newIops=$((IopsConsumption*2))
Result="$(aws ec2 modify-volume --volume-type io1 --iops ${newIops} --volume-id "${VolId}")"
echo ${Result}
echo "IOPS for volume "{VolId}" increased to ${newIops}"
else
echo "Nothing to do on the volume ${VolId}, max ${MaxIops} has not been reached"
fi
fi
fi
fi
echo "---------------------------------"
done