Skip to content

Commit

Permalink
provider/aws: Add "no_device" support to ephemeral block devices
Browse files Browse the repository at this point in the history
Fixes #8455, #5390

This add a new `no_device` attribute to `ephemeral_block_device` block,
which allows users omit ephemeral devices from AMI's predefined block
device mappings, which is useful for EBS-only instance types.
  • Loading branch information
timonwong committed Dec 6, 2016
1 parent b131d3d commit 3b84fe5
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 8 deletions.
27 changes: 21 additions & 6 deletions builtin/providers/aws/resource_aws_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,25 @@ func resourceAwsInstance() *schema.Resource {

"virtual_name": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
},

"no_device": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
},
Set: func(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%s-", m["device_name"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["virtual_name"].(string)))
if m["no_device"].(bool) {
buf.WriteString(fmt.Sprintf("%t-", m["no_device"].(bool)))
} else {
buf.WriteString(fmt.Sprintf("%s-", m["virtual_name"].(string)))
}
return hashcode.String(buf.String())
},
},
Expand Down Expand Up @@ -936,10 +946,15 @@ func readBlockDeviceMappingsFromConfig(
vL := v.(*schema.Set).List()
for _, v := range vL {
bd := v.(map[string]interface{})
blockDevices = append(blockDevices, &ec2.BlockDeviceMapping{
DeviceName: aws.String(bd["device_name"].(string)),
VirtualName: aws.String(bd["virtual_name"].(string)),
})
bdm := &ec2.BlockDeviceMapping{
DeviceName: aws.String(bd["device_name"].(string)),
}
if bd["no_device"].(bool) {
bdm.NoDevice = aws.String("")
} else {
bdm.VirtualName = aws.String(bd["virtual_name"].(string))
}
blockDevices = append(blockDevices, bdm)
}
}

Expand Down
64 changes: 64 additions & 0 deletions builtin/providers/aws/resource_aws_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,70 @@ func TestAccAWSInstance_rootInstanceStore(t *testing.T) {
})
}

func TestAcctABSInstance_noAMIEphemeralDevices(t *testing.T) {
var v ec2.Instance

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: "aws_instance.foo",
IDRefreshIgnore: []string{
"ephemeral_block_device", "security_groups", "vpc_security_groups"},
Providers: testAccProviders,
CheckDestroy: testAccCheckInstanceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: `
resource "aws_instance" "foo" {
# us-west-2
ami = "ami-01f05461" // This AMI (Ubuntu) contains two ephemerals
instance_type = "m4.medium"
root_block_device {
volume_type = "gp2"
volume_size = 11
}
ephemeral_block_device {
device_name = "/dev/sdb"
no_device = true
}
ephemeral_block_device {
device_name = "/dev/sdc"
no_device = true
}`,
Check: resource.ComposeTestCheckFunc(
testAccCheckInstanceExists(
"aws_instance.foo", &v),
resource.TestCheckResourceAttr(
"aws_instance.foo", "ami", "ami-01f05461"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "ebs_optimized", "false"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "instance_type", "m4.medium"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "root_block_device.#", "1"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "root_block_device.0.volume_size", "11"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "root_block_device.0.volume_type", "gp2"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "ebs_block_device.#", "0"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "ephemeral_block_device.#", "2"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "ephemeral_block_device.1689158549.device_name", "/dev/sdb"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "ephemeral_block_device.1689158549.no_device", "true"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "ephemeral_block_device.1025931231.device_name", "/dev/sdc"),
resource.TestCheckResourceAttr(
"aws_instance.foo", "ephemeral_block_device.1025931231.no_device", "true"),
),
},
},
})
}

func TestAccAWSInstance_sourceDestCheck(t *testing.T) {
var v ec2.Instance

Expand Down
5 changes: 3 additions & 2 deletions website/source/docs/providers/aws/r/instance.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,10 @@ Modifying any `ebs_block_device` currently requires resource replacement.
Each `ephemeral_block_device` supports the following:

* `device_name` - The name of the block device to mount on the instance.
* `virtual_name` - The [Instance Store Device
* `virtual_name` - (Optional) The [Instance Store Device
Name](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html#InstanceStoreDeviceNames)
(e.g. `"ephemeral0"`)
(e.g. `"ephemeral0"`).
* `no_device` - (Optional) Suppresses the specified device included in the AMI's block device mapping.

Each AWS Instance type has a different set of Instance Store block devices
available for attachment. AWS [publishes a
Expand Down

0 comments on commit 3b84fe5

Please sign in to comment.