Merge pull request #4601 from mitchellh/ebssurrogate-copy-ami

build/amazon-ebssurrogate: Add region copy, attributes, tags steps
This commit is contained in:
Matthew Hooker 2017-02-27 10:47:34 -08:00 committed by GitHub
commit 9c027aa70b
5 changed files with 95 additions and 9 deletions

View File

@ -1,21 +1,20 @@
package ebs
package common
import (
"fmt"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/template/interpolate"
)
type stepTagEBSVolumes struct {
type StepTagEBSVolumes struct {
VolumeRunTags map[string]string
Ctx interpolate.Context
}
func (s *stepTagEBSVolumes) Run(state multistep.StateBag) multistep.StepAction {
func (s *StepTagEBSVolumes) Run(state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2)
instance := state.Get("instance").(*ec2.Instance)
sourceAMI := state.Get("source_image").(*ec2.Image)
@ -37,7 +36,7 @@ func (s *stepTagEBSVolumes) Run(state multistep.StateBag) multistep.StepAction {
}
ui.Say("Adding tags to source EBS Volumes")
tags, err := common.ConvertToEC2Tags(s.VolumeRunTags, *ec2conn.Config.Region, *sourceAMI.ImageId, s.Ctx)
tags, err := ConvertToEC2Tags(s.VolumeRunTags, *ec2conn.Config.Region, *sourceAMI.ImageId, s.Ctx)
if err != nil {
err := fmt.Errorf("Error tagging source EBS Volumes on %s: %s", *instance.InstanceId, err)
state.Put("error", err)
@ -59,6 +58,6 @@ func (s *stepTagEBSVolumes) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue
}
func (s *stepTagEBSVolumes) Cleanup(state multistep.StateBag) {
func (s *StepTagEBSVolumes) Cleanup(state multistep.StateBag) {
// No cleanup...
}

View File

@ -149,7 +149,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Ctx: b.config.ctx,
InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior,
},
&stepTagEBSVolumes{
&awscommon.StepTagEBSVolumes{
VolumeRunTags: b.config.VolumeRunTags,
Ctx: b.config.ctx,
},

View File

@ -29,6 +29,7 @@ type Config struct {
awscommon.AMIConfig `mapstructure:",squash"`
RootDevice RootBlockDevice `mapstructure:"ami_root_device"`
VolumeRunTags map[string]string `mapstructure:"run_volume_tags"`
ctx interpolate.Context
}
@ -47,6 +48,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
Exclude: []string{
"ami_description",
"run_tags",
"run_volume_tags",
"snapshot_tags",
"tags",
},
},
@ -119,6 +122,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
// Build the steps
steps := []multistep.Step{
&awscommon.StepPreValidate{
DestAmiName: b.config.AMIName,
ForceDeregister: b.config.AMIForceDeregister,
},
&awscommon.StepSourceAMIInfo{
SourceAmi: b.config.SourceAmi,
EnhancedNetworking: b.config.AMIEnhancedNetworking,
@ -155,6 +162,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Tags: b.config.RunTags,
InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior,
},
&awscommon.StepTagEBSVolumes{
VolumeRunTags: b.config.VolumeRunTags,
Ctx: b.config.ctx,
},
&awscommon.StepGetPassword{
Debug: b.config.PackerDebug,
Comm: &b.config.RunConfig.Comm,
@ -181,10 +192,39 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&StepSnapshotNewRootVolume{
NewRootMountPoint: b.config.RootDevice.SourceDeviceName,
},
&awscommon.StepDeregisterAMI{
ForceDeregister: b.config.AMIForceDeregister,
ForceDeleteSnapshot: b.config.AMIForceDeleteSnapshot,
AMIName: b.config.AMIName,
},
&StepRegisterAMI{
RootDevice: b.config.RootDevice,
BlockDevices: b.config.BlockDevices.BuildLaunchDevices(),
},
&awscommon.StepCreateEncryptedAMICopy{
KeyID: b.config.AMIKmsKeyId,
EncryptBootVolume: b.config.AMIEncryptBootVolume,
Name: b.config.AMIName,
},
&awscommon.StepAMIRegionCopy{
AccessConfig: &b.config.AccessConfig,
Regions: b.config.AMIRegions,
Name: b.config.AMIName,
},
&awscommon.StepModifyAMIAttributes{
Description: b.config.AMIDescription,
Users: b.config.AMIUsers,
Groups: b.config.AMIGroups,
ProductCodes: b.config.AMIProductCodes,
SnapshotUsers: b.config.SnapshotUsers,
SnapshotGroups: b.config.SnapshotGroups,
Ctx: b.config.ctx,
},
&awscommon.StepCreateTags{
Tags: b.config.AMITags,
SnapshotTags: b.config.SnapshotTags,
Ctx: b.config.ctx,
},
}
// Run!

View File

@ -14,6 +14,7 @@ import (
type StepRegisterAMI struct {
RootDevice RootBlockDevice
BlockDevices []*ec2.BlockDeviceMapping
image *ec2.Image
}
func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
@ -82,7 +83,45 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionHalt
}
imagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{registerResp.ImageId}})
if err != nil {
err := fmt.Errorf("Error searching for AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
s.image = imagesResp.Images[0]
snapshots := make(map[string][]string)
for _, blockDeviceMapping := range imagesResp.Images[0].BlockDeviceMappings {
if blockDeviceMapping.Ebs != nil && blockDeviceMapping.Ebs.SnapshotId != nil {
snapshots[*ec2conn.Config.Region] = append(snapshots[*ec2conn.Config.Region], *blockDeviceMapping.Ebs.SnapshotId)
}
}
state.Put("snapshots", snapshots)
return multistep.ActionContinue
}
func (s *StepRegisterAMI) Cleanup(state multistep.StateBag) {}
func (s *StepRegisterAMI) Cleanup(state multistep.StateBag) {
if s.image == nil {
return
}
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
if !cancelled && !halted {
return
}
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
ui.Say("Deregistering the AMI because cancelation or error...")
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))
return
}
}

View File

@ -163,6 +163,14 @@ builder.
- `force_delete_snapshot` (boolean) - Force Packer to delete snapshots associated with
AMIs, which have been deregistered by `force_deregister`. Default `false`.
- `encrypt_boot` (boolean) - Instruct packer to automatically create a copy of the
AMI with an encrypted boot volume (discarding the initial unencrypted AMI in the
process). Default `false`.
- `kms_key_id` (string) - The ID of the KMS key to use for boot volume encryption.
This only applies to the main `region`, other regions where the AMI will be copied
will be encrypted by the default EBS KMS key.
- `iam_instance_profile` (string) - The name of an [IAM instance
profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html)
to launch the EC2 instance with.