Skip to content

Instantly share code, notes, and snippets.

@subuk
Created May 29, 2018 09:11
Show Gist options
  • Save subuk/36ecf582c456def526259026034bc83e to your computer and use it in GitHub Desktop.
Save subuk/36ecf582c456def526259026034bc83e to your computer and use it in GitHub Desktop.
Terminate aws asg instances with old launch configuration
package main
import (
"flag"
"fmt"
"os"
"time"
"github.com/aws/aws-sdk-go/aws"
aws_session "github.com/aws/aws-sdk-go/aws/session"
aws_autoscaling "github.com/aws/aws-sdk-go/service/autoscaling"
)
func main() {
var asgName string
var terminationPause int
var decrementCapacity bool
flag.IntVar(&terminationPause, "pause", 60, "pause in seconds between instance status set")
flag.BoolVar(&decrementCapacity, "decrement", true, "decrement asg capacity on instance termination")
flag.Parse()
asgName = flag.Arg(0)
if asgName == "" {
fmt.Fprintf(os.Stderr, "autoscaling group name required\n")
os.Exit(1)
}
session := aws_session.Must(aws_session.NewSession(aws.NewConfig().WithRegion("us-east-1")))
autoscaling := aws_autoscaling.New(session)
descAsgInput := &aws_autoscaling.DescribeAutoScalingGroupsInput{
AutoScalingGroupNames: aws.StringSlice([]string{asgName}),
}
asgDescription, err := autoscaling.DescribeAutoScalingGroups(descAsgInput)
if err != nil {
panic(err)
}
if len(asgDescription.AutoScalingGroups) == 0 {
fmt.Fprintf(os.Stderr, "autoscaling group %s not found\n", asgName)
return
}
terminateIds := []string{}
for _, group := range asgDescription.AutoScalingGroups {
fmt.Printf("scanning autoscaling group %s [lc %s]\n", *group.AutoScalingGroupName, *group.LaunchConfigurationName)
for _, instance := range group.Instances {
if *instance.HealthStatus == "Unhealthy" {
continue
}
if *instance.LifecycleState != aws_autoscaling.LifecycleStateInService {
continue
}
if (instance.LaunchConfigurationName == nil) || (*instance.LaunchConfigurationName != *group.LaunchConfigurationName) {
terminateIds = append(terminateIds, *instance.InstanceId)
}
}
}
if len(terminateIds) == 0 {
fmt.Println("all instances have latest launch configuration")
return
}
fmt.Println("the following instances will be terminated")
for _, instanceId := range terminateIds {
fmt.Println(instanceId)
}
userInput := ""
fmt.Printf("confirmation [yes/no]: ")
if _, err := fmt.Scan(&userInput); err != nil {
fmt.Fprintf(os.Stderr, "failed to read user input: %s", err.Error())
}
if userInput != "yes" {
fmt.Println("aborted")
return
}
for _, instanceId := range terminateIds {
input := &aws_autoscaling.TerminateInstanceInAutoScalingGroupInput{
InstanceId: aws.String(instanceId),
ShouldDecrementDesiredCapacity: aws.Bool(decrementCapacity),
}
fmt.Printf("terminating instance %s ... ", instanceId)
_, err := autoscaling.TerminateInstanceInAutoScalingGroup(input)
if err != nil {
panic(err)
}
fmt.Println("done")
fmt.Printf("waiting %d seconds\n", terminationPause)
time.Sleep(time.Second * time.Duration(terminationPause))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment