//go:generate struct-markdown package common import ( "fmt" "strings" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/template/interpolate" ) // TODO(adrien): doc correctly type BlockDevice struct { // 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. DeleteOnTermination bool `mapstructure:"delete_on_termination" required:"false"` // The device name exposed to the instance (for example, /dev/sdh or xvdh). // Required for every device in the block device mapping. DeviceName string `mapstructure:"device_name" required:"false"` // 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. Encrypted *bool `mapstructure:"encrypted" required:"false"` // The number of I/O operations per second (IOPS) that the volume supports. // See the documentation on IOPs for more information IOPS int64 `mapstructure:"iops" required:"false"` // Suppresses the specified device included in the block device mapping of // the AMI. NoDevice bool `mapstructure:"no_device" required:"false"` // The ID of the snapshot. SnapshotId string `mapstructure:"snapshot_id" required:"false"` // The virtual device name. See the documentation on Block Device Mapping // for more information. VirtualName string `mapstructure:"virtual_name" required:"false"` // 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. VolumeType string `mapstructure:"volume_type" required:"false"` // The size of the volume, in GiB. Required if not specifying a // snapshot_id. VolumeSize int64 `mapstructure:"volume_size" required:"false"` // ebssurrogate only OmitFromArtifact bool `mapstructure:"omit_from_artifact"` } type BlockDevices []BlockDevice func (bds BlockDevices) BuildEC2BlockDeviceMappings() []*ec2.BlockDeviceMapping { var blockDevices []*ec2.BlockDeviceMapping for _, blockDevice := range bds { blockDevices = append(blockDevices, blockDevice.BuildEC2BlockDeviceMapping()) } return blockDevices } func (blockDevice BlockDevice) BuildEC2BlockDeviceMapping() *ec2.BlockDeviceMapping { 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) } return mapping } ebsBlockDevice := &ec2.EbsBlockDevice{ DeleteOnTermination: aws.Bool(blockDevice.DeleteOnTermination), } 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 } func (b *BlockDevice) Prepare(ctx *interpolate.Context) error { if b.DeviceName == "" { return fmt.Errorf("The `device_name` must be specified " + "for every device in the block device mapping.") } return nil } func (bds BlockDevices) Prepare(ctx *interpolate.Context) (errs []error) { for _, block := range bds { if err := block.Prepare(ctx); err != nil { errs = append(errs, err) } } return errs } func (b BlockDevices) GetOmissions() map[string]bool { omitMap := make(map[string]bool) for _, blockDevice := range b { omitMap[blockDevice.DeviceName] = blockDevice.OmitFromArtifact } return omitMap }