Skip to content

Instantly share code, notes, and snippets.

@niski84
Created April 23, 2024 20:51
Show Gist options
  • Save niski84/431e10f4d86c8089cac23fd6e9bb45ff to your computer and use it in GitHub Desktop.
Save niski84/431e10f4d86c8089cac23fd6e9bb45ff to your computer and use it in GitHub Desktop.
Delete all ec2's ebs volume and snapshots with option to save last snapshot
package main
import (
"context"
"fmt"
"log"
"sort"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk"
)
func main() {
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
log.Fatalf("Unable to load SDK config, %v", err)
}
// Example usage
if err := deleteEnvironmentVolumes("your-environment-name", true); err != nil {
log.Fatalf("Error: %v", err)
}
}
func deleteEnvironmentVolumes(environmentName string, keepLastSnapshot bool) error {
ebClient := elasticbeanstalk.NewFromConfig(aws.Config{})
ec2Client := ec2.NewFromConfig(aws.Config{})
// Get environment resources
envResources, err := ebClient.DescribeEnvironmentResources(context.TODO(), &elasticbeanstalk.DescribeEnvironmentResourcesInput{
EnvironmentName: &environmentName,
})
if err != nil {
return fmt.Errorf("failed to get environment resources: %w", err)
}
// Loop through instances to get attached EBS volumes
for _, instance := range envResources.EnvironmentResources.Instances {
// Describe the instances to get volume information
descInstancesOutput, err := ec2Client.DescribeInstances(context.TODO(), &ec2.DescribeInstancesInput{
InstanceIds: []string{*instance.Id},
})
if err != nil {
return fmt.Errorf("failed to describe instances: %w", err)
}
for _, reservation := range descInstancesOutput.Reservations {
for _, inst := range reservation.Instances {
for _, blockDevice := range inst.BlockDeviceMappings {
volumeId := *blockDevice.Ebs.VolumeId
// Optionally, find and handle snapshots for the volume
if err := handleSnapshots(ec2Client, volumeId, keepLastSnapshot); err != nil {
log.Printf("Error handling snapshots for volume %s: %v", volumeId, err)
}
// Delete EBS volume
if _, err = ec2Client.DeleteVolume(context.TODO(), &ec2.DeleteVolumeInput{
VolumeId: &volumeId,
}); err != nil {
log.Printf("Failed to delete volume %s: %v", volumeId, err)
} else {
fmt.Printf("Deleted volume %s\n", volumeId)
}
}
}
}
}
return nil
}
func handleSnapshots(ec2Client *ec2.Client, volumeId string, keepLastSnapshot bool) error {
snapshotsOutput, err := ec2Client.DescribeSnapshots(context.TODO(), &ec2.DescribeSnapshotsInput{
Filters: []types.Filter{
{
Name: aws.String("volume-id"),
Values: []string{volumeId},
},
},
})
if err != nil {
return fmt.Errorf("failed to find snapshots for volume %s: %w", volumeId, err)
}
if keepLastSnapshot && len(snapshotsOutput.Snapshots) > 0 {
// Sort snapshots by date, oldest first
sort.Slice(snapshotsOutput.Snapshots, func(i, j int) bool {
return snapshotsOutput.Snapshots[i].StartTime.Before(*snapshotsOutput.Snapshots[j].StartTime)
})
// Remove the last one from the list to keep it
snapshotsOutput.Snapshots = snapshotsOutput.Snapshots[:len(snapshotsOutput.Snapshots)-1]
}
// Delete all snapshots that are not the last one
for _, snapshot := range snapshotsOutput.Snapshots {
if _, err := ec2Client.DeleteSnapshot(context.TODO(), &ec2.DeleteSnapshotInput{
SnapshotId: snapshot.SnapshotId,
}); err != nil {
log.Printf("Failed to delete snapshot %s: %v", *snapshot.SnapshotId, err)
} else {
fmt.Printf("Deleted snapshot %s\n", *snapshot.SnapshotId)
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment