Commit 91670cea authored by Mark Peek's avatar Mark Peek

builder/amazon: add block device mappings [GH-90]

parent c0721bc3
package common
import (
"github.com/mitchellh/goamz/ec2"
)
// BlockDevice
type BlockDevice struct {
DeviceName string `mapstructure:"device_name"`
VirtualName string `mapstructure:"virtual_name"`
SnapshotId string `mapstructure:"snapshot_id"`
VolumeType string `mapstructure:"volume_type"`
VolumeSize int64 `mapstructure:"volume_size"`
DeleteOnTermination bool `mapstructure:"delete_on_termination"`
IOPS int64 `mapstructure:"iops"`
}
type BlockDevices struct {
AMIMappings []BlockDevice `mapstructure:"ami_block_device_mappings,squash"`
LaunchMappings []BlockDevice `mapstructure:"launch_block_device_mappings,squash"`
}
func buildBlockDevices(b []BlockDevice) []ec2.BlockDeviceMapping {
var blockDevices []ec2.BlockDeviceMapping
for _, blockDevice := range b {
blockDevices = append(blockDevices, ec2.BlockDeviceMapping{
DeviceName: blockDevice.DeviceName,
VirtualName: blockDevice.VirtualName,
SnapshotId: blockDevice.SnapshotId,
VolumeType: blockDevice.VolumeType,
VolumeSize: blockDevice.VolumeSize,
DeleteOnTermination: blockDevice.DeleteOnTermination,
IOPS: blockDevice.IOPS,
})
}
return blockDevices
}
func (b *BlockDevices) BuildAMIDevices() []ec2.BlockDeviceMapping {
return buildBlockDevices(b.AMIMappings)
}
func (b *BlockDevices) BuildLaunchDevices() []ec2.BlockDeviceMapping {
return buildBlockDevices(b.LaunchMappings)
}
package common
import (
"cgl.tideland.biz/asserts"
"github.com/mitchellh/goamz/ec2"
"testing"
)
func TestBlockDevice(t *testing.T) {
assert := asserts.NewTestingAsserts(t, true)
ec2Mapping := []ec2.BlockDeviceMapping{
ec2.BlockDeviceMapping{
DeviceName: "/dev/sdb",
VirtualName: "ephemeral0",
SnapshotId: "snap-1234",
VolumeType: "standard",
VolumeSize: 8,
DeleteOnTermination: true,
IOPS: 1000,
},
}
blockDevice := BlockDevice{
DeviceName: "/dev/sdb",
VirtualName: "ephemeral0",
SnapshotId: "snap-1234",
VolumeType: "standard",
VolumeSize: 8,
DeleteOnTermination: true,
IOPS: 1000,
}
blockDevices := BlockDevices{
AMIMappings: []BlockDevice{blockDevice},
LaunchMappings: []BlockDevice{blockDevice},
}
assert.Equal(ec2Mapping, blockDevices.BuildAMIDevices(), "should match output")
assert.Equal(ec2Mapping, blockDevices.BuildLaunchDevices(), "should match output")
}
...@@ -17,6 +17,7 @@ type StepRunSourceInstance struct { ...@@ -17,6 +17,7 @@ type StepRunSourceInstance struct {
SourceAMI string SourceAMI string
IamInstanceProfile string IamInstanceProfile string
SubnetId string SubnetId string
BlockDevices BlockDevices
instance *ec2.Instance instance *ec2.Instance
} }
...@@ -48,6 +49,7 @@ func (s *StepRunSourceInstance) Run(state map[string]interface{}) multistep.Step ...@@ -48,6 +49,7 @@ func (s *StepRunSourceInstance) Run(state map[string]interface{}) multistep.Step
SecurityGroups: []ec2.SecurityGroup{ec2.SecurityGroup{Id: securityGroupId}}, SecurityGroups: []ec2.SecurityGroup{ec2.SecurityGroup{Id: securityGroupId}},
IamInstanceProfile: s.IamInstanceProfile, IamInstanceProfile: s.IamInstanceProfile,
SubnetId: s.SubnetId, SubnetId: s.SubnetId,
BlockDevices: s.BlockDevices.BuildLaunchDevices(),
} }
ui.Say("Launching a source AWS instance...") ui.Say("Launching a source AWS instance...")
......
...@@ -22,6 +22,7 @@ type config struct { ...@@ -22,6 +22,7 @@ type config struct {
common.PackerConfig `mapstructure:",squash"` common.PackerConfig `mapstructure:",squash"`
awscommon.AccessConfig `mapstructure:",squash"` awscommon.AccessConfig `mapstructure:",squash"`
awscommon.AMIConfig `mapstructure:",squash"` awscommon.AMIConfig `mapstructure:",squash"`
awscommon.BlockDevices `mapstructure:",squash"`
awscommon.RunConfig `mapstructure:",squash"` awscommon.RunConfig `mapstructure:",squash"`
// Tags for the AMI // Tags for the AMI
...@@ -119,6 +120,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -119,6 +120,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
SourceAMI: b.config.SourceAmi, SourceAMI: b.config.SourceAmi,
IamInstanceProfile: b.config.IamInstanceProfile, IamInstanceProfile: b.config.IamInstanceProfile,
SubnetId: b.config.SubnetId, SubnetId: b.config.SubnetId,
BlockDevices: b.config.BlockDevices,
}, },
&common.StepConnectSSH{ &common.StepConnectSSH{
SSHAddress: awscommon.SSHAddress(ec2conn, b.config.SSHPort), SSHAddress: awscommon.SSHAddress(ec2conn, b.config.SSHPort),
......
...@@ -19,8 +19,9 @@ func (s *stepCreateAMI) Run(state map[string]interface{}) multistep.StepAction { ...@@ -19,8 +19,9 @@ func (s *stepCreateAMI) Run(state map[string]interface{}) multistep.StepAction {
// Create the image // Create the image
ui.Say(fmt.Sprintf("Creating the AMI: %s", config.AMIName)) ui.Say(fmt.Sprintf("Creating the AMI: %s", config.AMIName))
createOpts := &ec2.CreateImage{ createOpts := &ec2.CreateImage{
InstanceId: instance.InstanceId, InstanceId: instance.InstanceId,
Name: config.AMIName, Name: config.AMIName,
BlockDevices: config.BlockDevices.BuildAMIDevices(),
} }
createResp, err := ec2conn.CreateImage(createOpts) createResp, err := ec2conn.CreateImage(createOpts)
......
...@@ -24,6 +24,7 @@ type Config struct { ...@@ -24,6 +24,7 @@ type Config struct {
common.PackerConfig `mapstructure:",squash"` common.PackerConfig `mapstructure:",squash"`
awscommon.AccessConfig `mapstructure:",squash"` awscommon.AccessConfig `mapstructure:",squash"`
awscommon.AMIConfig `mapstructure:",squash"` awscommon.AMIConfig `mapstructure:",squash"`
awscommon.BlockDevices `mapstructure:",squash"`
awscommon.RunConfig `mapstructure:",squash"` awscommon.RunConfig `mapstructure:",squash"`
AccountId string `mapstructure:"account_id"` AccountId string `mapstructure:"account_id"`
...@@ -198,6 +199,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -198,6 +199,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
UserDataFile: b.config.UserDataFile, UserDataFile: b.config.UserDataFile,
SourceAMI: b.config.SourceAmi, SourceAMI: b.config.SourceAmi,
SubnetId: b.config.SubnetId, SubnetId: b.config.SubnetId,
BlockDevices: b.config.BlockDevices,
}, },
&common.StepConnectSSH{ &common.StepConnectSSH{
SSHAddress: awscommon.SSHAddress(ec2conn, b.config.SSHPort), SSHAddress: awscommon.SSHAddress(ec2conn, b.config.SSHPort),
......
...@@ -20,6 +20,7 @@ func (s *StepRegisterAMI) Run(state map[string]interface{}) multistep.StepAction ...@@ -20,6 +20,7 @@ func (s *StepRegisterAMI) Run(state map[string]interface{}) multistep.StepAction
registerOpts := &ec2.RegisterImage{ registerOpts := &ec2.RegisterImage{
ImageLocation: manifestPath, ImageLocation: manifestPath,
Name: config.AMIName, Name: config.AMIName,
BlockDevices: config.BlockDevices.BuildAMIDevices(),
} }
registerResp, err := ec2conn.RegisterImage(registerOpts) registerResp, err := ec2conn.RegisterImage(registerOpts)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment