@@ -34,6 +34,9 @@ WAITER_INTERVAL=1
3434# AutoScaling Standby features at minimum require this version to work.
3535MIN_CLI_VERSION=' 1.3.25'
3636
37+ # Create a flagfile for each deployment
38+ FLAGFILE=" /tmp/asg_codedeploy_flags-$DEPLOYMENT_GROUP_ID -$DEPLOYMENT_ID "
39+
3740# Usage: get_instance_region
3841#
3942# Writes to STDOUT the AWS region as known by the local instance.
@@ -49,6 +52,125 @@ get_instance_region() {
4952
5053AWS_CLI=" aws --region $( get_instance_region) "
5154
55+ # Usage: set_flag <flag>
56+ #
57+ # Writes <flag> to FLAGFILE
58+ set_flag () {
59+ if echo " $1 =true" >> $FLAGFILE ; then
60+ # msg "$1 flag written to $FLAGFILE"
61+ return 0
62+ else
63+ error_exit " $1 flag NOT written to $FLAGFILE "
64+ fi
65+ }
66+
67+ # Usage: get_flag <flag>
68+ #
69+ # Checks if <flag> is true in FLAGFILE
70+ get_flag () {
71+ if [ -e $FLAGFILE ]; then
72+ if grep " $1 =true" $FLAGFILE > /dev/null; then
73+ # msg "$1 flag found in $FLAGFILE"
74+ return 0
75+ else
76+ # msg "$1 flag NOT found in $FLAGFILE"
77+ return 1
78+ fi
79+ else
80+ # FLAGFILE doesn't exist
81+ return 1
82+ fi
83+ }
84+
85+ # Usage: check_suspended_processes
86+ #
87+ # Checks processes suspended on the ASG before beginning and store them in
88+ # the FLAGFILE to avoid resuming afterwards. Also abort if Launch process
89+ # is suspended.
90+ check_suspended_processes () {
91+ # Get suspended processes in an array
92+ local suspended=($( $AWS_CLI autoscaling describe-auto-scaling-groups \
93+ --auto-scaling-group-name " ${asg_name} " \
94+ --query ' AutoScalingGroups[].SuspendedProcesses' \
95+ --output text | awk ' {printf $1" "}' ) )
96+
97+ if [ ${# suspended[@]} -eq 0 ]; then
98+ msg " No processes were suspended on the ASG before starting."
99+ else
100+ msg " This processes were suspended on the ASG before starting: ${suspended[*]} "
101+ fi
102+
103+ # If "Launch" process is suspended abort because we will not be able to recover from StandBy
104+ if [[ " ${suspended[@]} " =~ " Launch" ]]; then
105+ error_exit " 'Launch' process of AutoScaling is suspended which will not allow us to recover the instance from StandBy. Aborting."
106+ fi
107+
108+ for process in ${suspended[@]} ; do
109+ set_flag $process
110+ done
111+ }
112+
113+ # Usage: suspend_processes
114+ #
115+ # Suspend processes known to cause problems during deployments.
116+ # The API call is idempotent so it doesn't matter if any were previously suspended.
117+ suspend_processes () {
118+ local -a processes=(AZRebalance AlarmNotification ScheduledActions ReplaceUnhealthy)
119+
120+ msg " Suspending ${processes[*]} processes"
121+ $AWS_CLI autoscaling suspend-processes \
122+ --auto-scaling-group-name " ${asg_name} " \
123+ --scaling-processes ${processes[@]}
124+ if [ $? != 0 ]; then
125+ error_exit " Failed to suspend ${processes[*]} processes for ASG ${asg_name} . Aborting as this may cause issues."
126+ fi
127+ }
128+
129+ # Usage: resume_processes
130+ #
131+ # Resume processes suspended, except for the one suspended before deployment.
132+ resume_processes () {
133+ local -a processes=(AZRebalance AlarmNotification ScheduledActions ReplaceUnhealthy)
134+ local -a to_resume
135+
136+ for p in ${processes[@]} ; do
137+ if ! get_flag " $p " ; then
138+ to_resume=(" ${to_resume[@]} " " $p " )
139+ fi
140+ done
141+
142+ msg " Resuming ${to_resume[*]} processes"
143+ $AWS_CLI autoscaling resume-processes \
144+ --auto-scaling-group-name " ${asg_name} " \
145+ --scaling-processes ${to_resume[@]}
146+ if [ $? != 0 ]; then
147+ error_exit " Failed to resume ${to_resume[*]} processes for ASG ${asg_name} . Aborting as this may cause issues."
148+ fi
149+ }
150+
151+ # Usage: remove_flagfile
152+ #
153+ # Removes FLAGFILE
154+ remove_flagfile () {
155+ if rm -f $FLAGFILE ; then
156+ msg " Successfully removed flagfile $FLAGFILE "
157+ else
158+ error_exit " Failed to remove flagfile $FLAGFILE ."
159+ fi
160+ }
161+
162+ # Usage: finish_msg
163+ #
164+ # Prints some finishing statistics
165+ finish_msg () {
166+ msg " Finished $( basename $0 ) at $( /bin/date " +%F %T" ) "
167+
168+ end_sec=$( /bin/date +%s.%N)
169+ elapsed_seconds=$( echo " $end_sec - $start_sec " | /usr/bin/bc)
170+
171+ msg " Elapsed time: $elapsed_seconds "
172+ }
173+
52174# Usage: autoscaling_group_name <EC2 instance ID>
53175#
54176# Prints to STDOUT the name of the AutoScaling group this instance is a part of and returns 0. If
@@ -101,25 +223,11 @@ autoscaling_enter_standby() {
101223 return 0
102224 fi
103225
104- msg " Checking to see if ASG ${asg_name} had AZRebalance process suspended previously"
105- local azrebalance_suspended=$( $AWS_CLI autoscaling describe-auto-scaling-groups \
106- --auto-scaling-group-name " ${asg_name} " \
107- --query ' AutoScalingGroups[].SuspendedProcesses' \
108- --output text | grep -c ' AZRebalance' )
109- if [ $azrebalance_suspended -eq 1 ]; then
110- msg " ASG ${asg_name} had AZRebalance suspended, creating flag file /tmp/azrebalanced"
111- # Create a "flag" file to denote that the ASG had AZRebalance enabled
112- touch /tmp/azrebalanced
113- else
114- msg " ASG ${asg_name} didn't have AZRebalance suspended, suspending"
115- $AWS_CLI autoscaling suspend-processes \
116- --auto-scaling-group-name " ${asg_name} " \
117- --scaling-processes AZRebalance
118- if [ $? != 0 ]; then
119- msg " Failed to suspend the AZRebalance process for ASG ${asg_name} . Aborting as this may cause issues."
120- return 1
121- fi
122- fi
226+ msg " Checking ASG ${asg_name} suspended processes"
227+ check_suspended_processes
228+
229+ # Suspend troublesome processes while deploying
230+ suspend_processes
123231
124232 msg " Checking to see if ASG ${asg_name} will let us decrease desired capacity"
125233 local min_desired=$( $AWS_CLI autoscaling describe-auto-scaling-groups \
@@ -143,9 +251,9 @@ autoscaling_enter_standby() {
143251 msg " Failed to reduce ASG ${asg_name} 's minimum size to $new_min . Cannot put this instance into Standby."
144252 return 1
145253 else
146- msg " ASG ${asg_name} 's minimum size has been decremented, creating flag file /tmp/asgmindecremented "
147- # Create a "flag" file to denote that the ASG min has been decremented
148- touch /tmp/ asgmindecremented
254+ msg " ASG ${asg_name} 's minimum size has been decremented, creating flag in file $FLAGFILE "
255+ # Create a "flag" denote that the ASG min has been decremented
256+ set_flag asgmindecremented
149257 fi
150258 fi
151259
@@ -212,7 +320,7 @@ autoscaling_exit_standby() {
212320 return 1
213321 fi
214322
215- if [ -a /tmp/ asgmindecremented ] ; then
323+ if get_flag asgmindecremented; then
216324 local min_desired=$( $AWS_CLI autoscaling describe-auto-scaling-groups \
217325 --auto-scaling-group-name " ${asg_name} " \
218326 --query ' AutoScalingGroups[0].[MinSize, DesiredCapacity]' \
@@ -227,31 +335,20 @@ autoscaling_exit_standby() {
227335 --min-size $new_min )
228336 if [ $? != 0 ]; then
229337 msg " Failed to increase ASG ${asg_name} 's minimum size to $new_min ."
338+ remove_flagfile
230339 return 1
231340 else
232341 msg " Successfully incremented ASG ${asg_name} 's minimum size"
233- msg " Removing /tmp/asgmindecremented flag file"
234- rm -f /tmp/asgmindecremented
235342 fi
236343 else
237344 msg " Auto scaling group was not decremented previously, not incrementing min value"
238345 fi
239346
240- if [ -a /tmp/azrebalanced ]; then
241- msg " ASG ${asg_name} had AZRebalance suspended previously, leaving it suspended"
242- msg " Removing /tmp/azrebalanced flag file"
243- rm -f /tmp/azrebalanced
244- else
245- msg " Resuming AZRebalance process for ASG ${asg_name} "
246- $AWS_CLI autoscaling resume-processes \
247- --auto-scaling-group-name " ${asg_name} " \
248- --scaling-processes AZRebalance
249- if [ $? != 0 ]; then
250- msg " Failed to resume the AZRebalance process for ASG ${asg_name} . This may cause issues!"
251- return 1
252- fi
253- fi
347+ # Resume processes, except for the ones suspended before deployment
348+ resume_processes
254349
350+ # Clean up the FLAGFILE
351+ remove_flagfile
255352 return 0
256353}
257354
0 commit comments