Tuesday, 31 May 2016

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
================================================

Wednesday, 25 May 2016

Bash Script to find the exact application or command which consumed high CPU and Memory

#!/bin/bash
#loadavg=$(awk '{ print $1 "\t" $2 "\t" $3 }' /proc/loadavg )
#To find the exact memory used percentage[Used-(Cached+Buffer)]
Memusage=$(printf '%.0f\n' `free | awk 'FNR == 3{print $3/($3+$4)*100}'`)
now=$(date +"%Y-%m-%d %H:%M:%S")
#To find the cpu load average
cpu_load=$(printf '%.0f\n' `uptime | awk '{print $(NF-2)}' | cut -c1-4`)
if [ "$cpu_load" -ge "25" ] || [ "$Memusage" -ge "50" ];then
  echo -e "\n\n=================\t$now\t========================" >> /var/log/top_report
  top -b -c -n1 >> /var/log/top_report
fi