2019-05-31 08:27:41 -04:00
|
|
|
//go:generate struct-markdown
|
|
|
|
|
2013-08-15 17:05:08 -04:00
|
|
|
package common
|
|
|
|
|
|
|
|
import (
|
2018-01-12 18:10:51 -05:00
|
|
|
"fmt"
|
2015-07-15 20:07:36 -04:00
|
|
|
"strings"
|
|
|
|
|
2015-06-03 17:13:52 -04:00
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
|
|
"github.com/aws/aws-sdk-go/service/ec2"
|
2017-04-04 16:39:01 -04:00
|
|
|
"github.com/hashicorp/packer/template/interpolate"
|
2013-08-15 17:05:08 -04:00
|
|
|
)
|
|
|
|
|
2019-06-18 11:05:10 -04:00
|
|
|
// These will be attached when booting a new instance from your AMI.
|
|
|
|
// Your options here may vary depending on the type of VM you use. Example:
|
|
|
|
//
|
|
|
|
// ``` json
|
|
|
|
// "builders":[{
|
|
|
|
// "type":"...",
|
|
|
|
// "ami_block_device_mappings":[{
|
|
|
|
// "device_name":"xvda",
|
|
|
|
// "delete_on_termination":true,
|
|
|
|
// "volume_type":"gp2"
|
|
|
|
// }]
|
|
|
|
// }
|
|
|
|
// ```
|
2019-06-18 11:37:33 -04:00
|
|
|
// Documentation for Block Devices Mappings can be found here:
|
|
|
|
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html
|
2013-08-15 17:05:08 -04:00
|
|
|
type BlockDevice struct {
|
2019-06-18 05:55:12 -04:00
|
|
|
// Indicates whether the EBS volume is deleted on instance termination.
|
|
|
|
// Default false. NOTE: If this value is not explicitly set to true and
|
|
|
|
// volumes are not cleaned up by an alternative method, additional volumes
|
|
|
|
// will accumulate after every build.
|
2019-06-03 11:55:09 -04:00
|
|
|
DeleteOnTermination bool `mapstructure:"delete_on_termination" required:"false"`
|
2019-06-18 05:55:12 -04:00
|
|
|
// The device name exposed to the instance (for example, /dev/sdh or xvdh).
|
|
|
|
// Required for every device in the block device mapping.
|
2019-06-03 11:55:09 -04:00
|
|
|
DeviceName string `mapstructure:"device_name" required:"false"`
|
2019-06-18 05:55:12 -04:00
|
|
|
// 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.
|
2019-06-03 11:55:09 -04:00
|
|
|
Encrypted *bool `mapstructure:"encrypted" required:"false"`
|
2019-06-18 05:55:12 -04:00
|
|
|
// The number of I/O operations per second (IOPS) that the volume supports.
|
|
|
|
// See the documentation on IOPs for more information
|
2019-06-03 11:55:09 -04:00
|
|
|
IOPS int64 `mapstructure:"iops" required:"false"`
|
2019-06-18 05:55:12 -04:00
|
|
|
// Suppresses the specified device included in the block device mapping of
|
|
|
|
// the AMI.
|
2019-06-03 11:55:09 -04:00
|
|
|
NoDevice bool `mapstructure:"no_device" required:"false"`
|
2019-05-28 11:50:58 -04:00
|
|
|
// The ID of the snapshot.
|
2019-06-03 11:55:09 -04:00
|
|
|
SnapshotId string `mapstructure:"snapshot_id" required:"false"`
|
2019-06-18 05:55:12 -04:00
|
|
|
// The virtual device name. See the documentation on Block Device Mapping
|
2019-06-03 11:55:09 -04:00
|
|
|
// for more information.
|
|
|
|
VirtualName string `mapstructure:"virtual_name" required:"false"`
|
2019-06-18 05:55:12 -04:00
|
|
|
// The volume type. gp2 for General Purpose (SSD) volumes, io1 for
|
|
|
|
// Provisioned IOPS (SSD) volumes, st1 for Throughput Optimized HDD, sc1
|
|
|
|
// for Cold HDD, and standard for Magnetic volumes.
|
2019-06-03 11:55:09 -04:00
|
|
|
VolumeType string `mapstructure:"volume_type" required:"false"`
|
2019-06-18 05:55:12 -04:00
|
|
|
// The size of the volume, in GiB. Required if not specifying a
|
|
|
|
// snapshot_id.
|
2019-06-03 11:55:09 -04:00
|
|
|
VolumeSize int64 `mapstructure:"volume_size" required:"false"`
|
2013-08-15 17:05:08 -04:00
|
|
|
}
|
|
|
|
|
2019-06-18 06:37:47 -04:00
|
|
|
type BlockDevices []BlockDevice
|
2016-08-12 19:29:55 -04:00
|
|
|
|
2019-06-18 06:44:24 -04:00
|
|
|
func (bds BlockDevices) BuildEC2BlockDeviceMappings() []*ec2.BlockDeviceMapping {
|
2015-04-05 17:58:48 -04:00
|
|
|
var blockDevices []*ec2.BlockDeviceMapping
|
2013-08-15 17:05:08 -04:00
|
|
|
|
2019-06-18 06:37:47 -04:00
|
|
|
for _, blockDevice := range bds {
|
2019-06-18 06:49:54 -04:00
|
|
|
blockDevices = append(blockDevices, blockDevice.BuildEC2BlockDeviceMapping())
|
|
|
|
}
|
|
|
|
return blockDevices
|
|
|
|
}
|
|
|
|
|
|
|
|
func (blockDevice BlockDevice) BuildEC2BlockDeviceMapping() *ec2.BlockDeviceMapping {
|
2015-06-09 12:38:53 -04:00
|
|
|
|
2019-06-18 06:49:54 -04:00
|
|
|
mapping := &ec2.BlockDeviceMapping{
|
|
|
|
DeviceName: aws.String(blockDevice.DeviceName),
|
|
|
|
}
|
|
|
|
|
|
|
|
if blockDevice.NoDevice {
|
|
|
|
mapping.NoDevice = aws.String("")
|
|
|
|
return mapping
|
|
|
|
} else if blockDevice.VirtualName != "" {
|
|
|
|
if strings.HasPrefix(blockDevice.VirtualName, "ephemeral") {
|
|
|
|
mapping.VirtualName = aws.String(blockDevice.VirtualName)
|
2015-04-05 17:58:48 -04:00
|
|
|
}
|
2019-06-18 06:49:54 -04:00
|
|
|
return mapping
|
|
|
|
}
|
2015-04-05 17:58:48 -04:00
|
|
|
|
2019-06-18 06:49:54 -04:00
|
|
|
ebsBlockDevice := &ec2.EbsBlockDevice{
|
|
|
|
DeleteOnTermination: aws.Bool(blockDevice.DeleteOnTermination),
|
2013-08-15 17:05:08 -04:00
|
|
|
}
|
2019-06-18 06:49:54 -04:00
|
|
|
|
|
|
|
if blockDevice.VolumeType != "" {
|
|
|
|
ebsBlockDevice.VolumeType = aws.String(blockDevice.VolumeType)
|
|
|
|
}
|
|
|
|
|
|
|
|
if blockDevice.VolumeSize > 0 {
|
|
|
|
ebsBlockDevice.VolumeSize = aws.Int64(blockDevice.VolumeSize)
|
|
|
|
}
|
|
|
|
|
|
|
|
// IOPS is only valid for io1 type
|
|
|
|
if blockDevice.VolumeType == "io1" {
|
|
|
|
ebsBlockDevice.Iops = aws.Int64(blockDevice.IOPS)
|
|
|
|
}
|
|
|
|
|
|
|
|
// You cannot specify Encrypted if you specify a Snapshot ID
|
|
|
|
if blockDevice.SnapshotId != "" {
|
|
|
|
ebsBlockDevice.SnapshotId = aws.String(blockDevice.SnapshotId)
|
|
|
|
}
|
|
|
|
ebsBlockDevice.Encrypted = blockDevice.Encrypted
|
|
|
|
|
|
|
|
mapping.Ebs = ebsBlockDevice
|
|
|
|
|
|
|
|
return mapping
|
2013-08-15 17:05:08 -04:00
|
|
|
}
|
|
|
|
|
2018-01-12 18:10:51 -05:00
|
|
|
func (b *BlockDevice) Prepare(ctx *interpolate.Context) error {
|
2018-10-12 16:01:13 -04:00
|
|
|
if b.DeviceName == "" {
|
|
|
|
return fmt.Errorf("The `device_name` must be specified " +
|
|
|
|
"for every device in the block device mapping.")
|
|
|
|
}
|
2019-05-03 12:39:52 -04:00
|
|
|
|
2014-09-05 15:38:19 -04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-06-18 06:37:47 -04:00
|
|
|
func (bds BlockDevices) Prepare(ctx *interpolate.Context) (errs []error) {
|
|
|
|
for _, block := range bds {
|
|
|
|
if err := block.Prepare(ctx); err != nil {
|
|
|
|
errs = append(errs, err)
|
2018-01-12 18:10:51 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return errs
|
|
|
|
}
|