diff --git a/builder/amazon/common/step_ami_region_copy.go b/builder/amazon/common/step_ami_region_copy.go index d5316c4a0..f88a5fb4a 100644 --- a/builder/amazon/common/step_ami_region_copy.go +++ b/builder/amazon/common/step_ami_region_copy.go @@ -32,6 +32,9 @@ func (s *StepAMIRegionCopy) Run(ctx context.Context, state multistep.StateBag) m // AMI with required encryption setting. // temp image was created by stepCreateAMI. s.Regions = append(s.Regions, *ec2conn.Config.Region) + if s.RegionKeyIds == nil { + s.RegionKeyIds = make(map[string]string) + } s.RegionKeyIds[*ec2conn.Config.Region] = s.AMIKmsKeyId } diff --git a/builder/amazon/ebs/step_create_ami.go b/builder/amazon/ebs/step_create_ami.go index 5b952e8e3..f68b961da 100644 --- a/builder/amazon/ebs/step_create_ami.go +++ b/builder/amazon/ebs/step_create_ami.go @@ -5,6 +5,7 @@ import ( "fmt" "log" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" "github.com/hashicorp/packer/common/random" @@ -106,10 +107,49 @@ func (s *stepCreateAMI) Cleanup(state multistep.StateBag) { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) - ui.Say("Deregistering the AMI because cancellation, error or it was temporary (encrypt_boot was set)...") - deregisterOpts := &ec2.DeregisterImageInput{ImageId: s.image.ImageId} - if _, err := ec2conn.DeregisterImage(deregisterOpts); err != nil { - ui.Error(fmt.Sprintf("Error deregistering AMI, may still be around: %s", err)) + ui.Say("Deregistering the AMI and deleting associated snapshots because " + + "of cancellation, error or it was temporary (encrypt_boot was set)...") + + resp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ + ImageIds: []*string{s.image.ImageId}, + }) + + if err != nil { + err := fmt.Errorf("Error describing AMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) return } + + // Deregister image by name. + for _, i := range resp.Images { + _, err := ec2conn.DeregisterImage(&ec2.DeregisterImageInput{ + ImageId: i.ImageId, + }) + + if err != nil { + err := fmt.Errorf("Error deregistering existing AMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return + } + ui.Say(fmt.Sprintf("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 := ec2conn.DeleteSnapshot(&ec2.DeleteSnapshotInput{ + SnapshotId: b.Ebs.SnapshotId, + }) + + if err != nil { + err := fmt.Errorf("Error deleting existing snapshot: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return + } + ui.Say(fmt.Sprintf("Deleted snapshot: %s", *b.Ebs.SnapshotId)) + } + } + } }