Merge pull request #1277 from hashicorp/f-aws-derive-root-device-name

providers/aws: derive instance root_block_device name
This commit is contained in:
Paul Hinze 2015-03-25 15:15:05 -05:00
commit 6b02cfb700
3 changed files with 31 additions and 23 deletions

View File

@ -265,13 +265,6 @@ func resourceAwsInstance() *schema.Resource {
ForceNew: true,
},
"device_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Default: "/dev/sda1",
},
"iops": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
@ -298,7 +291,6 @@ func resourceAwsInstance() *schema.Resource {
var buf bytes.Buffer
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%t-", m["delete_on_termination"].(bool)))
buf.WriteString(fmt.Sprintf("%s-", m["device_name"].(string)))
// See the NOTE in "ebs_block_device" for why we skip iops here.
// buf.WriteString(fmt.Sprintf("%d-", m["iops"].(int)))
buf.WriteString(fmt.Sprintf("%d-", m["volume_size"].(int)))
@ -478,10 +470,14 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error {
ebs.IOPS = aws.Integer(v)
}
blockDevices = append(blockDevices, ec2.BlockDeviceMapping{
DeviceName: aws.String(bd["device_name"].(string)),
EBS: ebs,
})
if dn, err := fetchRootDeviceName(d.Get("ami").(string), ec2conn); err == nil {
blockDevices = append(blockDevices, ec2.BlockDeviceMapping{
DeviceName: dn,
EBS: ebs,
})
} else {
return err
}
}
}
@ -778,9 +774,6 @@ func readBlockDevicesFromInstance(instance *ec2.Instance, ec2conn *ec2.EC2) (map
if instanceBd.EBS != nil && instanceBd.EBS.DeleteOnTermination != nil {
bd["delete_on_termination"] = *instanceBd.EBS.DeleteOnTermination
}
if instanceBd.DeviceName != nil {
bd["device_name"] = *instanceBd.DeviceName
}
if vol.Size != nil {
bd["volume_size"] = *vol.Size
}
@ -794,6 +787,9 @@ func readBlockDevicesFromInstance(instance *ec2.Instance, ec2conn *ec2.EC2) (map
if blockDeviceIsRoot(instanceBd, instance) {
blockDevices["root"] = bd
} else {
if instanceBd.DeviceName != nil {
bd["device_name"] = *instanceBd.DeviceName
}
if vol.Encrypted != nil {
bd["encrypted"] = *vol.Encrypted
}
@ -813,3 +809,21 @@ func blockDeviceIsRoot(bd ec2.InstanceBlockDeviceMapping, instance *ec2.Instance
instance.RootDeviceName != nil &&
*bd.DeviceName == *instance.RootDeviceName)
}
func fetchRootDeviceName(ami string, conn *ec2.EC2) (aws.StringValue, error) {
if ami == "" {
return nil, fmt.Errorf("Cannot fetch root device name for blank AMI ID.")
}
log.Printf("[DEBUG] Describing AMI %q to get root block device name", ami)
req := &ec2.DescribeImagesRequest{ImageIDs: []string{ami}}
if res, err := conn.DescribeImages(req); err == nil {
if len(res.Images) == 1 {
return res.Images[0].RootDeviceName, nil
} else {
return nil, fmt.Errorf("Expected 1 AMI for ID: %s, got: %#v", ami, res.Images)
}
} else {
return nil, err
}
}

View File

@ -140,11 +140,9 @@ func TestAccAWSInstance_blockDevices(t *testing.T) {
resource.TestCheckResourceAttr(
"aws_instance.foo", "root_block_device.#", "1"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "root_block_device.1246122048.device_name", "/dev/sda1"),
"aws_instance.foo", "root_block_device.1023169747.volume_size", "11"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "root_block_device.1246122048.volume_size", "11"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "root_block_device.1246122048.volume_type", "gp2"),
"aws_instance.foo", "root_block_device.1023169747.volume_type", "gp2"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "ebs_block_device.#", "2"),
resource.TestCheckResourceAttr(
@ -467,7 +465,6 @@ resource "aws_instance" "foo" {
instance_type = "m1.small"
root_block_device {
device_name = "/dev/sda1"
volume_type = "gp2"
volume_size = 11
}

View File

@ -66,9 +66,6 @@ to understand the implications of using these attributes.
The `root_block_device` mapping supports the following:
* `device_name` - The name of the root device on the target instance. Must
match the root device as defined in the AMI. Defaults to `"/dev/sda1"`, which
is the typical root volume for Linux instances.
* `volume_type` - (Optional) The type of volume. Can be `"standard"`, `"gp2"`,
or `"io1"`. (Default: `"standard"`).
* `volume_size` - (Optional) The size of the volume in gigabytes.