Merge pull request #6787 from hashicorp/nilable_encrypt

amazon: Nilable encrypt setting
This commit is contained in:
Megan Marsh 2019-02-28 15:29:40 -08:00 committed by GitHub
commit d3ed89ab86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 78 additions and 255 deletions

View File

@ -273,12 +273,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
EnableAMISriovNetSupport: b.config.AMISriovNetSupport, EnableAMISriovNetSupport: b.config.AMISriovNetSupport,
EnableAMIENASupport: b.config.AMIENASupport, EnableAMIENASupport: b.config.AMIENASupport,
}, },
&awscommon.StepCreateEncryptedAMICopy{
KeyID: b.config.AMIKmsKeyId,
EncryptBootVolume: b.config.AMIEncryptBootVolume,
Name: b.config.AMIName,
AMIMappings: b.config.AMIBlockDevices.AMIMappings,
},
&awscommon.StepAMIRegionCopy{ &awscommon.StepAMIRegionCopy{
AccessConfig: &b.config.AccessConfig, AccessConfig: &b.config.AccessConfig,
Regions: b.config.AMIRegions, Regions: b.config.AMIRegions,

View File

@ -23,7 +23,7 @@ type AMIConfig struct {
AMISriovNetSupport bool `mapstructure:"sriov_support"` AMISriovNetSupport bool `mapstructure:"sriov_support"`
AMIForceDeregister bool `mapstructure:"force_deregister"` AMIForceDeregister bool `mapstructure:"force_deregister"`
AMIForceDeleteSnapshot bool `mapstructure:"force_delete_snapshot"` AMIForceDeleteSnapshot bool `mapstructure:"force_delete_snapshot"`
AMIEncryptBootVolume bool `mapstructure:"encrypt_boot"` AMIEncryptBootVolume *bool `mapstructure:"encrypt_boot"`
AMIKmsKeyId string `mapstructure:"kms_key_id"` AMIKmsKeyId string `mapstructure:"kms_key_id"`
AMIRegionKMSKeyIDs map[string]string `mapstructure:"region_kms_key_ids"` AMIRegionKMSKeyIDs map[string]string `mapstructure:"region_kms_key_ids"`
SnapshotTags TagMap `mapstructure:"snapshot_tags"` SnapshotTags TagMap `mapstructure:"snapshot_tags"`
@ -59,7 +59,7 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context
errs = append(errs, c.prepareRegions(accessConfig)...) errs = append(errs, c.prepareRegions(accessConfig)...)
if len(c.AMIUsers) > 0 && c.AMIEncryptBootVolume { if len(c.AMIUsers) > 0 && c.AMIEncryptBootVolume != nil && *c.AMIEncryptBootVolume {
errs = append(errs, fmt.Errorf("Cannot share AMI with encrypted boot volume")) errs = append(errs, fmt.Errorf("Cannot share AMI with encrypted boot volume"))
} }
@ -81,7 +81,7 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context
} }
if len(c.SnapshotUsers) > 0 { if len(c.SnapshotUsers) > 0 {
if len(c.AMIKmsKeyId) == 0 && c.AMIEncryptBootVolume { if len(c.AMIKmsKeyId) == 0 && c.AMIEncryptBootVolume != nil && *c.AMIEncryptBootVolume {
errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted with default KMS key")) errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted with default KMS key"))
} }
if len(c.AMIRegionKMSKeyIDs) > 0 { if len(c.AMIRegionKMSKeyIDs) > 0 {

View File

@ -138,7 +138,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) {
c.SnapshotUsers = []string{"foo", "bar"} c.SnapshotUsers = []string{"foo", "bar"}
c.AMIKmsKeyId = "123-abc-456" c.AMIKmsKeyId = "123-abc-456"
c.AMIEncryptBootVolume = true c.AMIEncryptBootVolume = &[]bool{true}[0]
c.AMIRegions = []string{"us-east-1", "us-west-1"} c.AMIRegions = []string{"us-east-1", "us-west-1"}
c.AMIRegionKMSKeyIDs = map[string]string{ c.AMIRegionKMSKeyIDs = map[string]string{
"us-east-1": "123-456-7890", "us-east-1": "123-456-7890",
@ -161,7 +161,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) {
func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) {
c := testAMIConfig() c := testAMIConfig()
c.AMIUsers = []string{"testAccountID"} c.AMIUsers = []string{"testAccountID"}
c.AMIEncryptBootVolume = true c.AMIEncryptBootVolume = &[]bool{true}[0]
accessConf := testAccessConfig() accessConf := testAccessConfig()
@ -178,7 +178,7 @@ func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) {
func TestAMIConfigPrepare_ValidateKmsKey(t *testing.T) { func TestAMIConfigPrepare_ValidateKmsKey(t *testing.T) {
c := testAMIConfig() c := testAMIConfig()
c.AMIEncryptBootVolume = true c.AMIEncryptBootVolume = aws.Bool(true)
accessConf := testAccessConfig() accessConf := testAccessConfig()

View File

@ -13,7 +13,7 @@ import (
type BlockDevice struct { type BlockDevice struct {
DeleteOnTermination bool `mapstructure:"delete_on_termination"` DeleteOnTermination bool `mapstructure:"delete_on_termination"`
DeviceName string `mapstructure:"device_name"` DeviceName string `mapstructure:"device_name"`
Encrypted bool `mapstructure:"encrypted"` Encrypted *bool `mapstructure:"encrypted"`
IOPS int64 `mapstructure:"iops"` IOPS int64 `mapstructure:"iops"`
NoDevice bool `mapstructure:"no_device"` NoDevice bool `mapstructure:"no_device"`
SnapshotId string `mapstructure:"snapshot_id"` SnapshotId string `mapstructure:"snapshot_id"`
@ -71,9 +71,8 @@ func buildBlockDevices(b []BlockDevice) []*ec2.BlockDeviceMapping {
// You cannot specify Encrypted if you specify a Snapshot ID // You cannot specify Encrypted if you specify a Snapshot ID
if blockDevice.SnapshotId != "" { if blockDevice.SnapshotId != "" {
ebsBlockDevice.SnapshotId = aws.String(blockDevice.SnapshotId) ebsBlockDevice.SnapshotId = aws.String(blockDevice.SnapshotId)
} else if blockDevice.Encrypted {
ebsBlockDevice.Encrypted = aws.Bool(blockDevice.Encrypted)
} }
ebsBlockDevice.Encrypted = blockDevice.Encrypted
if blockDevice.KmsKeyId != "" { if blockDevice.KmsKeyId != "" {
ebsBlockDevice.KmsKeyId = aws.String(blockDevice.KmsKeyId) ebsBlockDevice.KmsKeyId = aws.String(blockDevice.KmsKeyId)
@ -93,7 +92,7 @@ func (b *BlockDevice) Prepare(ctx *interpolate.Context) error {
"for every device in the block device mapping.") "for every device in the block device mapping.")
} }
// Warn that encrypted must be true when setting kms_key_id // Warn that encrypted must be true when setting kms_key_id
if b.KmsKeyId != "" && b.Encrypted == false { if b.KmsKeyId != "" && b.Encrypted != nil && *b.Encrypted == false {
return fmt.Errorf("The device %v, must also have `encrypted: "+ return fmt.Errorf("The device %v, must also have `encrypted: "+
"true` when setting a kms_key_id.", b.DeviceName) "true` when setting a kms_key_id.", b.DeviceName)
} }

View File

@ -71,7 +71,7 @@ func TestBlockDevice(t *testing.T) {
VolumeType: "gp2", VolumeType: "gp2",
VolumeSize: 8, VolumeSize: 8,
DeleteOnTermination: true, DeleteOnTermination: true,
Encrypted: true, Encrypted: aws.Bool(true),
}, },
Result: &ec2.BlockDeviceMapping{ Result: &ec2.BlockDeviceMapping{
@ -90,7 +90,7 @@ func TestBlockDevice(t *testing.T) {
VolumeType: "gp2", VolumeType: "gp2",
VolumeSize: 8, VolumeSize: 8,
DeleteOnTermination: true, DeleteOnTermination: true,
Encrypted: true, Encrypted: aws.Bool(true),
KmsKeyId: "2Fa48a521f-3aff-4b34-a159-376ac5d37812", KmsKeyId: "2Fa48a521f-3aff-4b34-a159-376ac5d37812",
}, },

View File

@ -19,8 +19,10 @@ func listEC2Regions(ec2conn ec2iface.EC2API) ([]string, error) {
return regions, nil return regions, nil
} }
// ValidateRegion returns true if the supplied region is a valid AWS // ValidateRegion returns an nil if the regions are valid
// region and false if it's not. // and exists; otherwise an error.
// ValidateRegion calls ec2conn.DescribeRegions to get the list of
// regions available to this account.
func (c *AccessConfig) ValidateRegion(regions ...string) error { func (c *AccessConfig) ValidateRegion(regions ...string) error {
ec2conn, err := c.NewEC2Connection() ec2conn, err := c.NewEC2Connection()
if err != nil { if err != nil {
@ -50,7 +52,7 @@ func (c *AccessConfig) ValidateRegion(regions ...string) error {
} }
if len(invalidRegions) > 0 { if len(invalidRegions) > 0 {
return fmt.Errorf("Invalid region(s): %v", invalidRegions) return fmt.Errorf("Invalid region(s): %v, available regions: %v", invalidRegions, validRegions)
} }
return nil return nil
} }

View File

@ -16,7 +16,7 @@ type StepAMIRegionCopy struct {
AccessConfig *AccessConfig AccessConfig *AccessConfig
Regions []string Regions []string
RegionKeyIds map[string]string RegionKeyIds map[string]string
EncryptBootVolume bool EncryptBootVolume *bool // nil means preserve
Name string Name string
} }
@ -27,6 +27,13 @@ func (s *StepAMIRegionCopy) Run(ctx context.Context, state multistep.StateBag) m
snapshots := state.Get("snapshots").(map[string][]string) snapshots := state.Get("snapshots").(map[string][]string)
ami := amis[*ec2conn.Config.Region] ami := amis[*ec2conn.Config.Region]
if s.EncryptBootVolume != nil {
// encrypt_boot was set, we now have to copy the temporary
// AMI with required encryption setting.
// temp image was created by stepCreateAMI.
s.Regions = append(s.Regions, *ec2conn.Config.Region)
}
if len(s.Regions) == 0 { if len(s.Regions) == 0 {
return multistep.ActionContinue return multistep.ActionContinue
} }
@ -37,23 +44,24 @@ func (s *StepAMIRegionCopy) Run(ctx context.Context, state multistep.StateBag) m
var wg sync.WaitGroup var wg sync.WaitGroup
var regKeyID string var regKeyID string
errs := new(packer.MultiError) errs := new(packer.MultiError)
wg.Add(len(s.Regions))
for _, region := range s.Regions { for _, region := range s.Regions {
if region == *ec2conn.Config.Region { if region == *ec2conn.Config.Region && s.EncryptBootVolume == nil {
ui.Message(fmt.Sprintf( ui.Message(fmt.Sprintf(
"Avoiding copying AMI to duplicate region %s", region)) "Avoiding copying AMI to duplicate region %s", region))
continue continue
} }
wg.Add(1)
ui.Message(fmt.Sprintf("Copying to: %s", region)) ui.Message(fmt.Sprintf("Copying to: %s", region))
if s.EncryptBootVolume { if s.EncryptBootVolume != nil && *s.EncryptBootVolume {
regKeyID = s.RegionKeyIds[region] regKeyID = s.RegionKeyIds[region]
} }
go func(region string) { go func(region string) {
defer wg.Done() defer wg.Done()
id, snapshotIds, err := amiRegionCopy(ctx, state, s.AccessConfig, s.Name, ami, region, *ec2conn.Config.Region, regKeyID) id, snapshotIds, err := amiRegionCopy(ctx, state, s.AccessConfig, s.Name, ami, region, *ec2conn.Config.Region, regKeyID, s.EncryptBootVolume)
lock.Lock() lock.Lock()
defer lock.Unlock() defer lock.Unlock()
amis[region] = id amis[region] = id
@ -85,20 +93,16 @@ func (s *StepAMIRegionCopy) Cleanup(state multistep.StateBag) {
// amiRegionCopy does a copy for the given AMI to the target region and // amiRegionCopy does a copy for the given AMI to the target region and
// returns the resulting ID and snapshot IDs, or error. // returns the resulting ID and snapshot IDs, or error.
func amiRegionCopy(ctx context.Context, state multistep.StateBag, config *AccessConfig, name string, imageId string, func amiRegionCopy(ctx context.Context, state multistep.StateBag, config *AccessConfig, name, imageId,
target string, source string, keyID string) (string, []string, error) { target, source, keyId string, encrypt *bool) (string, []string, error) {
snapshotIds := []string{} snapshotIds := []string{}
isEncrypted := false
// Connect to the region where the AMI will be copied to // Connect to the region where the AMI will be copied to
session, err := config.Session() session, err := config.Session()
if err != nil { if err != nil {
return "", snapshotIds, err return "", snapshotIds, err
} }
// if we've provided a map of key ids to regions, use those keys.
if len(keyID) > 0 {
isEncrypted = true
}
regionconn := ec2.New(session.Copy(&aws.Config{ regionconn := ec2.New(session.Copy(&aws.Config{
Region: aws.String(target), Region: aws.String(target),
HTTPClient: commonhelper.HttpClientWithEnvironmentProxy(), HTTPClient: commonhelper.HttpClientWithEnvironmentProxy(),
@ -108,8 +112,8 @@ func amiRegionCopy(ctx context.Context, state multistep.StateBag, config *Access
SourceRegion: &source, SourceRegion: &source,
SourceImageId: &imageId, SourceImageId: &imageId,
Name: &name, Name: &name,
Encrypted: aws.Bool(isEncrypted), Encrypted: encrypt,
KmsKeyId: aws.String(keyID), KmsKeyId: aws.String(keyId),
}) })
if err != nil { if err != nil {

View File

@ -27,7 +27,7 @@ func (s *StepDeregisterAMI) Run(_ context.Context, state multistep.StateBag) mul
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
ec2conn := state.Get("ec2").(*ec2.EC2) ec2conn := state.Get("ec2").(*ec2.EC2)
// Add the session region to list of regions will will deregister AMIs in // Add the session region to list of regions will deregister AMIs in
regions := append(s.Regions, *ec2conn.Config.Region) regions := append(s.Regions, *ec2conn.Config.Region)
for _, region := range regions { for _, region := range regions {

View File

@ -1,178 +0,0 @@
package common
import (
"context"
"fmt"
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type StepCreateEncryptedAMICopy struct {
image *ec2.Image
KeyID string
EncryptBootVolume bool
Name string
AMIMappings []BlockDevice
ToDelete []*string
}
func (s *StepCreateEncryptedAMICopy) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
kmsKeyId := s.KeyID
// Encrypt boot not set, so skip step
if !s.EncryptBootVolume {
if kmsKeyId != "" {
log.Printf("Ignoring KMS Key ID: %s, encrypted=false", kmsKeyId)
}
return multistep.ActionContinue
}
ui.Say("Creating Encrypted AMI Copy")
amis := state.Get("amis").(map[string]string)
var region, id string
if amis != nil {
for region, id = range amis {
break // There is only ever one region:ami pair in this map
}
}
ui.Say(fmt.Sprintf("Copying AMI: %s(%s)", region, id))
if kmsKeyId != "" {
ui.Say(fmt.Sprintf("Encrypting with KMS Key ID: %s", kmsKeyId))
}
copyOpts := &ec2.CopyImageInput{
Name: &s.Name, // Try to overwrite existing AMI
SourceImageId: aws.String(id),
SourceRegion: aws.String(region),
Encrypted: aws.Bool(true),
KmsKeyId: aws.String(kmsKeyId),
}
copyResp, err := ec2conn.CopyImage(copyOpts)
if err != nil {
err := fmt.Errorf("Error copying AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Wait for the copy to become ready
ui.Say("Waiting for AMI copy to become ready...")
if err := WaitUntilAMIAvailable(ctx, ec2conn, *copyResp.ImageId); err != nil {
err := fmt.Errorf("Error waiting for AMI Copy: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Get the encrypted AMI image, we need the new snapshot id's
encImagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{aws.String(*copyResp.ImageId)}})
if err != nil {
err := fmt.Errorf("Error searching for AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
encImage := encImagesResp.Images[0]
var encSnapshots []string
for _, blockDevice := range encImage.BlockDeviceMappings {
if blockDevice.Ebs != nil && blockDevice.Ebs.SnapshotId != nil {
encSnapshots = append(encSnapshots, *blockDevice.Ebs.SnapshotId)
}
}
// Get the unencrypted AMI image
unencImagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{aws.String(id)}})
if err != nil {
err := fmt.Errorf("Error searching for AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
unencImage := unencImagesResp.Images[0]
// Remove unencrypted AMI
ui.Say("Deregistering unencrypted AMI")
deregisterOpts := &ec2.DeregisterImageInput{ImageId: aws.String(id)}
if _, err := ec2conn.DeregisterImage(deregisterOpts); err != nil {
ui.Error(fmt.Sprintf("Error deregistering AMI, may still be around: %s", err))
return multistep.ActionHalt
}
// Figure out which unencrypted snapshot(s) to delete
snapshots := state.Get("snapshots").(map[string][]string)
OuterLoop:
for _, blockDevice := range unencImage.BlockDeviceMappings {
if blockDevice.Ebs != nil && blockDevice.Ebs.SnapshotId != nil {
// If this packer run didn't create it, then don't delete it
for _, origDevice := range s.AMIMappings {
if origDevice.SnapshotId == *blockDevice.Ebs.SnapshotId {
ui.Message(fmt.Sprintf("Keeping Snapshot ID: %s", *blockDevice.Ebs.SnapshotId))
continue OuterLoop
}
}
s.ToDelete = append(s.ToDelete, aws.String(*blockDevice.Ebs.SnapshotId))
}
}
// Replace original AMI ID with Encrypted ID in state
amis[region] = *copyResp.ImageId
snapshots[region] = encSnapshots
state.Put("amis", amis)
state.Put("snapshots", snapshots)
imagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{copyResp.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]
return multistep.ActionContinue
}
func (s *StepCreateEncryptedAMICopy) 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 cancellation 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
}
ui.Say("Deleting unencrypted snapshots")
for _, snap := range s.ToDelete {
ui.Message(fmt.Sprintf("Deleting Snapshot ID: %s", *snap))
deleteSnapOpts := &ec2.DeleteSnapshotInput{
SnapshotId: snap,
}
if _, err := ec2conn.DeleteSnapshot(deleteSnapOpts); err != nil {
ui.Error(fmt.Sprintf("Error deleting snapshot, may still be around: %s", err))
return
}
}
}

View File

@ -223,12 +223,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Regions: b.config.AMIRegions, Regions: b.config.AMIRegions,
}, },
&stepCreateAMI{}, &stepCreateAMI{},
&awscommon.StepCreateEncryptedAMICopy{
KeyID: b.config.AMIKmsKeyId,
EncryptBootVolume: b.config.AMIEncryptBootVolume,
Name: b.config.AMIName,
AMIMappings: b.config.AMIBlockDevices.AMIMappings,
},
&awscommon.StepAMIRegionCopy{ &awscommon.StepAMIRegionCopy{
AccessConfig: &b.config.AccessConfig, AccessConfig: &b.config.AccessConfig,
Regions: b.config.AMIRegions, Regions: b.config.AMIRegions,

View File

@ -24,13 +24,13 @@ func (s *stepCreateAMI) Run(ctx context.Context, state multistep.StateBag) multi
// Create the image // Create the image
amiName := config.AMIName amiName := config.AMIName
if config.AMIEncryptBootVolume { if config.AMIEncryptBootVolume != nil {
// to avoid having a temporary unencrypted // encrypt_boot was set, so we will create a temporary image
// image named config.AMIName // and then create a copy of it with the correct encrypt_boot
amiName = random.AlphaNum(7) amiName = random.AlphaNum(7)
} }
ui.Say(fmt.Sprintf("Creating unencrypted AMI %s from instance %s", amiName, *instance.InstanceId)) ui.Say(fmt.Sprintf("Creating AMI %s from instance %s", amiName, *instance.InstanceId))
createOpts := &ec2.CreateImageInput{ createOpts := &ec2.CreateImageInput{
InstanceId: instance.InstanceId, InstanceId: instance.InstanceId,
Name: &amiName, Name: &amiName,
@ -94,17 +94,19 @@ func (s *stepCreateAMI) Cleanup(state multistep.StateBag) {
if s.image == nil { if s.image == nil {
return return
} }
config := state.Get("config").(*Config)
_, cancelled := state.GetOk(multistep.StateCancelled) _, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted) _, halted := state.GetOk(multistep.StateHalted)
if !cancelled && !halted { encryptBootSet := config.AMIEncryptBootVolume != nil
if !cancelled && !halted && !encryptBootSet {
return return
} }
ec2conn := state.Get("ec2").(*ec2.EC2) ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
ui.Say("Deregistering the AMI because cancellation or error...") ui.Say("Deregistering the AMI because cancellation, error or it was temporary (encrypt_boot was set)...")
deregisterOpts := &ec2.DeregisterImageInput{ImageId: s.image.ImageId} deregisterOpts := &ec2.DeregisterImageInput{ImageId: s.image.ImageId}
if _, err := ec2conn.DeregisterImage(deregisterOpts); err != nil { if _, err := ec2conn.DeregisterImage(deregisterOpts); err != nil {
ui.Error(fmt.Sprintf("Error deregistering AMI, may still be around: %s", err)) ui.Error(fmt.Sprintf("Error deregistering AMI, may still be around: %s", err))

View File

@ -249,11 +249,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
EnableAMISriovNetSupport: b.config.AMISriovNetSupport, EnableAMISriovNetSupport: b.config.AMISriovNetSupport,
EnableAMIENASupport: b.config.AMIENASupport, EnableAMIENASupport: b.config.AMIENASupport,
}, },
&awscommon.StepCreateEncryptedAMICopy{
KeyID: b.config.AMIKmsKeyId,
EncryptBootVolume: b.config.AMIEncryptBootVolume,
Name: b.config.AMIName,
},
&awscommon.StepAMIRegionCopy{ &awscommon.StepAMIRegionCopy{
AccessConfig: &b.config.AccessConfig, AccessConfig: &b.config.AccessConfig,
Regions: b.config.AMIRegions, Regions: b.config.AMIRegions,

View File

@ -141,11 +141,10 @@ each category, the available configuration keys are alphabetized.
documentation on enabling enhanced documentation on enabling enhanced
networking](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking.html#enabling_enhanced_networking). networking](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking.html#enabling_enhanced_networking).
- `encrypt_boot` (boolean) - Instruct packer to automatically create a copy - `encrypt_boot` (boolean) - Whether or not to encrypt the resulting AMI when
of the AMI with an encrypted boot volume (discarding the initial copying a provisioned instance to an AMI. By default, Packer will keep the
unencrypted AMI in the process). Packer will always run this operation, encryption setting to what it was in the source image. Setting `false` will
even if the base AMI has an encrypted boot volume to start with. Default result in an unencrypted image, and `true` will result in an encrypted one.
`false`.
- `force_deregister` (boolean) - Force Packer to first deregister an existing - `force_deregister` (boolean) - Force Packer to first deregister an existing
AMI if one with the same name already exists. Default `false`. AMI if one with the same name already exists. Default `false`.
@ -187,6 +186,9 @@ each category, the available configuration keys are alphabetized.
device mapping. device mapping.
- `encrypted` (boolean) - Indicates whether or not to encrypt the volume. - `encrypted` (boolean) - Indicates whether or not to encrypt the volume.
By default, Packer will keep the encryption setting to what it was in
the source image. Setting `false` will result in an unencrypted device,
and `true` will result in an encrypted one.
- `kms_key_id` (string) - The ARN for the KMS encryption key. When - `kms_key_id` (string) - The ARN for the KMS encryption key. When
specifying `kms_key_id`, `encrypted` needs to be set to `true`. For specifying `kms_key_id`, `encrypted` needs to be set to `true`. For

View File

@ -91,7 +91,10 @@ builder.
example, `/dev/sdh` or `xvdh`). Required for every device in the block example, `/dev/sdh` or `xvdh`). Required for every device in the block
device mapping. device mapping.
- `encrypted` (boolean) - Indicates whether to encrypt the volume or not - `encrypted` (boolean) - Indicates whether or not to encrypt the volume.
By default, Packer will keep the encryption setting to what it was in
the source image. Setting `false` will result in an unencrypted device,
and `true` will result in an encrypted one.
- `iops` (number) - The number of I/O operations per second (IOPS) that - `iops` (number) - The number of I/O operations per second (IOPS) that
the volume supports. See the documentation on the volume supports. See the documentation on
@ -220,18 +223,16 @@ builder.
Attempting to do so will cause an error. Attempting to do so will cause an error.
!> **Warning!** Additional costs may be incurred by enabling T2 !> **Warning!** Additional costs may be incurred by enabling T2
Unlimited - even for instances that would usually qualify for the [AWS Free Unlimited - even for instances that would usually qualify for the
Tier](https://aws.amazon.com/free/). [AWS Free Tier](https://aws.amazon.com/free/).
- `encrypt_boot` (boolean) - Instruct packer to automatically create a copy - `encrypt_boot` (boolean) - Whether or not to encrypt the resulting AMI when
of the AMI with an encrypted boot volume (discarding the initial copying a provisioned instance to an AMI. By default, Packer will keep the
unencrypted AMI in the process). Packer will always run this operation, encryption setting to what it was in the source image. Setting `false` will
even if the base AMI has an encrypted boot volume to start with. Default result in an unencrypted image, and `true` will result in an encrypted one.
`false`.
- `force_delete_snapshot` (boolean) - Force Packer to delete snapshots associated with
- `force_delete_snapshot` (boolean) - Force Packer to delete snapshots AMIs, which have been deregistered by `force_deregister`. Default `false`.
associated with AMIs, which have been deregistered by `force_deregister`.
Default `false`.
- `force_deregister` (boolean) - Force Packer to first deregister an existing - `force_deregister` (boolean) - Force Packer to first deregister an existing
AMI if one with the same name already exists. Default `false`. AMI if one with the same name already exists. Default `false`.

View File

@ -81,6 +81,9 @@ builder.
device mapping. device mapping.
- `encrypted` (boolean) - Indicates whether or not to encrypt the volume. - `encrypted` (boolean) - Indicates whether or not to encrypt the volume.
By default, Packer will keep the encryption setting to what it was in
the source image. Setting `false` will result in an unencrypted device,
and `true` will result in an encrypted one.
- `iops` (number) - The number of I/O operations per second (IOPS) that - `iops` (number) - The number of I/O operations per second (IOPS) that
the volume supports. See the documentation on the volume supports. See the documentation on
@ -212,11 +215,10 @@ builder.
Unlimited - even for instances that would usually qualify for the [AWS Free Unlimited - even for instances that would usually qualify for the [AWS Free
Tier](https://aws.amazon.com/free/). Tier](https://aws.amazon.com/free/).
- `encrypt_boot` (boolean) - Instruct packer to automatically create a copy - `encrypt_boot` (boolean) - Whether or not to encrypt the resulting AMI when
of the AMI with an encrypted boot volume (discarding the initial copying a provisioned instance to an AMI. By default, Packer will keep the
unencrypted AMI in the process). Packer will always run this operation, encryption setting to what it was in the source image. Setting `false` will
even if the base AMI has an encrypted boot volume to start with. Default result in an unencrypted image, and `true` will result in an encrypted one.
`false`.
- `force_deregister` (boolean) - Force Packer to first deregister an existing - `force_deregister` (boolean) - Force Packer to first deregister an existing
AMI if one with the same name already exists. Default `false`. AMI if one with the same name already exists. Default `false`.

View File

@ -69,7 +69,10 @@ builder.
- `delete_on_termination` (boolean) - Indicates whether the EBS volume is - `delete_on_termination` (boolean) - Indicates whether the EBS volume is
deleted on instance termination. deleted on instance termination.
- `encrypted` (boolean) - Indicates whether to encrypt the volume or not - `encrypted` (boolean) - Indicates whether or not to encrypt the volume.
By default, Packer will keep the encryption setting to what it was in
the source image. Setting `false` will result in an unencrypted device,
and `true` will result in an encrypted one.
- `kms_key_id` (string) - The ARN for the KMS encryption key. When - `kms_key_id` (string) - The ARN for the KMS encryption key. When
specifying `kms_key_id`, `encrypted` needs to be set to `true`. For specifying `kms_key_id`, `encrypted` needs to be set to `true`. For

View File

@ -110,7 +110,10 @@ builder.
example, `/dev/sdh` or `xvdh`). Required for every device in the block example, `/dev/sdh` or `xvdh`). Required for every device in the block
device mapping. device mapping.
- `encrypted` (boolean) - Indicates whether to encrypt the volume or not - `encrypted` (boolean) - Indicates whether or not to encrypt the volume.
By default, Packer will keep the encryption setting to what it was in
the source image. Setting `false` will result in an unencrypted device,
and `true` will result in an encrypted one.
- `iops` (number) - The number of I/O operations per second (IOPS) that - `iops` (number) - The number of I/O operations per second (IOPS) that
the volume supports. See the documentation on the volume supports. See the documentation on