mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-07-05 17:52:38 +00:00
Add scratch_disk
property to google_compute_instance
and deprecate disk
(#123)
* Add scratch_disk property to google_compute_instance * docs for scratch_disk * limit scope of scratchDisks array by using bool, test formatting * add slash back to disk check
This commit is contained in:
parent
549e1314f9
commit
32bf0df2d0
|
@ -107,10 +107,27 @@ func resourceComputeInstance() *schema.Resource {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
"disk": &schema.Schema{
|
"scratch_disk": &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"interface": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Default: "SCSI",
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"SCSI", "NVME"}, false),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"disk": &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Deprecated: "Use boot_disk, scratch_disk, and attached_disk instead",
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
// TODO(mitchellh): one of image or disk is required
|
// TODO(mitchellh): one of image or disk is required
|
||||||
|
@ -499,6 +516,15 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err
|
||||||
disks = append(disks, bootDisk)
|
disks = append(disks, bootDisk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hasScratchDisk bool
|
||||||
|
if _, hasScratchDisk := d.GetOk("scratch_disk"); hasScratchDisk {
|
||||||
|
scratchDisks, err := expandScratchDisks(d, config, zone)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
disks = append(disks, scratchDisks...)
|
||||||
|
}
|
||||||
|
|
||||||
disksCount := d.Get("disk.#").(int)
|
disksCount := d.Get("disk.#").(int)
|
||||||
attachedDisksCount := d.Get("attached_disk.#").(int)
|
attachedDisksCount := d.Get("attached_disk.#").(int)
|
||||||
|
|
||||||
|
@ -545,6 +571,9 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err
|
||||||
|
|
||||||
if v, ok := d.GetOk(prefix + ".scratch"); ok {
|
if v, ok := d.GetOk(prefix + ".scratch"); ok {
|
||||||
if v.(bool) {
|
if v.(bool) {
|
||||||
|
if hasScratchDisk {
|
||||||
|
return fmt.Errorf("Cannot set scratch disks using both `scratch_disk` and `disk` properties")
|
||||||
|
}
|
||||||
disk.Type = "SCRATCH"
|
disk.Type = "SCRATCH"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -960,11 +989,12 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
|
||||||
|
|
||||||
disksCount := d.Get("disk.#").(int)
|
disksCount := d.Get("disk.#").(int)
|
||||||
attachedDisksCount := d.Get("attached_disk.#").(int)
|
attachedDisksCount := d.Get("attached_disk.#").(int)
|
||||||
|
scratchDisksCount := d.Get("scratch_disk.#").(int)
|
||||||
|
|
||||||
if _, ok := d.GetOk("boot_disk"); ok {
|
if _, ok := d.GetOk("boot_disk"); ok {
|
||||||
disksCount++
|
disksCount++
|
||||||
}
|
}
|
||||||
if expectedDisks := disksCount + attachedDisksCount; len(instance.Disks) != expectedDisks {
|
if expectedDisks := disksCount + attachedDisksCount + scratchDisksCount; len(instance.Disks) != expectedDisks {
|
||||||
return fmt.Errorf("Expected %d disks, API returned %d", expectedDisks, len(instance.Disks))
|
return fmt.Errorf("Expected %d disks, API returned %d", expectedDisks, len(instance.Disks))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -975,13 +1005,20 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
|
||||||
|
|
||||||
dIndex := 0
|
dIndex := 0
|
||||||
adIndex := 0
|
adIndex := 0
|
||||||
|
sIndex := 0
|
||||||
disks := make([]map[string]interface{}, 0, disksCount)
|
disks := make([]map[string]interface{}, 0, disksCount)
|
||||||
attachedDisks := make([]map[string]interface{}, 0, attachedDisksCount)
|
attachedDisks := make([]map[string]interface{}, 0, attachedDisksCount)
|
||||||
|
scratchDisks := make([]map[string]interface{}, 0, scratchDisksCount)
|
||||||
for _, disk := range instance.Disks {
|
for _, disk := range instance.Disks {
|
||||||
if _, ok := d.GetOk("boot_disk"); ok && disk.Boot {
|
if _, ok := d.GetOk("boot_disk"); ok && disk.Boot {
|
||||||
// This disk is a boot disk and there is a boot disk set in the config, therefore
|
// This disk is a boot disk and there is a boot disk set in the config, therefore
|
||||||
// this is the boot disk set in the config.
|
// this is the boot disk set in the config.
|
||||||
d.Set("boot_disk", flattenBootDisk(d, disk))
|
d.Set("boot_disk", flattenBootDisk(d, disk))
|
||||||
|
} else if _, ok := d.GetOk("scratch_disk"); ok && disk.Type == "SCRATCH" {
|
||||||
|
// This disk is a scratch disk and there are scratch disks set in the config, therefore
|
||||||
|
// this is a scratch disk set in the config.
|
||||||
|
scratchDisks = append(scratchDisks, flattenScratchDisk(disk))
|
||||||
|
sIndex++
|
||||||
} else if _, ok := attachedDiskSources[disk.Source]; !ok {
|
} else if _, ok := attachedDiskSources[disk.Source]; !ok {
|
||||||
di := map[string]interface{}{
|
di := map[string]interface{}{
|
||||||
"disk": d.Get(fmt.Sprintf("disk.%d.disk", dIndex)),
|
"disk": d.Get(fmt.Sprintf("disk.%d.disk", dIndex)),
|
||||||
|
@ -1013,6 +1050,7 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
|
||||||
}
|
}
|
||||||
d.Set("disk", disks)
|
d.Set("disk", disks)
|
||||||
d.Set("attached_disk", attachedDisks)
|
d.Set("attached_disk", attachedDisks)
|
||||||
|
d.Set("scratch_disk", scratchDisks)
|
||||||
|
|
||||||
d.Set("self_link", instance.SelfLink)
|
d.Set("self_link", instance.SelfLink)
|
||||||
d.SetId(instance.Name)
|
d.SetId(instance.Name)
|
||||||
|
@ -1371,3 +1409,32 @@ func flattenBootDisk(d *schema.ResourceData, disk *compute.AttachedDisk) []map[s
|
||||||
|
|
||||||
return []map[string]interface{}{result}
|
return []map[string]interface{}{result}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func expandScratchDisks(d *schema.ResourceData, config *Config, zone *compute.Zone) ([]*compute.AttachedDisk, error) {
|
||||||
|
diskType, err := readDiskType(config, zone, "local-ssd")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Error loading disk type 'local-ssd': %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
n := d.Get("scratch_disk.#").(int)
|
||||||
|
scratchDisks := make([]*compute.AttachedDisk, 0, n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
scratchDisks = append(scratchDisks, &compute.AttachedDisk{
|
||||||
|
AutoDelete: true,
|
||||||
|
Type: "SCRATCH",
|
||||||
|
Interface: d.Get(fmt.Sprintf("scratch_disk.%d.interface", i)).(string),
|
||||||
|
InitializeParams: &compute.AttachedDiskInitializeParams{
|
||||||
|
DiskType: diskType.SelfLink,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return scratchDisks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenScratchDisk(disk *compute.AttachedDisk) map[string]interface{} {
|
||||||
|
result := map[string]interface{}{
|
||||||
|
"interface": disk.Interface,
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
|
@ -347,6 +347,27 @@ func TestAccComputeInstance_local_ssd(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccComputeInstance_scratchDisk(t *testing.T) {
|
||||||
|
var instance compute.Instance
|
||||||
|
var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckComputeInstanceDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccComputeInstance_scratchDisk(instanceName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckComputeInstanceExists(
|
||||||
|
"google_compute_instance.scratch", &instance),
|
||||||
|
testAccCheckComputeInstanceScratchDisk(&instance, []string{"NVME", "SCSI"}),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccComputeInstance_update_deprecated_network(t *testing.T) {
|
func TestAccComputeInstance_update_deprecated_network(t *testing.T) {
|
||||||
var instance compute.Instance
|
var instance compute.Instance
|
||||||
var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
|
var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
|
||||||
|
@ -794,7 +815,7 @@ func testAccCheckComputeInstanceDisk(instance *compute.Instance, source string,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, disk := range instance.Disks {
|
for _, disk := range instance.Disks {
|
||||||
if strings.HasSuffix(disk.Source, source) && disk.AutoDelete == delete && disk.Boot == boot {
|
if strings.HasSuffix(disk.Source, "/"+source) && disk.AutoDelete == delete && disk.Boot == boot {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -821,6 +842,34 @@ func testAccCheckComputeInstanceBootDisk(instance *compute.Instance, source stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccCheckComputeInstanceScratchDisk(instance *compute.Instance, interfaces []string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
if instance.Disks == nil {
|
||||||
|
return fmt.Errorf("no disks")
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for _, disk := range instance.Disks {
|
||||||
|
if disk.Type == "SCRATCH" {
|
||||||
|
if i >= len(interfaces) {
|
||||||
|
return fmt.Errorf("Expected %d scratch disks, found more", len(interfaces))
|
||||||
|
}
|
||||||
|
if disk.Interface != interfaces[i] {
|
||||||
|
return fmt.Errorf("Mismatched interface on scratch disk #%d, expected: %q, found: %q",
|
||||||
|
i, interfaces[i], disk.Interface)
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if i != len(interfaces) {
|
||||||
|
return fmt.Errorf("Expected %d scratch disks, found %d", len(interfaces), i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testAccCheckComputeInstanceDiskEncryptionKey(n string, instance *compute.Instance) resource.TestCheckFunc {
|
func testAccCheckComputeInstanceDiskEncryptionKey(n string, instance *compute.Instance) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
rs, ok := s.RootModule().Resources[n]
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
@ -1380,6 +1429,35 @@ resource "google_compute_instance" "local-ssd" {
|
||||||
`, instance)
|
`, instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccComputeInstance_scratchDisk(instance string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "google_compute_instance" "scratch" {
|
||||||
|
name = "%s"
|
||||||
|
machine_type = "n1-standard-1"
|
||||||
|
zone = "us-central1-a"
|
||||||
|
|
||||||
|
boot_disk {
|
||||||
|
initialize_params {
|
||||||
|
image = "debian-8-jessie-v20160803"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scratch_disk {
|
||||||
|
interface = "NVME"
|
||||||
|
}
|
||||||
|
|
||||||
|
scratch_disk {
|
||||||
|
interface = "SCSI"
|
||||||
|
}
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
network = "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
`, instance)
|
||||||
|
}
|
||||||
|
|
||||||
func testAccComputeInstance_service_account(instance string) string {
|
func testAccComputeInstance_service_account(instance string) string {
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
resource "google_compute_instance" "foobar" {
|
resource "google_compute_instance" "foobar" {
|
||||||
|
|
|
@ -76,6 +76,9 @@ The following arguments are supported:
|
||||||
|
|
||||||
- - -
|
- - -
|
||||||
|
|
||||||
|
* `scratch_disk` - (Optional) Scratch disks to attach to the instance. This can be
|
||||||
|
specified multiple times for multiple scratch disks. Structure is documented below.
|
||||||
|
|
||||||
* `can_ip_forward` - (Optional) Whether to allow sending and receiving of
|
* `can_ip_forward` - (Optional) Whether to allow sending and receiving of
|
||||||
packets with non-matching source or destination IPs.
|
packets with non-matching source or destination IPs.
|
||||||
This defaults to false.
|
This defaults to false.
|
||||||
|
@ -85,9 +88,6 @@ The following arguments are supported:
|
||||||
|
|
||||||
* `description` - (Optional) A brief description of this resource.
|
* `description` - (Optional) A brief description of this resource.
|
||||||
|
|
||||||
* `disk` - (Optional) Disks to attach to the instance. This can be specified
|
|
||||||
multiple times for multiple disks. Structure is documented below.
|
|
||||||
|
|
||||||
* `labels` - (Optional) A set of key/value label pairs to assign to the instance.
|
* `labels` - (Optional) A set of key/value label pairs to assign to the instance.
|
||||||
|
|
||||||
* `metadata` - (Optional) Metadata key/value pairs to make available from
|
* `metadata` - (Optional) Metadata key/value pairs to make available from
|
||||||
|
@ -112,6 +112,9 @@ The following arguments are supported:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
* `disk` - (DEPRECATED) Disks to attach to the instance. This can be specified
|
||||||
|
multiple times for multiple disks. Structure is documented below.
|
||||||
|
|
||||||
* `network` - (DEPRECATED) Networks to attach to the instance. This
|
* `network` - (DEPRECATED) Networks to attach to the instance. This
|
||||||
can be specified multiple times for multiple networks. Structure is
|
can be specified multiple times for multiple networks. Structure is
|
||||||
documented below.
|
documented below.
|
||||||
|
@ -151,7 +154,12 @@ The `initialize_params` block supports:
|
||||||
`global/images/family/{family}`, `family/{family}`, `{project}/{family}`,
|
`global/images/family/{family}`, `family/{family}`, `{project}/{family}`,
|
||||||
`{project}/{image}`, `{family}`, or `{image}`.
|
`{project}/{image}`, `{family}`, or `{image}`.
|
||||||
|
|
||||||
The `disk` block supports: (Note that either disk or image is required, unless
|
The `scratch_disk` block supports:
|
||||||
|
|
||||||
|
* `interface` - (Optional) The disk interface to use for attaching this disk; either SCSI or NVME.
|
||||||
|
Defaults to SCSI.
|
||||||
|
|
||||||
|
(DEPRECATED) The `disk` block supports: (Note that either disk or image is required, unless
|
||||||
the type is "local-ssd", in which case scratch must be true).
|
the type is "local-ssd", in which case scratch must be true).
|
||||||
|
|
||||||
* `disk` - The name of the existing disk (such as those managed by
|
* `disk` - The name of the existing disk (such as those managed by
|
||||||
|
|
Loading…
Reference in New Issue
Block a user