diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index 7459ee6b4..f51ae9255 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -408,6 +408,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack RootVolumeSize: b.config.RootVolumeSize, EnableAMISriovNetSupport: b.config.AMISriovNetSupport, EnableAMIENASupport: b.config.AMIENASupport, + AMISkipBuildRegion: b.config.AMISkipBuildRegion, }, &awscommon.StepAMIRegionCopy{ AccessConfig: &b.config.AccessConfig, diff --git a/builder/amazon/chroot/step_register_ami.go b/builder/amazon/chroot/step_register_ami.go index c8976dc6f..e38ad83ee 100644 --- a/builder/amazon/chroot/step_register_ami.go +++ b/builder/amazon/chroot/step_register_ami.go @@ -7,6 +7,7 @@ import ( "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" confighelper "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -17,6 +18,7 @@ type StepRegisterAMI struct { RootVolumeSize int64 EnableAMIENASupport confighelper.Trilean EnableAMISriovNetSupport bool + AMISkipBuildRegion bool } func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { @@ -29,12 +31,29 @@ func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) mul var registerOpts *ec2.RegisterImageInput + // Create the image + amiName := config.AMIName + state.Put("intermediary_image", false) + if config.AMIEncryptBootVolume.True() || s.AMISkipBuildRegion { + state.Put("intermediary_image", true) + + // From AWS SDK docs: You can encrypt a copy of an unencrypted snapshot, + // but you cannot use it to create an unencrypted copy of an encrypted + // snapshot. Your default CMK for EBS is used unless you specify a + // non-default key using KmsKeyId. + + // If encrypt_boot is nil or true, we need to create a temporary image + // so that in step_region_copy, we can copy it with the correct + // encryption + amiName = random.AlphaNum(7) + } + // Source Image is only required to be passed if the image is not from scratch if config.FromScratch { - registerOpts = buildBaseRegisterOpts(config, nil, s.RootVolumeSize, snapshotID) + registerOpts = buildBaseRegisterOpts(config, nil, s.RootVolumeSize, snapshotID, amiName) } else { image := state.Get("source_image").(*ec2.Image) - registerOpts = buildBaseRegisterOpts(config, image, s.RootVolumeSize, snapshotID) + registerOpts = buildBaseRegisterOpts(config, image, s.RootVolumeSize, snapshotID, amiName) } if s.EnableAMISriovNetSupport { @@ -75,7 +94,7 @@ func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) mul func (s *StepRegisterAMI) Cleanup(state multistep.StateBag) {} // Builds the base register opts with architecture, name, root block device, mappings, virtualizationtype -func buildBaseRegisterOpts(config *Config, sourceImage *ec2.Image, rootVolumeSize int64, snapshotID string) *ec2.RegisterImageInput { +func buildBaseRegisterOpts(config *Config, sourceImage *ec2.Image, rootVolumeSize int64, snapshotID string, amiName string) *ec2.RegisterImageInput { var ( mappings []*ec2.BlockDeviceMapping rootDeviceName string @@ -117,7 +136,7 @@ func buildBaseRegisterOpts(config *Config, sourceImage *ec2.Image, rootVolumeSiz if config.FromScratch { return &ec2.RegisterImageInput{ - Name: &config.AMIName, + Name: &amiName, Architecture: aws.String(config.Architecture), RootDeviceName: aws.String(rootDeviceName), VirtualizationType: aws.String(config.AMIVirtType), @@ -125,12 +144,12 @@ func buildBaseRegisterOpts(config *Config, sourceImage *ec2.Image, rootVolumeSiz } } - return buildRegisterOptsFromExistingImage(config, sourceImage, newMappings, rootDeviceName) + return buildRegisterOptsFromExistingImage(config, sourceImage, newMappings, rootDeviceName, amiName) } -func buildRegisterOptsFromExistingImage(config *Config, image *ec2.Image, mappings []*ec2.BlockDeviceMapping, rootDeviceName string) *ec2.RegisterImageInput { +func buildRegisterOptsFromExistingImage(config *Config, image *ec2.Image, mappings []*ec2.BlockDeviceMapping, rootDeviceName string, amiName string) *ec2.RegisterImageInput { registerOpts := &ec2.RegisterImageInput{ - Name: &config.AMIName, + Name: &amiName, Architecture: image.Architecture, RootDeviceName: &rootDeviceName, BlockDeviceMappings: mappings,