package common import ( "context" "fmt" "log" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/builder/amazon/common/awserrors" "github.com/hashicorp/packer/packer-plugin-sdk/retry" ) // DestroyAMIs deregisters the AWS machine images in imageids from an active AWS account func DestroyAMIs(imageids []*string, ec2conn *ec2.EC2) error { resp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ ImageIds: imageids, }) if err != nil { err := fmt.Errorf("Error describing AMI: %s", err) return err } // Deregister image by name. for _, i := range resp.Images { ctx := context.TODO() err = retry.Config{ Tries: 11, ShouldRetry: func(err error) bool { return awserrors.Matches(err, "UnauthorizedOperation", "") }, RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 30 * time.Second, Multiplier: 2}).Linear, }.Run(ctx, func(ctx context.Context) error { _, err := ec2conn.DeregisterImage(&ec2.DeregisterImageInput{ ImageId: i.ImageId, }) return err }) if err != nil { err := fmt.Errorf("Error deregistering existing AMI: %s", err) return err } log.Printf("Deregistered AMI id: %s", *i.ImageId) // Delete snapshot(s) by image for _, b := range i.BlockDeviceMappings { if b.Ebs != nil && aws.StringValue(b.Ebs.SnapshotId) != "" { err = retry.Config{ Tries: 11, ShouldRetry: func(err error) bool { return awserrors.Matches(err, "UnauthorizedOperation", "") }, RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 30 * time.Second, Multiplier: 2}).Linear, }.Run(ctx, func(ctx context.Context) error { _, err := ec2conn.DeleteSnapshot(&ec2.DeleteSnapshotInput{ SnapshotId: b.Ebs.SnapshotId, }) return err }) if err != nil { err := fmt.Errorf("Error deleting existing snapshot: %s", err) return err } log.Printf("Deleted snapshot: %s", *b.Ebs.SnapshotId) } } } return nil }