Frequently update the AMI or Instance-Type in AWS Autoscaling group
If your instances running under AWS autoscaling, then instances will always use the same AMI or Instance-Type which configured in launch configuration.
If you installed new packages or did any changes in instance root volume, then you need to take new AMI from that instance[root volume] and need to update that AMI in Autoscaling group[using launch configuration]. But it will require many manual steps.
So I created a Bash script and it will do that task automatically.
Example 1:-
If you want to just update the AMI in Autoscaling group, run the script like below.
#./script.sh <Autoscaling Group Name> <Launch Configuration Name> <AWS Region>
Example 2:-
If you want to update both instance type and AMI in Autoscaling group, run the script like below.
#./script.sh <Autoscaling Group Name> <Launch Configuration Name> <AWS Region> <Instance Type>
====================================
#!/bin/bash
AutoscalingGroupName=$1
LaunchConfigurationName=$2
Region=$3
InstanceType=$4
DATE=`date "+%Y-%m-%d_%H-%M"`
#############Creating AMI from Autoscaling instance root volume ####################
Instanceid=`aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name ${AutoscalingGroupName} --region $Region --query AutoScalingGroups[].Instances[].InstanceId --output text`
#echo "Autoscaling Instance Id is $Instanceid"
NewAMIid=`/usr/bin/aws ec2 create-image --instance-id $Instanceid --region us-east-1 --name "${AutoscalingGroupName}-Autoscaling-${DATE}" --description ${AutoscalingGroupName} --no-reboot --block-device-mappings "[{\"DeviceName\": \"/dev/sdf\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdg\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdh\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdi\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdj\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdk\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdl\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdm\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdn\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdo\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdp\",\"NoDevice\":\"\"}]" | grep -oP 'ami-\S+' | cut -d'"' -f1`
#echo "New AMI ID which created using package updated autoscaling instance = $NewAMIid"
###################Update an Autoscalingsroup with launch configuration which have updated AMI####################
## Note: It will not affect running instances in autoscaling group. The changes will apply on next instance failover #####
UpdateAutoscalingGroup() {
aws autoscaling update-auto-scaling-group --auto-scaling-group-name ${AutoscalingGroupName} --launch-configuration-name $1 --region $Region
}
###################Create an Launch configuration##########################
DeviceName=`aws autoscaling describe-launch-configurations --launch-configuration-names ${LaunchConfigurationName} --region $Region --query LaunchConfigurations[].BlockDeviceMappings[0].DeviceName --output text`
EbsVolumeType=`aws autoscaling describe-launch-configurations --launch-configuration-names ${LaunchConfigurationName} --region $Region --query LaunchConfigurations[].BlockDeviceMappings[0].Ebs.VolumeType --output text`
EbsVolumeSize=`aws autoscaling describe-launch-configurations --launch-configuration-names ${LaunchConfigurationName} --region $Region --query LaunchConfigurations[].BlockDeviceMappings[0].Ebs.VolumeSize --output text`
aws autoscaling create-launch-configuration --launch-configuration-name ${LaunchConfigurationName}-Copy --instance-id $Instanceid --image-id $NewAMIid --block-device-mappings "[{\"DeviceName\": \"$DeviceName\",\"Ebs\":{\"VolumeSize\":$EbsVolumeSize,\"VolumeType\":\"$EbsVolumeType\",\"DeleteOnTermination\":false}}]" --region $Region
##################Update an Autoscalingsroup with copied launch configuration#########################
aws ec2 wait image-available --image-ids $NewAMIid --region $Region
UpdateAutoscalingGroup ${LaunchConfigurationName}-Copy
##############Deregister an AMI and also remove the associated snapshot based on Description################
OldAMIid=`aws autoscaling describe-launch-configurations --launch-configuration-names ${LaunchConfigurationName} --region $Region --query LaunchConfigurations[].ImageId --output text`
OldAMIsnapid=`aws ec2 describe-images --image-id $OldAMIid --region $Region --query Images[].BlockDeviceMappings[0].Ebs.SnapshotId --output text`
aws ec2 deregister-image --image-id $OldAMIid --region $Region 2>/dev/null 1>&2 && aws ec2 delete-snapshot --snapshot-id $OldAMIsnapid --region $Region 2>/dev/null 1>&2
#####################Delete an Old Launch configuration and Rename the copied Launch configuration to Old name again######################
aws autoscaling delete-launch-configuration --launch-configuration-name ${LaunchConfigurationName} --region $Region
if [ -z "$InstanceType" ]
then
aws autoscaling create-launch-configuration --launch-configuration-name ${LaunchConfigurationName} --instance-id $Instanceid --image-id $NewAMIid --block-device-mappings "[{\"DeviceName\": \"$DeviceName\",\"Ebs\":{\"VolumeSize\":$EbsVolumeSize,\"VolumeType\":\"$EbsVolumeType\",\"DeleteOnTermination\":false}}]" --region $Region
else
aws autoscaling create-launch-configuration --launch-configuration-name ${LaunchConfigurationName} --instance-id $Instanceid --image-id $NewAMIid --instance-type $InstanceType --block-device-mappings "[{\"DeviceName\": \"$DeviceName\",\"Ebs\":{\"VolumeSize\":$EbsVolumeSize,\"VolumeType\":\"$EbsVolumeType\",\"DeleteOnTermination\":false}}]" --region $Region
fi
UpdateAutoscalingGroup ${LaunchConfigurationName}
aws autoscaling delete-launch-configuration --launch-configuration-name ${LaunchConfigurationName}-Copy --region $Region
================================================
If you installed new packages or did any changes in instance root volume, then you need to take new AMI from that instance[root volume] and need to update that AMI in Autoscaling group[using launch configuration]. But it will require many manual steps.
So I created a Bash script and it will do that task automatically.
Example 1:-
If you want to just update the AMI in Autoscaling group, run the script like below.
#./script.sh <Autoscaling Group Name> <Launch Configuration Name> <AWS Region>
Example 2:-
If you want to update both instance type and AMI in Autoscaling group, run the script like below.
#./script.sh <Autoscaling Group Name> <Launch Configuration Name> <AWS Region> <Instance Type>
====================================
#!/bin/bash
AutoscalingGroupName=$1
LaunchConfigurationName=$2
Region=$3
InstanceType=$4
DATE=`date "+%Y-%m-%d_%H-%M"`
#############Creating AMI from Autoscaling instance root volume ####################
Instanceid=`aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name ${AutoscalingGroupName} --region $Region --query AutoScalingGroups[].Instances[].InstanceId --output text`
#echo "Autoscaling Instance Id is $Instanceid"
NewAMIid=`/usr/bin/aws ec2 create-image --instance-id $Instanceid --region us-east-1 --name "${AutoscalingGroupName}-Autoscaling-${DATE}" --description ${AutoscalingGroupName} --no-reboot --block-device-mappings "[{\"DeviceName\": \"/dev/sdf\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdg\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdh\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdi\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdj\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdk\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdl\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdm\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdn\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdo\",\"NoDevice\":\"\"},{\"DeviceName\": \"/dev/sdp\",\"NoDevice\":\"\"}]" | grep -oP 'ami-\S+' | cut -d'"' -f1`
#echo "New AMI ID which created using package updated autoscaling instance = $NewAMIid"
###################Update an Autoscalingsroup with launch configuration which have updated AMI####################
## Note: It will not affect running instances in autoscaling group. The changes will apply on next instance failover #####
UpdateAutoscalingGroup() {
aws autoscaling update-auto-scaling-group --auto-scaling-group-name ${AutoscalingGroupName} --launch-configuration-name $1 --region $Region
}
###################Create an Launch configuration##########################
DeviceName=`aws autoscaling describe-launch-configurations --launch-configuration-names ${LaunchConfigurationName} --region $Region --query LaunchConfigurations[].BlockDeviceMappings[0].DeviceName --output text`
EbsVolumeType=`aws autoscaling describe-launch-configurations --launch-configuration-names ${LaunchConfigurationName} --region $Region --query LaunchConfigurations[].BlockDeviceMappings[0].Ebs.VolumeType --output text`
EbsVolumeSize=`aws autoscaling describe-launch-configurations --launch-configuration-names ${LaunchConfigurationName} --region $Region --query LaunchConfigurations[].BlockDeviceMappings[0].Ebs.VolumeSize --output text`
aws autoscaling create-launch-configuration --launch-configuration-name ${LaunchConfigurationName}-Copy --instance-id $Instanceid --image-id $NewAMIid --block-device-mappings "[{\"DeviceName\": \"$DeviceName\",\"Ebs\":{\"VolumeSize\":$EbsVolumeSize,\"VolumeType\":\"$EbsVolumeType\",\"DeleteOnTermination\":false}}]" --region $Region
##################Update an Autoscalingsroup with copied launch configuration#########################
aws ec2 wait image-available --image-ids $NewAMIid --region $Region
UpdateAutoscalingGroup ${LaunchConfigurationName}-Copy
##############Deregister an AMI and also remove the associated snapshot based on Description################
OldAMIid=`aws autoscaling describe-launch-configurations --launch-configuration-names ${LaunchConfigurationName} --region $Region --query LaunchConfigurations[].ImageId --output text`
OldAMIsnapid=`aws ec2 describe-images --image-id $OldAMIid --region $Region --query Images[].BlockDeviceMappings[0].Ebs.SnapshotId --output text`
aws ec2 deregister-image --image-id $OldAMIid --region $Region 2>/dev/null 1>&2 && aws ec2 delete-snapshot --snapshot-id $OldAMIsnapid --region $Region 2>/dev/null 1>&2
#####################Delete an Old Launch configuration and Rename the copied Launch configuration to Old name again######################
aws autoscaling delete-launch-configuration --launch-configuration-name ${LaunchConfigurationName} --region $Region
if [ -z "$InstanceType" ]
then
aws autoscaling create-launch-configuration --launch-configuration-name ${LaunchConfigurationName} --instance-id $Instanceid --image-id $NewAMIid --block-device-mappings "[{\"DeviceName\": \"$DeviceName\",\"Ebs\":{\"VolumeSize\":$EbsVolumeSize,\"VolumeType\":\"$EbsVolumeType\",\"DeleteOnTermination\":false}}]" --region $Region
else
aws autoscaling create-launch-configuration --launch-configuration-name ${LaunchConfigurationName} --instance-id $Instanceid --image-id $NewAMIid --instance-type $InstanceType --block-device-mappings "[{\"DeviceName\": \"$DeviceName\",\"Ebs\":{\"VolumeSize\":$EbsVolumeSize,\"VolumeType\":\"$EbsVolumeType\",\"DeleteOnTermination\":false}}]" --region $Region
fi
UpdateAutoscalingGroup ${LaunchConfigurationName}
aws autoscaling delete-launch-configuration --launch-configuration-name ${LaunchConfigurationName}-Copy --region $Region
================================================
Nice explanation with examples keep update AWS Online Training
ReplyDelete