2014-08-25 18:48:20 +00:00
package google
2014-08-25 21:57:17 +00:00
import (
2017-09-07 14:04:26 +00:00
"crypto/sha256"
"encoding/base64"
2014-08-25 21:57:17 +00:00
"fmt"
"log"
2015-12-16 23:33:00 +00:00
"strings"
2014-08-25 21:57:17 +00:00
2018-01-24 20:50:39 +00:00
"time"
2017-11-02 20:08:02 +00:00
"github.com/hashicorp/errwrap"
2018-01-23 19:51:36 +00:00
"github.com/hashicorp/terraform/helper/customdiff"
2014-08-25 18:48:20 +00:00
"github.com/hashicorp/terraform/helper/schema"
2017-06-28 22:36:00 +00:00
"github.com/hashicorp/terraform/helper/validation"
2017-11-02 20:08:02 +00:00
"github.com/mitchellh/hashstructure"
2017-08-22 19:49:43 +00:00
computeBeta "google.golang.org/api/compute/v0.beta"
2015-03-18 17:10:39 +00:00
"google.golang.org/api/compute/v1"
2017-06-19 22:03:46 +00:00
"google.golang.org/api/googleapi"
2014-08-25 18:48:20 +00:00
)
func resourceComputeInstance ( ) * schema . Resource {
return & schema . Resource {
Create : resourceComputeInstanceCreate ,
2014-08-25 21:57:17 +00:00
Read : resourceComputeInstanceRead ,
2014-08-26 20:48:49 +00:00
Update : resourceComputeInstanceUpdate ,
2014-08-25 21:57:17 +00:00
Delete : resourceComputeInstanceDelete ,
2017-12-19 22:33:30 +00:00
Importer : & schema . ResourceImporter {
State : resourceComputeInstanceImportState ,
} ,
2014-08-25 21:57:17 +00:00
2017-11-03 22:25:54 +00:00
SchemaVersion : 6 ,
2015-04-14 00:04:10 +00:00
MigrateState : resourceComputeInstanceMigrateState ,
2017-12-14 01:03:15 +00:00
Timeouts : & schema . ResourceTimeout {
Create : schema . DefaultTimeout ( 6 * time . Minute ) ,
Update : schema . DefaultTimeout ( 6 * time . Minute ) ,
Delete : schema . DefaultTimeout ( 6 * time . Minute ) ,
} ,
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
// A compute instance is more or less a superset of a compute instance
// template. Please attempt to maintain consistency with the
// resource_compute_instance_template schema when updating this one.
2014-08-25 21:57:17 +00:00
Schema : map [ string ] * schema . Schema {
2017-06-28 22:36:00 +00:00
"boot_disk" : & schema . Schema {
Type : schema . TypeList ,
2017-10-23 19:53:41 +00:00
Required : true ,
2017-06-28 22:36:00 +00:00
ForceNew : true ,
MaxItems : 1 ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"auto_delete" : & schema . Schema {
Type : schema . TypeBool ,
Optional : true ,
Default : true ,
ForceNew : true ,
} ,
"device_name" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
ForceNew : true ,
} ,
"disk_encryption_key_raw" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
ForceNew : true ,
Sensitive : true ,
} ,
"disk_encryption_key_sha256" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
} ,
"initialize_params" : & schema . Schema {
Type : schema . TypeList ,
Optional : true ,
2018-01-17 21:23:24 +00:00
Computed : true ,
2017-06-28 22:36:00 +00:00
ForceNew : true ,
MaxItems : 1 ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"size" : & schema . Schema {
2017-08-10 20:01:45 +00:00
Type : schema . TypeInt ,
Optional : true ,
2018-01-17 21:23:24 +00:00
Computed : true ,
2017-08-10 20:01:45 +00:00
ForceNew : true ,
ValidateFunc : validation . IntAtLeast ( 1 ) ,
2017-06-28 22:36:00 +00:00
} ,
"type" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
2018-01-17 21:23:24 +00:00
Computed : true ,
2017-06-28 22:36:00 +00:00
ForceNew : true ,
ValidateFunc : validation . StringInSlice ( [ ] string { "pd-standard" , "pd-ssd" } , false ) ,
} ,
"image" : & schema . Schema {
2018-01-17 21:23:24 +00:00
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
ForceNew : true ,
DiffSuppressFunc : diskImageDiffSuppress ,
2017-06-28 22:36:00 +00:00
} ,
} ,
} ,
} ,
"source" : & schema . Schema {
2017-10-23 20:26:59 +00:00
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
ForceNew : true ,
ConflictsWith : [ ] string { "boot_disk.initialize_params" } ,
DiffSuppressFunc : linkDiffSuppress ,
2017-06-28 22:36:00 +00:00
} ,
} ,
} ,
} ,
2018-06-28 23:09:23 +00:00
"machine_type" : & schema . Schema {
Type : schema . TypeString ,
Required : true ,
} ,
"name" : & schema . Schema {
Type : schema . TypeString ,
Required : true ,
2014-08-25 21:57:17 +00:00
ForceNew : true ,
2017-06-28 22:43:58 +00:00
} ,
2018-06-28 23:09:23 +00:00
"network_interface" : & schema . Schema {
2017-09-29 00:22:29 +00:00
Type : schema . TypeList ,
2018-06-28 23:09:23 +00:00
Required : true ,
2017-09-29 00:22:29 +00:00
ForceNew : true ,
2014-08-25 21:57:17 +00:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
2018-06-28 23:09:23 +00:00
"network" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
ForceNew : true ,
DiffSuppressFunc : compareSelfLinkOrResourceName ,
} ,
2014-08-26 04:35:23 +00:00
2018-06-28 23:09:23 +00:00
"subnetwork" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
ForceNew : true ,
DiffSuppressFunc : compareSelfLinkOrResourceName ,
2014-08-26 04:35:23 +00:00
} ,
2018-06-28 23:09:23 +00:00
"subnetwork_project" : & schema . Schema {
2014-08-26 04:35:23 +00:00
Type : schema . TypeString ,
Optional : true ,
2018-06-28 23:09:23 +00:00
Computed : true ,
2015-02-13 17:55:16 +00:00
ForceNew : true ,
2014-08-25 21:57:17 +00:00
} ,
2014-10-07 04:59:09 +00:00
2018-06-28 23:09:23 +00:00
"name" : & schema . Schema {
2014-10-07 04:59:09 +00:00
Type : schema . TypeString ,
2018-06-28 23:09:23 +00:00
Computed : true ,
2014-10-07 04:59:09 +00:00
} ,
2018-06-28 23:09:23 +00:00
"address" : & schema . Schema {
Type : schema . TypeString ,
2015-05-12 01:40:37 +00:00
Optional : true ,
ForceNew : true ,
2018-06-28 23:09:23 +00:00
Computed : true ,
2015-05-12 01:40:37 +00:00
} ,
2018-06-28 23:09:23 +00:00
"network_ip" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
ForceNew : true ,
Computed : true ,
Deprecated : "Please use address" ,
2014-09-02 13:52:49 +00:00
} ,
2015-03-24 16:45:20 +00:00
2018-06-28 23:09:23 +00:00
"access_config" : & schema . Schema {
Type : schema . TypeList ,
2015-03-24 16:45:20 +00:00
Optional : true ,
2018-06-28 23:09:23 +00:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"nat_ip" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
} ,
2014-10-16 13:43:52 +00:00
2018-06-28 23:09:23 +00:00
"network_tier" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
ValidateFunc : validation . StringInSlice ( [ ] string { "PREMIUM" , "STANDARD" } , false ) ,
} ,
2017-01-18 13:49:48 +00:00
2018-06-28 23:09:23 +00:00
// It's unclear why this field exists, as
// nat_ip can be both optional and computed.
// Consider deprecating it.
"assigned_nat_ip" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
} ,
"public_ptr_domain_name" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
} ,
} ,
} ,
2017-01-18 13:49:48 +00:00
} ,
2018-06-28 23:09:23 +00:00
"alias_ip_range" : & schema . Schema {
Type : schema . TypeList ,
MaxItems : 1 ,
Optional : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"ip_cidr_range" : & schema . Schema {
Type : schema . TypeString ,
Required : true ,
DiffSuppressFunc : ipCidrRangeDiffSuppress ,
} ,
"subnetwork_range_name" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
} ,
} ,
} ,
2017-01-18 13:49:48 +00:00
} ,
2014-08-25 21:57:17 +00:00
} ,
} ,
} ,
2014-08-25 18:48:20 +00:00
2018-06-28 23:09:23 +00:00
"allow_stopping_for_update" : & schema . Schema {
Type : schema . TypeBool ,
Optional : true ,
} ,
2017-04-25 20:20:02 +00:00
"attached_disk" : & schema . Schema {
Type : schema . TypeList ,
Optional : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"source" : & schema . Schema {
2017-10-23 20:26:59 +00:00
Type : schema . TypeString ,
Required : true ,
2018-07-11 00:10:05 +00:00
DiffSuppressFunc : compareSelfLinkOrResourceName ,
2017-04-25 20:20:02 +00:00
} ,
"device_name" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
} ,
2018-02-12 18:56:06 +00:00
"mode" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Default : "READ_WRITE" ,
ValidateFunc : validation . StringInSlice ( [ ] string { "READ_WRITE" , "READ_ONLY" } , false ) ,
} ,
2017-04-25 20:20:02 +00:00
"disk_encryption_key_raw" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Sensitive : true ,
} ,
"disk_encryption_key_sha256" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
} ,
} ,
} ,
} ,
2016-04-10 21:34:15 +00:00
"can_ip_forward" : & schema . Schema {
Type : schema . TypeBool ,
Optional : true ,
Default : false ,
ForceNew : true ,
} ,
2018-06-28 23:09:23 +00:00
"create_timeout" : & schema . Schema {
Type : schema . TypeInt ,
Optional : true ,
Default : 4 ,
Deprecated : "Use timeouts block instead." ,
2016-04-10 21:34:15 +00:00
} ,
2018-06-28 23:09:23 +00:00
"description" : & schema . Schema {
2016-04-10 21:34:15 +00:00
Type : schema . TypeString ,
Optional : true ,
ForceNew : true ,
} ,
2018-06-28 23:09:23 +00:00
"deletion_protection" : & schema . Schema {
Type : schema . TypeBool ,
Optional : true ,
Default : false ,
2016-04-10 21:34:15 +00:00
} ,
2018-06-28 23:09:23 +00:00
"disk" : & schema . Schema {
2015-02-06 08:21:22 +00:00
Type : schema . TypeList ,
2018-06-28 23:09:23 +00:00
Optional : true ,
2015-02-06 08:21:22 +00:00
ForceNew : true ,
2018-06-28 23:09:23 +00:00
Removed : "Use boot_disk, scratch_disk, and attached_disk instead" ,
2015-02-06 08:21:22 +00:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
2018-06-28 23:09:23 +00:00
// TODO(mitchellh): one of image or disk is required
2016-02-15 03:17:55 +00:00
2018-06-28 23:09:23 +00:00
"disk" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
ForceNew : true ,
2015-02-06 08:21:22 +00:00
} ,
2018-06-28 23:09:23 +00:00
"image" : & schema . Schema {
2016-10-27 15:25:58 +00:00
Type : schema . TypeString ,
Optional : true ,
ForceNew : true ,
} ,
2018-06-28 23:09:23 +00:00
"type" : & schema . Schema {
2015-02-06 08:21:22 +00:00
Type : schema . TypeString ,
2018-06-28 23:09:23 +00:00
Optional : true ,
ForceNew : true ,
2015-02-06 08:21:22 +00:00
} ,
2018-06-28 23:09:23 +00:00
"scratch" : & schema . Schema {
Type : schema . TypeBool ,
2016-08-08 01:01:31 +00:00
Optional : true ,
ForceNew : true ,
2015-02-06 08:21:22 +00:00
} ,
2018-06-28 23:09:23 +00:00
"auto_delete" : & schema . Schema {
Type : schema . TypeBool ,
Optional : true ,
Default : true ,
ForceNew : true ,
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
} ,
2018-06-28 23:09:23 +00:00
"size" : & schema . Schema {
Type : schema . TypeInt ,
2015-02-06 08:21:22 +00:00
Optional : true ,
2018-06-28 23:09:23 +00:00
ForceNew : true ,
} ,
2015-12-11 16:41:02 +00:00
2018-06-28 23:09:23 +00:00
"device_name" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
} ,
2018-06-05 19:35:44 +00:00
2018-06-28 23:09:23 +00:00
"disk_encryption_key_raw" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
ForceNew : true ,
Sensitive : true ,
} ,
2018-04-20 18:14:38 +00:00
2018-06-28 23:09:23 +00:00
"disk_encryption_key_sha256" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
2015-02-06 08:21:22 +00:00
} ,
2018-06-28 23:09:23 +00:00
} ,
} ,
} ,
2017-09-07 20:43:00 +00:00
2018-06-28 23:09:23 +00:00
"guest_accelerator" : & schema . Schema {
Type : schema . TypeList ,
Optional : true ,
Computed : true ,
ForceNew : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"count" : & schema . Schema {
Type : schema . TypeInt ,
Required : true ,
ForceNew : true ,
} ,
"type" : & schema . Schema {
Type : schema . TypeString ,
Required : true ,
ForceNew : true ,
DiffSuppressFunc : linkDiffSuppress ,
2017-09-07 20:43:00 +00:00
} ,
2015-02-06 08:21:22 +00:00
} ,
} ,
} ,
2018-06-28 23:09:23 +00:00
"labels" : & schema . Schema {
Type : schema . TypeMap ,
Optional : true ,
Elem : & schema . Schema { Type : schema . TypeString } ,
Set : schema . HashString ,
} ,
"metadata" : & schema . Schema {
Type : schema . TypeMap ,
Optional : true ,
Elem : schema . TypeString ,
} ,
"metadata_startup_script" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
ForceNew : true ,
} ,
"min_cpu_platform" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
} ,
2014-08-25 21:57:17 +00:00
"network" : & schema . Schema {
2017-09-28 21:38:38 +00:00
Type : schema . TypeList ,
Optional : true ,
ForceNew : true ,
Removed : "Please use network_interface" ,
2014-08-25 21:57:17 +00:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"source" : & schema . Schema {
Type : schema . TypeString ,
Required : true ,
2015-02-06 08:21:22 +00:00
ForceNew : true ,
2014-08-25 21:57:17 +00:00
} ,
2014-08-25 22:47:21 +00:00
"address" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
2015-02-06 08:21:22 +00:00
ForceNew : true ,
2014-08-25 22:47:21 +00:00
} ,
2014-08-25 23:23:28 +00:00
"name" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
} ,
2014-10-19 06:17:14 +00:00
2014-08-25 23:23:28 +00:00
"internal_address" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
} ,
2014-10-19 06:17:14 +00:00
2014-10-19 06:03:37 +00:00
"external_address" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
} ,
2014-08-25 21:57:17 +00:00
} ,
} ,
} ,
2014-08-25 22:10:30 +00:00
2016-04-10 21:34:15 +00:00
"project" : & schema . Schema {
Type : schema . TypeString ,
2014-10-07 16:24:13 +00:00
Optional : true ,
2017-11-28 00:32:20 +00:00
Computed : true ,
2014-10-07 16:24:13 +00:00
ForceNew : true ,
} ,
2016-04-10 21:34:15 +00:00
"scheduling" : & schema . Schema {
Type : schema . TypeList ,
2017-08-03 20:51:45 +00:00
MaxItems : 1 ,
2016-04-10 21:34:15 +00:00
Optional : true ,
2017-08-03 20:51:45 +00:00
Computed : true ,
2016-04-10 21:34:15 +00:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"on_host_maintenance" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
2017-08-03 20:51:45 +00:00
Computed : true ,
2016-04-10 21:34:15 +00:00
} ,
"automatic_restart" : & schema . Schema {
Type : schema . TypeBool ,
Optional : true ,
2017-08-03 20:51:45 +00:00
Default : true ,
2016-04-10 21:34:15 +00:00
} ,
"preemptible" : & schema . Schema {
Type : schema . TypeBool ,
Optional : true ,
2017-08-03 20:51:45 +00:00
Default : false ,
ForceNew : true ,
2016-04-10 21:34:15 +00:00
} ,
} ,
} ,
2014-08-25 22:25:45 +00:00
} ,
2018-06-28 23:09:23 +00:00
"scratch_disk" : & schema . Schema {
Type : schema . TypeList ,
Optional : 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 ) ,
} ,
} ,
} ,
} ,
2014-10-07 08:16:50 +00:00
"service_account" : & schema . Schema {
Type : schema . TypeList ,
2016-08-04 21:12:52 +00:00
MaxItems : 1 ,
2014-10-07 08:16:50 +00:00
Optional : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"email" : & schema . Schema {
Type : schema . TypeString ,
2016-08-04 21:12:52 +00:00
Optional : true ,
Computed : true ,
2014-10-07 08:16:50 +00:00
} ,
"scopes" : & schema . Schema {
2015-05-01 01:21:21 +00:00
Type : schema . TypeSet ,
2015-01-28 21:38:02 +00:00
Required : true ,
Elem : & schema . Schema {
Type : schema . TypeString ,
2014-10-07 08:16:50 +00:00
StateFunc : func ( v interface { } ) string {
return canonicalizeServiceScope ( v . ( string ) )
} ,
} ,
2015-05-01 01:21:21 +00:00
Set : stringScopeHashcode ,
2014-10-07 08:16:50 +00:00
} ,
} ,
} ,
} ,
2018-06-28 23:09:23 +00:00
"tags" : & schema . Schema {
Type : schema . TypeSet ,
Optional : true ,
Elem : & schema . Schema { Type : schema . TypeString } ,
Set : schema . HashString ,
} ,
"zone" : & schema . Schema {
Type : schema . TypeString ,
2017-08-22 19:49:43 +00:00
Optional : true ,
2018-01-23 19:51:36 +00:00
Computed : true ,
2017-08-22 19:49:43 +00:00
ForceNew : true ,
} ,
2017-08-30 21:25:31 +00:00
"cpu_platform" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
} ,
2018-06-28 23:09:23 +00:00
"instance_id" : & schema . Schema {
2017-08-30 21:25:31 +00:00
Type : schema . TypeString ,
2018-06-28 23:09:23 +00:00
Computed : true ,
2014-08-25 22:10:30 +00:00
} ,
2014-08-26 20:48:49 +00:00
2018-06-28 23:09:23 +00:00
"label_fingerprint" : & schema . Schema {
2014-08-26 20:52:18 +00:00
Type : schema . TypeString ,
Computed : true ,
} ,
2016-11-13 02:01:32 +00:00
2018-06-28 23:09:23 +00:00
"metadata_fingerprint" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
2018-03-16 18:57:42 +00:00
} ,
2018-06-28 23:09:23 +00:00
"self_link" : & schema . Schema {
2017-06-19 22:00:34 +00:00
Type : schema . TypeString ,
Computed : true ,
} ,
2018-06-28 23:09:23 +00:00
"tags_fingerprint" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
2016-11-13 02:01:32 +00:00
} ,
2014-08-25 21:57:17 +00:00
} ,
2018-01-23 19:51:36 +00:00
CustomizeDiff : customdiff . All (
customdiff . If (
func ( d * schema . ResourceDiff , meta interface { } ) bool {
return d . HasChange ( "guest_accelerator" )
} ,
suppressEmptyGuestAcceleratorDiff ,
) ,
) ,
2014-08-25 18:48:20 +00:00
}
}
2017-08-22 19:49:43 +00:00
func getInstance ( config * Config , d * schema . ResourceData ) ( * computeBeta . Instance , error ) {
2016-04-10 16:59:57 +00:00
project , err := getProject ( d , config )
if err != nil {
return nil , err
}
2017-12-06 22:30:04 +00:00
zone , err := getZone ( d , config )
if err != nil {
return nil , err
}
2018-05-09 18:24:40 +00:00
instance , err := config . clientComputeBeta . Instances . Get ( project , zone , d . Id ( ) ) . Do ( )
if err != nil {
return nil , handleNotFoundError ( err , d , fmt . Sprintf ( "Instance %s" , d . Get ( "name" ) . ( string ) ) )
2015-08-31 21:33:02 +00:00
}
return instance , nil
}
2018-01-17 21:23:24 +00:00
func getDisk ( diskUri string , d * schema . ResourceData , config * Config ) ( * compute . Disk , error ) {
source , err := ParseDiskFieldValue ( diskUri , d , config )
if err != nil {
return nil , err
}
disk , err := config . clientCompute . Disks . Get ( source . Project , source . Zone , source . Name ) . Do ( )
if err != nil {
return nil , err
}
return disk , err
}
2018-06-28 23:09:23 +00:00
func expandComputeInstance ( project string , zone * compute . Zone , d * schema . ResourceData , config * Config ) ( * computeBeta . Instance , error ) {
2014-08-25 21:57:17 +00:00
// Get the machine type
2018-06-28 23:09:23 +00:00
var machineTypeUrl string
if mt , ok := d . GetOk ( "machine_type" ) ; ok {
log . Printf ( "[DEBUG] Loading machine type: %s" , mt . ( string ) )
machineType , err := config . clientCompute . MachineTypes . Get (
project , zone . Name , mt . ( string ) ) . Do ( )
if err != nil {
return nil , fmt . Errorf (
"Error loading machine type: %s" ,
err )
}
machineTypeUrl = machineType . SelfLink
2014-08-25 21:57:17 +00:00
}
// Build up the list of disks
2017-06-28 22:36:00 +00:00
2017-08-22 19:49:43 +00:00
disks := [ ] * computeBeta . AttachedDisk { }
2018-06-28 23:09:23 +00:00
if _ , hasBootDisk := d . GetOk ( "boot_disk" ) ; hasBootDisk {
bootDisk , err := expandBootDisk ( d , config , zone , project )
if err != nil {
return nil , err
}
disks = append ( disks , bootDisk )
2017-06-28 22:36:00 +00:00
}
2017-06-28 22:43:58 +00:00
if _ , hasScratchDisk := d . GetOk ( "scratch_disk" ) ; hasScratchDisk {
2017-09-27 00:01:52 +00:00
scratchDisks , err := expandScratchDisks ( d , config , zone , project )
2017-06-28 22:43:58 +00:00
if err != nil {
2018-06-28 23:09:23 +00:00
return nil , err
2017-06-28 22:43:58 +00:00
}
disks = append ( disks , scratchDisks ... )
}
2017-04-25 20:20:02 +00:00
attachedDisksCount := d . Get ( "attached_disk.#" ) . ( int )
2017-06-28 22:36:00 +00:00
2017-04-25 20:20:02 +00:00
for i := 0 ; i < attachedDisksCount ; i ++ {
2017-11-02 20:08:02 +00:00
diskConfig := d . Get ( fmt . Sprintf ( "attached_disk.%d" , i ) ) . ( map [ string ] interface { } )
disk , err := expandAttachedDisk ( diskConfig , d , config )
2017-10-23 20:26:59 +00:00
if err != nil {
2018-06-28 23:09:23 +00:00
return nil , err
2017-10-23 20:26:59 +00:00
}
2017-04-25 20:20:02 +00:00
2017-11-02 20:08:02 +00:00
disks = append ( disks , disk )
2017-04-25 20:20:02 +00:00
}
2015-10-26 20:16:06 +00:00
prefix := "scheduling.0"
2018-07-16 20:54:47 +00:00
scheduling := & computeBeta . Scheduling {
AutomaticRestart : googleapi . Bool ( d . Get ( prefix + ".automatic_restart" ) . ( bool ) ) ,
Preemptible : d . Get ( prefix + ".preemptible" ) . ( bool ) ,
OnHostMaintenance : d . Get ( prefix + ".on_host_maintenance" ) . ( string ) ,
ForceSendFields : [ ] string { "AutomaticRestart" , "Preemptible" } ,
2015-10-26 20:16:06 +00:00
}
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
metadata , err := resourceInstanceMetadata ( d )
2015-07-02 01:24:34 +00:00
if err != nil {
2018-06-28 23:09:23 +00:00
return nil , fmt . Errorf ( "Error creating metadata: %s" , err )
2015-07-02 01:24:34 +00:00
}
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
networkInterfaces , err := expandNetworkInterfaces ( d , config )
if err != nil {
2018-06-28 23:09:23 +00:00
return nil , fmt . Errorf ( "Error creating network interfaces: %s" , err )
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
}
accels , err := expandInstanceGuestAccelerators ( d , config )
if err != nil {
2018-06-28 23:09:23 +00:00
return nil , fmt . Errorf ( "Error creating guest accelerators: %s" , err )
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
}
2014-08-25 21:57:17 +00:00
// Create the instance information
2018-06-28 23:09:23 +00:00
return & computeBeta . Instance {
2018-03-16 18:57:42 +00:00
CanIpForward : d . Get ( "can_ip_forward" ) . ( bool ) ,
Description : d . Get ( "description" ) . ( string ) ,
Disks : disks ,
2018-06-28 23:09:23 +00:00
MachineType : machineTypeUrl ,
2018-03-16 18:57:42 +00:00
Metadata : metadata ,
Name : d . Get ( "name" ) . ( string ) ,
NetworkInterfaces : networkInterfaces ,
Tags : resourceInstanceTags ( d ) ,
Labels : expandLabels ( d ) ,
ServiceAccounts : expandServiceAccounts ( d . Get ( "service_account" ) . ( [ ] interface { } ) ) ,
GuestAccelerators : accels ,
MinCpuPlatform : d . Get ( "min_cpu_platform" ) . ( string ) ,
Scheduling : scheduling ,
DeletionProtection : d . Get ( "deletion_protection" ) . ( bool ) ,
2018-06-28 23:09:23 +00:00
ForceSendFields : [ ] string { "CanIpForward" , "DeletionProtection" } ,
} , nil
}
func resourceComputeInstanceCreate ( d * schema . ResourceData , meta interface { } ) error {
config := meta . ( * Config )
project , err := getProject ( d , config )
if err != nil {
return err
}
// Get the zone
z , err := getZone ( d , config )
if err != nil {
return err
}
log . Printf ( "[DEBUG] Loading zone: %s" , z )
zone , err := config . clientCompute . Zones . Get (
project , z ) . Do ( )
if err != nil {
return fmt . Errorf ( "Error loading zone '%s': %s" , z , err )
}
instance , err := expandComputeInstance ( project , zone , d , config )
if err != nil {
return err
}
// Read create timeout
// Until "create_timeout" is removed, use that timeout if set.
createTimeout := int ( d . Timeout ( schema . TimeoutCreate ) . Minutes ( ) )
if v , ok := d . GetOk ( "create_timeout" ) ; ok && v != 4 {
createTimeout = v . ( int )
2014-08-25 21:57:17 +00:00
}
log . Printf ( "[INFO] Requesting instance creation" )
2018-05-09 18:24:40 +00:00
op , err := config . clientComputeBeta . Instances . Insert ( project , zone . Name , instance ) . Do ( )
2014-08-25 21:57:17 +00:00
if err != nil {
return fmt . Errorf ( "Error creating instance: %s" , err )
}
// Store the ID now
d . SetId ( instance . Name )
// Wait for the operation to complete
2017-10-13 22:36:03 +00:00
waitErr := computeSharedOperationWaitTime ( config . clientCompute , op , project , createTimeout , "instance to create" )
2015-02-06 08:21:22 +00:00
if waitErr != nil {
2014-08-26 05:44:27 +00:00
// The resource didn't actually create
d . SetId ( "" )
2015-02-06 08:21:22 +00:00
return waitErr
2014-08-26 05:44:27 +00:00
}
2014-08-25 21:57:17 +00:00
return resourceComputeInstanceRead ( d , meta )
}
func resourceComputeInstanceRead ( d * schema . ResourceData , meta interface { } ) error {
config := meta . ( * Config )
2017-11-28 00:32:20 +00:00
project , err := getProject ( d , config )
if err != nil {
return err
}
2015-10-07 20:35:06 +00:00
instance , err := getInstance ( config , d )
2017-05-04 23:15:36 +00:00
if err != nil || instance == nil {
2015-08-31 21:33:02 +00:00
return err
}
2014-08-26 05:49:14 +00:00
2017-11-29 17:47:42 +00:00
md := flattenMetadataBeta ( instance . Metadata )
2017-08-01 17:47:58 +00:00
existingMetadata := d . Get ( "metadata" ) . ( map [ string ] interface { } )
2015-10-14 18:17:44 +00:00
2018-02-14 07:55:37 +00:00
// If the existing config specifies "metadata.startup-script" instead of "metadata_startup_script",
// we shouldn't move the remote metadata.startup-script to metadata_startup_script. Otherwise,
// we should.
if ss , ok := existingMetadata [ "startup-script" ] ; ! ok || ss == "" {
d . Set ( "metadata_startup_script" , md [ "startup-script" ] )
// Note that here we delete startup-script from our metadata list. This is to prevent storing the startup-script
// as a value in the metadata since the config specifically tracks it under 'metadata_startup_script'
delete ( md , "startup-script" )
} else if _ , ok := d . GetOk ( "metadata_startup_script" ) ; ok {
delete ( md , "startup-script" )
}
2017-08-01 17:47:58 +00:00
// Delete any keys not explicitly set in our config file
for k := range md {
if _ , ok := existingMetadata [ k ] ; ! ok {
delete ( md , k )
}
2015-10-14 17:17:08 +00:00
}
2017-08-01 17:47:58 +00:00
if err = d . Set ( "metadata" , md ) ; err != nil {
2015-08-31 21:33:02 +00:00
return fmt . Errorf ( "Error setting metadata: %s" , err )
2014-08-25 21:57:17 +00:00
}
2014-10-07 16:24:13 +00:00
d . Set ( "can_ip_forward" , instance . CanIpForward )
2018-01-17 18:45:28 +00:00
d . Set ( "machine_type" , GetResourceNameFromSelfLink ( instance . MachineType ) )
2017-02-03 11:50:57 +00:00
2014-08-25 23:23:28 +00:00
// Set the networks
2015-02-06 08:21:22 +00:00
// Use the first external IP found for the default connection info.
2017-11-29 17:47:42 +00:00
networkInterfaces , _ , internalIP , externalIP , err := flattenNetworkInterfaces ( d , config , instance . NetworkInterfaces )
if err != nil {
return err
}
2018-06-28 23:09:23 +00:00
if err := d . Set ( "network_interface" , networkInterfaces ) ; err != nil {
return err
}
2014-10-19 07:04:17 +00:00
2015-02-06 08:21:22 +00:00
// Fall back on internal ip if there is no external ip. This makes sense in the situation where
// terraform is being used on a cloud instance and can therefore access the instances it creates
// via their internal ips.
sshIP := externalIP
if sshIP == "" {
sshIP = internalIP
2014-08-25 23:23:28 +00:00
}
2014-10-19 07:04:17 +00:00
// Initialize the connection info
d . SetConnInfo ( map [ string ] string {
"type" : "ssh" ,
2015-02-06 08:21:22 +00:00
"host" : sshIP ,
2014-10-19 07:04:17 +00:00
} )
2014-08-26 20:48:49 +00:00
// Set the metadata fingerprint if there is one.
if instance . Metadata != nil {
d . Set ( "metadata_fingerprint" , instance . Metadata . Fingerprint )
}
2014-08-26 20:52:18 +00:00
// Set the tags fingerprint if there is one.
if instance . Tags != nil {
d . Set ( "tags_fingerprint" , instance . Tags . Fingerprint )
2017-12-19 22:33:30 +00:00
d . Set ( "tags" , convertStringArrToInterface ( instance . Tags . Items ) )
2014-08-26 20:52:18 +00:00
}
2018-06-28 23:09:23 +00:00
if err := d . Set ( "labels" , instance . Labels ) ; err != nil {
return err
2017-06-19 22:00:34 +00:00
}
if instance . LabelFingerprint != "" {
d . Set ( "label_fingerprint" , instance . LabelFingerprint )
}
2018-04-07 00:40:49 +00:00
attachedDiskSources := make ( map [ string ] int )
for i , v := range d . Get ( "attached_disk" ) . ( [ ] interface { } ) {
if v == nil {
// There was previously a bug in this code that, when triggered,
// would cause some nil values to end up in the list of attached disks.
// Check for this case to make sure we don't try to parse the nil disk.
continue
}
disk := v . ( map [ string ] interface { } )
2018-07-11 00:10:05 +00:00
s := disk [ "source" ] . ( string )
var sourceLink string
if strings . Contains ( s , "regions/" ) {
source , err := ParseRegionDiskFieldValue ( disk [ "source" ] . ( string ) , d , config )
if err != nil {
return err
}
sourceLink = source . RelativeLink ( )
} else {
source , err := ParseDiskFieldValue ( disk [ "source" ] . ( string ) , d , config )
if err != nil {
return err
}
sourceLink = source . RelativeLink ( )
2017-10-23 20:26:59 +00:00
}
2018-07-11 00:10:05 +00:00
attachedDiskSources [ sourceLink ] = i
2017-04-25 20:20:02 +00:00
}
2018-04-07 00:40:49 +00:00
attachedDisks := make ( [ ] map [ string ] interface { } , d . Get ( "attached_disk.#" ) . ( int ) )
2017-10-23 19:53:41 +00:00
scratchDisks := [ ] map [ string ] interface { } { }
2017-04-25 20:20:02 +00:00
for _ , disk := range instance . Disks {
2017-10-23 19:53:41 +00:00
if disk . Boot {
2018-01-17 21:23:24 +00:00
d . Set ( "boot_disk" , flattenBootDisk ( d , disk , config ) )
2017-10-23 19:53:41 +00:00
} else if disk . Type == "SCRATCH" {
2017-06-28 22:43:58 +00:00
scratchDisks = append ( scratchDisks , flattenScratchDisk ( disk ) )
2017-04-25 20:20:02 +00:00
} else {
2018-07-11 00:10:05 +00:00
var sourceLink string
if strings . Contains ( disk . Source , "regions/" ) {
source , err := ParseRegionDiskFieldValue ( disk . Source , d , config )
if err != nil {
return err
}
sourceLink = source . RelativeLink ( )
} else {
source , err := ParseDiskFieldValue ( disk . Source , d , config )
if err != nil {
return err
}
sourceLink = source . RelativeLink ( )
2017-10-23 20:26:59 +00:00
}
2018-07-11 00:10:05 +00:00
adIndex , inConfig := attachedDiskSources [ sourceLink ]
2017-04-25 20:20:02 +00:00
di := map [ string ] interface { } {
2018-05-09 18:24:40 +00:00
"source" : ConvertSelfLinkToV1 ( disk . Source ) ,
2017-09-07 14:04:26 +00:00
"device_name" : disk . DeviceName ,
2018-02-12 18:56:06 +00:00
"mode" : disk . Mode ,
2017-04-25 20:20:02 +00:00
}
2017-09-07 14:04:26 +00:00
if key := disk . DiskEncryptionKey ; key != nil {
2017-10-23 19:53:41 +00:00
if inConfig {
di [ "disk_encryption_key_raw" ] = d . Get ( fmt . Sprintf ( "attached_disk.%d.disk_encryption_key_raw" , adIndex ) )
}
2017-09-07 14:04:26 +00:00
di [ "disk_encryption_key_sha256" ] = key . Sha256
2017-04-25 20:20:02 +00:00
}
2018-04-07 00:40:49 +00:00
// We want the disks to remain in the order we set in the config, so if a disk
// is present in the config, make sure it's at the correct index. Otherwise, append it.
2017-10-23 19:53:41 +00:00
if inConfig {
attachedDisks [ adIndex ] = di
} else {
2018-04-07 00:40:49 +00:00
attachedDisks = append ( attachedDisks , di )
2017-10-23 19:53:41 +00:00
}
2017-01-18 13:49:48 +00:00
}
}
2018-04-07 00:40:49 +00:00
// Remove nils from map in case there were disks in the config that were not present on read;
// i.e. a disk was detached out of band
ads := [ ] map [ string ] interface { } { }
for _ , d := range attachedDisks {
if d != nil {
ads = append ( ads , d )
}
}
2017-09-07 14:04:26 +00:00
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
d . Set ( "service_account" , flattenServiceAccounts ( instance . ServiceAccounts ) )
2018-04-07 00:40:49 +00:00
d . Set ( "attached_disk" , ads )
2017-06-28 22:43:58 +00:00
d . Set ( "scratch_disk" , scratchDisks )
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
d . Set ( "scheduling" , flattenScheduling ( instance . Scheduling ) )
d . Set ( "guest_accelerator" , flattenGuestAccelerators ( instance . GuestAccelerators ) )
2017-08-30 21:25:31 +00:00
d . Set ( "cpu_platform" , instance . CpuPlatform )
d . Set ( "min_cpu_platform" , instance . MinCpuPlatform )
2018-03-16 18:57:42 +00:00
d . Set ( "deletion_protection" , instance . DeletionProtection )
2017-08-22 19:49:43 +00:00
d . Set ( "self_link" , ConvertSelfLinkToV1 ( instance . SelfLink ) )
2017-09-13 23:18:08 +00:00
d . Set ( "instance_id" , fmt . Sprintf ( "%d" , instance . Id ) )
2017-11-28 00:32:20 +00:00
d . Set ( "project" , project )
2018-01-03 21:18:40 +00:00
d . Set ( "zone" , GetResourceNameFromSelfLink ( instance . Zone ) )
2017-12-19 22:33:30 +00:00
d . Set ( "name" , instance . Name )
2015-10-14 17:17:08 +00:00
d . SetId ( instance . Name )
2015-02-02 09:46:35 +00:00
2014-08-25 21:57:17 +00:00
return nil
}
2014-08-26 20:48:49 +00:00
func resourceComputeInstanceUpdate ( d * schema . ResourceData , meta interface { } ) error {
config := meta . ( * Config )
2016-04-10 16:59:57 +00:00
project , err := getProject ( d , config )
if err != nil {
return err
}
2017-12-06 22:30:04 +00:00
zone , err := getZone ( d , config )
if err != nil {
return err
}
2015-02-06 08:21:22 +00:00
2018-02-14 20:48:47 +00:00
// Use beta api directly in order to read network_interface.fingerprint without having to put it in the schema.
// Change back to getInstance(config, d) once updating alias ips is GA.
instance , err := config . clientComputeBeta . Instances . Get ( project , zone , d . Id ( ) ) . Do ( )
2015-02-06 08:21:22 +00:00
if err != nil {
2018-02-14 20:48:47 +00:00
return handleNotFoundError ( err , d , fmt . Sprintf ( "Instance %s" , d . Get ( "name" ) . ( string ) ) )
2015-02-06 08:21:22 +00:00
}
2014-08-27 03:31:35 +00:00
// Enable partial mode for the resource since it is possible
d . Partial ( true )
2014-08-26 20:48:49 +00:00
// If the Metadata has changed, then update that.
if d . HasChange ( "metadata" ) {
2015-08-31 21:33:02 +00:00
o , n := d . GetChange ( "metadata" )
2018-02-14 07:55:37 +00:00
if script , scriptExists := d . GetOk ( "metadata_startup_script" ) ; scriptExists && script != "" {
2015-10-14 17:17:08 +00:00
if _ , ok := n . ( map [ string ] interface { } ) [ "startup-script" ] ; ok {
return fmt . Errorf ( "Only one of metadata.startup-script and metadata_startup_script may be defined" )
}
2018-02-14 07:55:37 +00:00
if err = d . Set ( "metadata" , n ) ; err != nil {
return err
}
2015-10-14 17:17:08 +00:00
n . ( map [ string ] interface { } ) [ "startup-script" ] = script
}
2015-08-31 21:33:02 +00:00
updateMD := func ( ) error {
// Reload the instance in the case of a fingerprint mismatch
2015-10-07 20:35:06 +00:00
instance , err = getInstance ( config , d )
2015-08-31 21:33:02 +00:00
if err != nil {
return err
}
md := instance . Metadata
2017-08-22 19:49:43 +00:00
BetaMetadataUpdate ( o . ( map [ string ] interface { } ) , n . ( map [ string ] interface { } ) , md )
2015-08-31 21:33:02 +00:00
if err != nil {
return fmt . Errorf ( "Error updating metadata: %s" , err )
}
2017-08-22 19:49:43 +00:00
mdV1 := & compute . Metadata { }
err = Convert ( md , mdV1 )
if err != nil {
return err
}
2015-08-31 21:33:02 +00:00
op , err := config . clientCompute . Instances . SetMetadata (
2017-08-22 19:49:43 +00:00
project , zone , d . Id ( ) , mdV1 ) . Do ( )
2015-08-31 21:33:02 +00:00
if err != nil {
return fmt . Errorf ( "Error updating metadata: %s" , err )
}
2017-12-14 01:03:15 +00:00
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "metadata to update" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
2015-08-31 21:33:02 +00:00
if opErr != nil {
return opErr
}
d . SetPartial ( "metadata" )
2018-02-14 07:55:37 +00:00
2015-08-31 21:33:02 +00:00
return nil
2014-08-26 20:48:49 +00:00
}
2014-08-27 03:31:35 +00:00
2015-08-31 21:33:02 +00:00
MetadataRetryWrapper ( updateMD )
2018-02-14 07:55:37 +00:00
2014-08-26 20:52:18 +00:00
}
if d . HasChange ( "tags" ) {
tags := resourceInstanceTags ( d )
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
tagsV1 := & compute . Tags { }
if err := Convert ( tags , tagsV1 ) ; err != nil {
return err
}
2014-08-26 20:52:18 +00:00
op , err := config . clientCompute . Instances . SetTags (
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
project , zone , d . Id ( ) , tagsV1 ) . Do ( )
2014-08-26 20:52:18 +00:00
if err != nil {
return fmt . Errorf ( "Error updating tags: %s" , err )
}
2014-08-26 20:48:49 +00:00
2017-12-14 01:03:15 +00:00
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "tags to update" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
2015-02-06 08:21:22 +00:00
if opErr != nil {
return opErr
2014-08-26 20:52:18 +00:00
}
2014-08-27 03:31:35 +00:00
d . SetPartial ( "tags" )
2014-08-26 20:48:49 +00:00
}
2017-06-19 22:00:34 +00:00
if d . HasChange ( "labels" ) {
2017-08-18 20:34:11 +00:00
labels := expandLabels ( d )
2017-06-19 22:00:34 +00:00
labelFingerprint := d . Get ( "label_fingerprint" ) . ( string )
req := compute . InstancesSetLabelsRequest { Labels : labels , LabelFingerprint : labelFingerprint }
op , err := config . clientCompute . Instances . SetLabels ( project , zone , d . Id ( ) , & req ) . Do ( )
if err != nil {
return fmt . Errorf ( "Error updating labels: %s" , err )
}
2017-12-14 01:03:15 +00:00
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "labels to update" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
2017-06-19 22:00:34 +00:00
if opErr != nil {
return opErr
}
d . SetPartial ( "labels" )
}
2015-10-26 20:16:06 +00:00
if d . HasChange ( "scheduling" ) {
prefix := "scheduling.0"
2018-07-16 20:54:47 +00:00
scheduling := & compute . Scheduling {
AutomaticRestart : googleapi . Bool ( d . Get ( prefix + ".automatic_restart" ) . ( bool ) ) ,
Preemptible : d . Get ( prefix + ".preemptible" ) . ( bool ) ,
OnHostMaintenance : d . Get ( prefix + ".on_host_maintenance" ) . ( string ) ,
ForceSendFields : [ ] string { "AutomaticRestart" , "Preemptible" } ,
2015-10-26 20:16:06 +00:00
}
2016-04-10 16:59:57 +00:00
op , err := config . clientCompute . Instances . SetScheduling ( project ,
2015-10-26 20:16:06 +00:00
zone , d . Id ( ) , scheduling ) . Do ( )
if err != nil {
return fmt . Errorf ( "Error updating scheduling policy: %s" , err )
}
2017-12-14 01:03:15 +00:00
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "scheduling policy update" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
2015-10-26 20:16:06 +00:00
if opErr != nil {
return opErr
}
2015-10-29 22:10:44 +00:00
d . SetPartial ( "scheduling" )
2015-10-26 20:16:06 +00:00
}
2015-02-06 08:21:22 +00:00
networkInterfacesCount := d . Get ( "network_interface.#" ) . ( int )
2017-09-28 21:38:38 +00:00
// Sanity check
if networkInterfacesCount != len ( instance . NetworkInterfaces ) {
return fmt . Errorf ( "Instance had unexpected number of network interfaces: %d" , len ( instance . NetworkInterfaces ) )
}
for i := 0 ; i < networkInterfacesCount ; i ++ {
prefix := fmt . Sprintf ( "network_interface.%d" , i )
instNetworkInterface := instance . NetworkInterfaces [ i ]
networkName := d . Get ( prefix + ".name" ) . ( string )
// TODO: This sanity check is broken by #929, disabled for now (by forcing the equality)
networkName = instNetworkInterface . Name
2015-02-06 08:21:22 +00:00
// Sanity check
2017-09-28 21:38:38 +00:00
if networkName != instNetworkInterface . Name {
return fmt . Errorf ( "Instance networkInterface had unexpected name: %s" , instNetworkInterface . Name )
2015-02-06 08:21:22 +00:00
}
2017-09-28 21:38:38 +00:00
if d . HasChange ( prefix + ".access_config" ) {
// TODO: This code deletes then recreates accessConfigs. This is bad because it may
// leave the machine inaccessible from either ip if the creation part fails (network
// timeout etc). However right now there is a GCE limit of 1 accessConfig so it is
// the only way to do it. In future this should be revised to only change what is
// necessary, and also add before removing.
// Delete any accessConfig that currently exists in instNetworkInterface
for _ , ac := range instNetworkInterface . AccessConfigs {
op , err := config . clientCompute . Instances . DeleteAccessConfig (
project , zone , d . Id ( ) , ac . Name , networkName ) . Do ( )
if err != nil {
return fmt . Errorf ( "Error deleting old access_config: %s" , err )
}
2017-12-14 01:03:15 +00:00
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "old access_config to delete" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
2017-09-28 21:38:38 +00:00
if opErr != nil {
return opErr
2015-02-06 08:21:22 +00:00
}
2017-09-28 21:38:38 +00:00
}
2015-02-06 08:21:22 +00:00
2017-09-28 21:38:38 +00:00
// Create new ones
accessConfigsCount := d . Get ( prefix + ".access_config.#" ) . ( int )
for j := 0 ; j < accessConfigsCount ; j ++ {
acPrefix := fmt . Sprintf ( "%s.access_config.%d" , prefix , j )
2018-06-05 19:35:44 +00:00
ac := & computeBeta . AccessConfig {
Type : "ONE_TO_ONE_NAT" ,
NatIP : d . Get ( acPrefix + ".nat_ip" ) . ( string ) ,
NetworkTier : d . Get ( acPrefix + ".network_tier" ) . ( string ) ,
2017-09-28 21:38:38 +00:00
}
2018-04-25 20:26:24 +00:00
if ptr , ok := d . GetOk ( acPrefix + ".public_ptr_domain_name" ) ; ok && ptr != "" {
2018-04-20 18:14:38 +00:00
ac . SetPublicPtr = true
ac . PublicPtrDomainName = ptr . ( string )
}
2018-06-05 19:35:44 +00:00
op , err := config . clientComputeBeta . Instances . AddAccessConfig (
2017-09-28 21:38:38 +00:00
project , zone , d . Id ( ) , networkName , ac ) . Do ( )
if err != nil {
return fmt . Errorf ( "Error adding new access_config: %s" , err )
}
2018-06-05 19:35:44 +00:00
opErr := computeSharedOperationWaitTime ( config . clientCompute , op , project , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) , "new access_config to add" )
2017-09-28 21:38:38 +00:00
if opErr != nil {
return opErr
2015-02-06 08:21:22 +00:00
}
}
}
2018-02-14 20:48:47 +00:00
if d . HasChange ( prefix + ".alias_ip_range" ) {
rereadFingerprint := false
// Alias IP ranges cannot be updated; they must be removed and then added.
if len ( instNetworkInterface . AliasIpRanges ) > 0 {
ni := & computeBeta . NetworkInterface {
Fingerprint : instNetworkInterface . Fingerprint ,
ForceSendFields : [ ] string { "AliasIpRanges" } ,
}
op , err := config . clientComputeBeta . Instances . UpdateNetworkInterface ( project , zone , d . Id ( ) , networkName , ni ) . Do ( )
if err != nil {
return errwrap . Wrapf ( "Error removing alias_ip_range: {{err}}" , err )
}
opErr := computeSharedOperationWaitTime ( config . clientCompute , op , project , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) , "updaing alias ip ranges" )
if opErr != nil {
return opErr
}
rereadFingerprint = true
}
ranges := d . Get ( prefix + ".alias_ip_range" ) . ( [ ] interface { } )
if len ( ranges ) > 0 {
if rereadFingerprint {
instance , err = config . clientComputeBeta . Instances . Get ( project , zone , d . Id ( ) ) . Do ( )
if err != nil {
return err
}
instNetworkInterface = instance . NetworkInterfaces [ i ]
}
ni := & computeBeta . NetworkInterface {
AliasIpRanges : expandAliasIpRanges ( ranges ) ,
Fingerprint : instNetworkInterface . Fingerprint ,
}
op , err := config . clientComputeBeta . Instances . UpdateNetworkInterface ( project , zone , d . Id ( ) , networkName , ni ) . Do ( )
if err != nil {
return errwrap . Wrapf ( "Error adding alias_ip_range: {{err}}" , err )
}
opErr := computeSharedOperationWaitTime ( config . clientCompute , op , project , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) , "updaing alias ip ranges" )
if opErr != nil {
return opErr
}
}
}
2017-11-02 20:08:02 +00:00
d . SetPartial ( "network_interface" )
}
if d . HasChange ( "attached_disk" ) {
o , n := d . GetChange ( "attached_disk" )
// Keep track of disks currently in the instance. Because the google_compute_disk resource
// can detach disks, it's possible that there are fewer disks currently attached than there
// were at the time we ran terraform plan.
currDisks := map [ string ] struct { } { }
for _ , disk := range instance . Disks {
if ! disk . Boot && disk . Type != "SCRATCH" {
currDisks [ disk . DeviceName ] = struct { } { }
}
}
// Keep track of disks currently in state.
// Since changing any field within the disk needs to detach+reattach it,
// keep track of the hash of the full disk.
oDisks := map [ uint64 ] string { }
for _ , disk := range o . ( [ ] interface { } ) {
diskConfig := disk . ( map [ string ] interface { } )
computeDisk , err := expandAttachedDisk ( diskConfig , d , config )
if err != nil {
return err
}
hash , err := hashstructure . Hash ( * computeDisk , nil )
if err != nil {
return err
}
if _ , ok := currDisks [ computeDisk . DeviceName ] ; ok {
oDisks [ hash ] = computeDisk . DeviceName
}
}
// Keep track of new config's disks.
// Since changing any field within the disk needs to detach+reattach it,
// keep track of the hash of the full disk.
// If a disk with a certain hash is only in the new config, it should be attached.
nDisks := map [ uint64 ] struct { } { }
var attach [ ] * compute . AttachedDisk
for _ , disk := range n . ( [ ] interface { } ) {
diskConfig := disk . ( map [ string ] interface { } )
computeDisk , err := expandAttachedDisk ( diskConfig , d , config )
if err != nil {
return err
}
hash , err := hashstructure . Hash ( * computeDisk , nil )
if err != nil {
return err
}
nDisks [ hash ] = struct { } { }
if _ , ok := oDisks [ hash ] ; ! ok {
computeDiskV1 := & compute . AttachedDisk { }
err = Convert ( computeDisk , computeDiskV1 )
if err != nil {
return err
}
attach = append ( attach , computeDiskV1 )
}
}
// If a source is only in the old config, it should be detached.
// Detach the old disks.
for hash , deviceName := range oDisks {
if _ , ok := nDisks [ hash ] ; ! ok {
op , err := config . clientCompute . Instances . DetachDisk ( project , zone , instance . Name , deviceName ) . Do ( )
if err != nil {
return errwrap . Wrapf ( "Error detaching disk: %s" , err )
}
2017-12-14 01:03:15 +00:00
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "detaching disk" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
2017-11-02 20:08:02 +00:00
if opErr != nil {
return opErr
}
log . Printf ( "[DEBUG] Successfully detached disk %s" , deviceName )
}
}
// Attach the new disks
for _ , disk := range attach {
op , err := config . clientCompute . Instances . AttachDisk ( project , zone , instance . Name , disk ) . Do ( )
if err != nil {
return errwrap . Wrapf ( "Error attaching disk : {{err}}" , err )
}
2017-12-14 01:03:15 +00:00
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "attaching disk" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
2017-11-02 20:08:02 +00:00
if opErr != nil {
return opErr
}
log . Printf ( "[DEBUG] Successfully attached disk %s" , disk . Source )
}
d . SetPartial ( "attached_disk" )
2015-02-06 08:21:22 +00:00
}
2018-02-27 22:29:00 +00:00
// d.HasChange("service_account") is oversensitive: see https://github.com/hashicorp/terraform/issues/17411
// Until that's fixed, manually check whether there is a change.
o , n := d . GetChange ( "service_account" )
oList := o . ( [ ] interface { } )
nList := n . ( [ ] interface { } )
scopesChange := false
if len ( oList ) != len ( nList ) {
scopesChange = true
} else if len ( oList ) == 1 {
// service_account has MaxItems: 1
// scopes is a required field and so will always be set
oScopes := oList [ 0 ] . ( map [ string ] interface { } ) [ "scopes" ] . ( * schema . Set )
nScopes := nList [ 0 ] . ( map [ string ] interface { } ) [ "scopes" ] . ( * schema . Set )
scopesChange = ! oScopes . Equal ( nScopes )
}
2018-03-16 18:57:42 +00:00
if d . HasChange ( "deletion_protection" ) {
nDeletionProtection := d . Get ( "deletion_protection" ) . ( bool )
op , err := config . clientCompute . Instances . SetDeletionProtection ( project , zone , d . Id ( ) ) . DeletionProtection ( nDeletionProtection ) . Do ( )
if err != nil {
return fmt . Errorf ( "Error updating deletion protection flag: %s" , err )
}
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "deletion protection to update" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
if opErr != nil {
return opErr
}
d . SetPartial ( "deletion_protection" )
}
2018-01-24 20:50:39 +00:00
// Attributes which can only be changed if the instance is stopped
2018-02-27 22:29:00 +00:00
if scopesChange || d . HasChange ( "service_account.0.email" ) || d . HasChange ( "machine_type" ) || d . HasChange ( "min_cpu_platform" ) {
2018-01-24 20:50:39 +00:00
if ! d . Get ( "allow_stopping_for_update" ) . ( bool ) {
return fmt . Errorf ( "Changing the machine_type, min_cpu_platform, or service_account on an instance requires stopping it. " +
"To acknowledge this, please set allow_stopping_for_update = true in your config." )
}
op , err := config . clientCompute . Instances . Stop ( project , zone , instance . Name ) . Do ( )
if err != nil {
return errwrap . Wrapf ( "Error stopping instance: {{err}}" , err )
}
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "stopping instance" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
if opErr != nil {
return opErr
}
if d . HasChange ( "machine_type" ) {
mt , err := ParseMachineTypesFieldValue ( d . Get ( "machine_type" ) . ( string ) , d , config )
if err != nil {
return err
}
req := & compute . InstancesSetMachineTypeRequest {
MachineType : mt . RelativeLink ( ) ,
}
op , err = config . clientCompute . Instances . SetMachineType ( project , zone , instance . Name , req ) . Do ( )
if err != nil {
return err
}
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "updating machinetype" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
if opErr != nil {
return opErr
}
d . SetPartial ( "machine_type" )
}
if d . HasChange ( "min_cpu_platform" ) {
minCpuPlatform , ok := d . GetOk ( "min_cpu_platform" )
// Even though you don't have to set minCpuPlatform on create, you do have to set it to an
// actual value on update. "Automatic" is the default. This will be read back from the API as empty,
// so we don't need to worry about diffs.
if ! ok {
minCpuPlatform = "Automatic"
}
req := & compute . InstancesSetMinCpuPlatformRequest {
MinCpuPlatform : minCpuPlatform . ( string ) ,
}
op , err = config . clientCompute . Instances . SetMinCpuPlatform ( project , zone , instance . Name , req ) . Do ( )
if err != nil {
return err
}
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "updating min cpu platform" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
if opErr != nil {
return opErr
}
d . SetPartial ( "min_cpu_platform" )
}
2018-02-27 22:29:00 +00:00
if d . HasChange ( "service_account.0.email" ) || scopesChange {
2018-01-24 20:50:39 +00:00
sa := d . Get ( "service_account" ) . ( [ ] interface { } )
req := & compute . InstancesSetServiceAccountRequest { ForceSendFields : [ ] string { "email" } }
if len ( sa ) > 0 {
saMap := sa [ 0 ] . ( map [ string ] interface { } )
req . Email = saMap [ "email" ] . ( string )
req . Scopes = canonicalizeServiceScopes ( convertStringSet ( saMap [ "scopes" ] . ( * schema . Set ) ) )
}
op , err = config . clientCompute . Instances . SetServiceAccount ( project , zone , instance . Name , req ) . Do ( )
if err != nil {
return err
}
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "updating service account" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
if opErr != nil {
return opErr
}
d . SetPartial ( "service_account" )
}
op , err = config . clientCompute . Instances . Start ( project , zone , instance . Name ) . Do ( )
if err != nil {
return errwrap . Wrapf ( "Error starting instance: {{err}}" , err )
}
opErr = computeOperationWaitTime ( config . clientCompute , op , project , "starting instance" , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) )
if opErr != nil {
return opErr
}
}
2014-08-27 03:31:35 +00:00
// We made it, disable partial mode
d . Partial ( false )
2014-08-26 20:48:49 +00:00
return resourceComputeInstanceRead ( d , meta )
}
2017-11-02 20:08:02 +00:00
func expandAttachedDisk ( diskConfig map [ string ] interface { } , d * schema . ResourceData , meta interface { } ) ( * computeBeta . AttachedDisk , error ) {
config := meta . ( * Config )
2018-07-11 00:10:05 +00:00
s := diskConfig [ "source" ] . ( string )
var sourceLink string
if strings . Contains ( s , "regions/" ) {
source , err := ParseRegionDiskFieldValue ( s , d , config )
if err != nil {
return nil , err
}
sourceLink = source . RelativeLink ( )
} else {
source , err := ParseDiskFieldValue ( s , d , config )
if err != nil {
return nil , err
}
sourceLink = source . RelativeLink ( )
2017-11-02 20:08:02 +00:00
}
disk := & computeBeta . AttachedDisk {
2018-07-11 00:10:05 +00:00
Source : sourceLink ,
2017-11-02 20:08:02 +00:00
}
2018-02-12 18:56:06 +00:00
if v , ok := diskConfig [ "mode" ] ; ok {
disk . Mode = v . ( string )
}
2017-11-02 20:08:02 +00:00
if v , ok := diskConfig [ "device_name" ] ; ok {
disk . DeviceName = v . ( string )
}
if v , ok := diskConfig [ "disk_encryption_key_raw" ] ; ok {
disk . DiskEncryptionKey = & computeBeta . CustomerEncryptionKey {
RawKey : v . ( string ) ,
}
}
return disk , nil
}
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
// See comment on expandInstanceTemplateGuestAccelerators regarding why this
// code is duplicated.
func expandInstanceGuestAccelerators ( d TerraformResourceData , config * Config ) ( [ ] * computeBeta . AcceleratorConfig , error ) {
configs , ok := d . GetOk ( "guest_accelerator" )
if ! ok {
return nil , nil
}
accels := configs . ( [ ] interface { } )
2018-01-23 19:51:36 +00:00
guestAccelerators := make ( [ ] * computeBeta . AcceleratorConfig , 0 , len ( accels ) )
for _ , raw := range accels {
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
data := raw . ( map [ string ] interface { } )
2018-01-23 19:51:36 +00:00
if data [ "count" ] . ( int ) == 0 {
continue
}
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
at , err := ParseAcceleratorFieldValue ( data [ "type" ] . ( string ) , d , config )
if err != nil {
return nil , fmt . Errorf ( "cannot parse accelerator type: %v" , err )
}
2018-01-23 19:51:36 +00:00
guestAccelerators = append ( guestAccelerators , & computeBeta . AcceleratorConfig {
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
AcceleratorCount : int64 ( data [ "count" ] . ( int ) ) ,
AcceleratorType : at . RelativeLink ( ) ,
2018-01-23 19:51:36 +00:00
} )
Add Alias IP and Guest Accelerator support to Instance Templates (#639)
* Move AliasIpRange helpers into utils
To reflect the fact they'll be used by multiple resources.
* Pass Config to build helpers, not meta
It's the only thing meta is used for.
* Refactor getNetwork util methods to return early for the happy path.
* Update compute APIs
compute.Instance.MinCpuPlatform is now GA.
* Fix panic in TestComputeInstanceMigrateState
This seemed to be a pre-existing issue, i.e. I could repro it in master.
--- FAIL: TestComputeInstanceMigrateState (0.00s)
panic: interface conversion: interface {} is nil, not *google.Config [recovered]
panic: interface conversion: interface {} is nil, not *google.Config
goroutine 85 [running]:
testing.tRunner.func1(0xc4205d60f0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:711 +0x2d2
panic(0x203acc0, 0xc4205d2080)
/usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:491 +0x283
github.com/terraform-providers/terraform-provider-google/google.migrateStateV3toV4(0xc4205f2000, 0x0, 0x0, 0x0, 0x48, 0xc4205f2000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:182 +0x2405
github.com/terraform-providers/terraform-provider-google/google.resourceComputeInstanceMigrateState(0x2, 0xc4205f2000, 0x0, 0x0, 0x0, 0x0, 0xe0000000000)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate.go:48 +0x21a
github.com/terraform-providers/terraform-provider-google/google.runInstanceMigrateTest(0xc4205d60f0, 0x2260816, 0x8, 0x227d23a, 0x20, 0x2, 0xc4205ec0f0, 0xc4205ec120, 0x0,
0x0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:803 +0xc1
github.com/terraform-providers/terraform-provider-google/google.TestComputeInstanceMigrateState(0xc4205d60f0)
/Users/negz/control/go/src/github.com/terraform-providers/terraform-provider-google/google/resource_compute_instance_migrate_test.go:71 +0xc84
testing.tRunner(0xc4205d60f0, 0x22d81c0)
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de
FAIL github.com/terraform-providers/terraform-provider-google/google 0.035s
* Use only the v1 API for resource_compute_instance
Alias IP ranges, Accelerators, and min CPU platform are now GA.
* Move common instance code into utils.go
Methods used by both resource_compute_instance and
resource_compute_instance_template are currently spread between their respective
files, and utils.go.
This commit moves them all into utils.go for the sake of consistency. It may be
worth considering an instance_common.go file or similar.
* Unify compute_instance and compute_instance_template network_interface and service_account code
This has the side effect of enabling Alias IP range support for
compute_instance_templates.
* Add tests for compute instance template Alias IP ranges
* Mark instance template region as computed
We compute it from the subnet its network interfaces are in. Note this
is not new behaviour - I believe it was erroneously missing the computed
flag.
* Support guest accelerators for instance templates
Since most of the code is already there.
* Add a test for using 'address' rather than 'network_ip' for instance templates
* Don't mark assigned_nat_ip as deprecated
* Remove network_interface schema fields that don't make sense for a compute instance template
* Add newline after count in instance template docs
* Don't try to dedupe guest accelerator expansion code
The API calls to Google to create guest accelerators take different values
for instances and instance templates. Instance templates don't have a zone
and can thus *only* be passed a guest accelerator name.
* Use ParseNetworkFieldValue instead of getNetworkLink
* Add support for parsing regional fields, and subnetworks specifically
Currently unused because subnetworks may have a separate project from that
of the instance using them, which complicates looking up the project field.
* Fall back to provider region when parsing regional field values
Also slightly refactors getXFromSchema field helper functions for readability.
* Revert to assigned_nat_ip in compute instance docs
* Add beta scaffolding to compute instance and compute instance template
Note these resources don't currently use beta features - this is futureproofing.
* Fix indentation in comment about instance template alias IP ranges
* Consolidate metadata helper functions in metadata.go
* Move compute instance (and template) related helpers into their own file
2017-11-28 18:01:27 +00:00
}
return guestAccelerators , nil
}
2018-01-23 19:51:36 +00:00
// suppressEmptyGuestAcceleratorDiff is used to work around perpetual diff
// issues when a count of `0` guest accelerators is desired. This may occur when
// guest_accelerator support is controlled via a module variable. E.g.:
//
// guest_accelerators {
// count = "${var.enable_gpu ? var.gpu_count : 0}"
// ...
// }
// After reconciling the desired and actual state, we would otherwise see a
// perpetual resembling:
// [] != [{"count":0, "type": "nvidia-tesla-k80"}]
func suppressEmptyGuestAcceleratorDiff ( d * schema . ResourceDiff , meta interface { } ) error {
oldi , newi := d . GetChange ( "guest_accelerator" )
old , ok := oldi . ( [ ] interface { } )
if ! ok {
return fmt . Errorf ( "Expected old guest accelerator diff to be a slice" )
}
new , ok := newi . ( [ ] interface { } )
if ! ok {
return fmt . Errorf ( "Expected new guest accelerator diff to be a slice" )
}
if len ( old ) != 0 && len ( new ) != 1 {
return nil
}
firstAccel , ok := new [ 0 ] . ( map [ string ] interface { } )
if ! ok {
return fmt . Errorf ( "Unable to type assert guest accelerator" )
}
if firstAccel [ "count" ] . ( int ) == 0 {
if err := d . Clear ( "guest_accelerator" ) ; err != nil {
return err
}
}
return nil
}
2014-08-25 21:57:17 +00:00
func resourceComputeInstanceDelete ( d * schema . ResourceData , meta interface { } ) error {
config := meta . ( * Config )
2016-04-10 16:59:57 +00:00
project , err := getProject ( d , config )
if err != nil {
return err
}
2017-12-06 22:30:04 +00:00
zone , err := getZone ( d , config )
if err != nil {
return err
}
2015-04-14 00:04:10 +00:00
log . Printf ( "[INFO] Requesting instance deletion: %s" , d . Id ( ) )
2014-08-25 21:57:17 +00:00
2018-03-16 21:09:21 +00:00
if d . Get ( "deletion_protection" ) . ( bool ) {
return fmt . Errorf ( "Cannot delete instance %s: instance Deletion Protection is enabled. Set deletion_protection to false for this resource and run \"terraform apply\" before attempting to delete it." , d . Id ( ) )
} else {
op , err := config . clientCompute . Instances . Delete ( project , zone , d . Id ( ) ) . Do ( )
if err != nil {
return fmt . Errorf ( "Error deleting instance: %s" , err )
}
2014-08-25 21:57:17 +00:00
2018-03-16 21:09:21 +00:00
// Wait for the operation to complete
opErr := computeOperationWaitTime ( config . clientCompute , op , project , "instance to delete" , int ( d . Timeout ( schema . TimeoutDelete ) . Minutes ( ) ) )
if opErr != nil {
return opErr
}
d . SetId ( "" )
return nil
}
2014-08-25 18:48:20 +00:00
}
2014-08-26 20:48:49 +00:00
2017-12-19 22:33:30 +00:00
func resourceComputeInstanceImportState ( d * schema . ResourceData , meta interface { } ) ( [ ] * schema . ResourceData , error ) {
parts := strings . Split ( d . Id ( ) , "/" )
if len ( parts ) != 3 {
return nil , fmt . Errorf ( "Invalid import id %q. Expecting {project}/{zone}/{instance_name}" , d . Id ( ) )
}
d . Set ( "project" , parts [ 0 ] )
d . Set ( "zone" , parts [ 1 ] )
d . SetId ( parts [ 2 ] )
return [ ] * schema . ResourceData { d } , nil
}
2017-08-22 19:49:43 +00:00
func expandBootDisk ( d * schema . ResourceData , config * Config , zone * compute . Zone , project string ) ( * computeBeta . AttachedDisk , error ) {
disk := & computeBeta . AttachedDisk {
2017-06-28 22:36:00 +00:00
AutoDelete : d . Get ( "boot_disk.0.auto_delete" ) . ( bool ) ,
Boot : true ,
}
if v , ok := d . GetOk ( "boot_disk.0.device_name" ) ; ok {
disk . DeviceName = v . ( string )
}
if v , ok := d . GetOk ( "boot_disk.0.disk_encryption_key_raw" ) ; ok {
2017-08-22 19:49:43 +00:00
disk . DiskEncryptionKey = & computeBeta . CustomerEncryptionKey {
2017-06-28 22:36:00 +00:00
RawKey : v . ( string ) ,
}
}
if v , ok := d . GetOk ( "boot_disk.0.source" ) ; ok {
2017-10-23 20:26:59 +00:00
source , err := ParseDiskFieldValue ( v . ( string ) , d , config )
2017-06-28 22:36:00 +00:00
if err != nil {
2017-10-23 20:26:59 +00:00
return nil , err
2017-06-28 22:36:00 +00:00
}
2017-10-23 20:26:59 +00:00
disk . Source = source . RelativeLink ( )
2017-06-28 22:36:00 +00:00
}
if _ , ok := d . GetOk ( "boot_disk.0.initialize_params" ) ; ok {
2017-08-22 19:49:43 +00:00
disk . InitializeParams = & computeBeta . AttachedDiskInitializeParams { }
2017-06-28 22:36:00 +00:00
if v , ok := d . GetOk ( "boot_disk.0.initialize_params.0.size" ) ; ok {
disk . InitializeParams . DiskSizeGb = int64 ( v . ( int ) )
}
if v , ok := d . GetOk ( "boot_disk.0.initialize_params.0.type" ) ; ok {
diskTypeName := v . ( string )
2017-09-27 00:01:52 +00:00
diskType , err := readDiskType ( config , zone , project , diskTypeName )
2017-06-28 22:36:00 +00:00
if err != nil {
return nil , fmt . Errorf ( "Error loading disk type '%s': %s" , diskTypeName , err )
}
2017-08-01 22:39:32 +00:00
disk . InitializeParams . DiskType = diskType . SelfLink
2017-06-28 22:36:00 +00:00
}
if v , ok := d . GetOk ( "boot_disk.0.initialize_params.0.image" ) ; ok {
imageName := v . ( string )
2017-09-27 00:01:52 +00:00
imageUrl , err := resolveImage ( config , project , imageName )
2017-06-28 22:36:00 +00:00
if err != nil {
return nil , fmt . Errorf ( "Error resolving image name '%s': %s" , imageName , err )
}
disk . InitializeParams . SourceImage = imageUrl
}
}
return disk , nil
}
2018-01-17 21:23:24 +00:00
func flattenBootDisk ( d * schema . ResourceData , disk * computeBeta . AttachedDisk , config * Config ) [ ] map [ string ] interface { } {
2017-06-28 22:36:00 +00:00
result := map [ string ] interface { } {
"auto_delete" : disk . AutoDelete ,
"device_name" : disk . DeviceName ,
2018-05-09 18:24:40 +00:00
"source" : ConvertSelfLinkToV1 ( disk . Source ) ,
2017-07-14 17:57:23 +00:00
// disk_encryption_key_raw is not returned from the API, so copy it from what the user
// originally specified to avoid diffs.
"disk_encryption_key_raw" : d . Get ( "boot_disk.0.disk_encryption_key_raw" ) ,
2017-06-28 22:36:00 +00:00
}
2018-01-17 21:23:24 +00:00
diskDetails , err := getDisk ( disk . Source , d , config )
if err != nil {
log . Printf ( "[WARN] Cannot retrieve boot disk details: %s" , err )
if _ , ok := d . GetOk ( "boot_disk.0.initialize_params.#" ) ; ok {
// If we can't read the disk details due to permission for instance,
// copy the initialize_params from what the user originally specified to avoid diffs.
m := d . Get ( "boot_disk.0.initialize_params" )
result [ "initialize_params" ] = m
}
} else {
result [ "initialize_params" ] = [ ] map [ string ] interface { } { {
"type" : GetResourceNameFromSelfLink ( diskDetails . Type ) ,
// If the config specifies a family name that doesn't match the image name, then
// the diff won't be properly suppressed. See DiffSuppressFunc for this field.
"image" : diskDetails . SourceImage ,
"size" : diskDetails . SizeGb ,
} }
}
2017-06-28 22:36:00 +00:00
if disk . DiskEncryptionKey != nil {
result [ "disk_encryption_key_sha256" ] = disk . DiskEncryptionKey . Sha256
}
return [ ] map [ string ] interface { } { result }
}
2017-06-28 22:43:58 +00:00
2017-09-27 00:01:52 +00:00
func expandScratchDisks ( d * schema . ResourceData , config * Config , zone * compute . Zone , project string ) ( [ ] * computeBeta . AttachedDisk , error ) {
diskType , err := readDiskType ( config , zone , project , "local-ssd" )
2017-06-28 22:43:58 +00:00
if err != nil {
return nil , fmt . Errorf ( "Error loading disk type 'local-ssd': %s" , err )
}
n := d . Get ( "scratch_disk.#" ) . ( int )
2017-08-22 19:49:43 +00:00
scratchDisks := make ( [ ] * computeBeta . AttachedDisk , 0 , n )
2017-06-28 22:43:58 +00:00
for i := 0 ; i < n ; i ++ {
2017-08-22 19:49:43 +00:00
scratchDisks = append ( scratchDisks , & computeBeta . AttachedDisk {
2017-06-28 22:43:58 +00:00
AutoDelete : true ,
Type : "SCRATCH" ,
Interface : d . Get ( fmt . Sprintf ( "scratch_disk.%d.interface" , i ) ) . ( string ) ,
2017-08-22 19:49:43 +00:00
InitializeParams : & computeBeta . AttachedDiskInitializeParams {
2017-06-28 22:43:58 +00:00
DiskType : diskType . SelfLink ,
} ,
} )
}
return scratchDisks , nil
}
2017-08-22 19:49:43 +00:00
func flattenScratchDisk ( disk * computeBeta . AttachedDisk ) map [ string ] interface { } {
2017-06-28 22:43:58 +00:00
result := map [ string ] interface { } {
"interface" : disk . Interface ,
}
return result
}
2017-08-04 18:00:45 +00:00
2017-09-07 14:04:26 +00:00
func hash256 ( raw string ) ( string , error ) {
decoded , err := base64 . StdEncoding . DecodeString ( raw )
if err != nil {
return "" , err
}
h := sha256 . Sum256 ( decoded )
return base64 . StdEncoding . EncodeToString ( h [ : ] ) , nil
}