diff --git a/builtin/providers/google/resource_compute_instance_template.go b/builtin/providers/google/resource_compute_instance_template.go index da0708b3b6..9b9798dc21 100644 --- a/builtin/providers/google/resource_compute_instance_template.go +++ b/builtin/providers/google/resource_compute_instance_template.go @@ -203,6 +203,12 @@ func resourceComputeInstanceTemplate() *schema.Resource { ForceNew: true, }, + "subnetwork_project": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "access_config": &schema.Schema{ Type: schema.TypeList, Optional: true, @@ -406,14 +412,16 @@ func buildNetworks(d *schema.ResourceData, meta interface{}) ([]*compute.Network for i := 0; i < networksCount; i++ { prefix := fmt.Sprintf("network_interface.%d", i) - var networkName, subnetworkName string + var networkName, subnetworkName, subnetworkProject string if v, ok := d.GetOk(prefix + ".network"); ok { networkName = v.(string) } if v, ok := d.GetOk(prefix + ".subnetwork"); ok { subnetworkName = v.(string) } - + if v, ok := d.GetOk(prefix + ".subnetwork_project"); ok { + subnetworkProject = v.(string) + } if networkName == "" && subnetworkName == "" { return nil, fmt.Errorf("network or subnetwork must be provided") } @@ -435,8 +443,11 @@ func buildNetworks(d *schema.ResourceData, meta interface{}) ([]*compute.Network if err != nil { return nil, err } + if subnetworkProject == "" { + subnetworkProject = project + } subnetwork, err := config.clientCompute.Subnetworks.Get( - project, region, subnetworkName).Do() + subnetworkProject, region, subnetworkName).Do() if err != nil { return nil, fmt.Errorf( "Error referencing subnetwork '%s' in region '%s': %s", @@ -639,6 +650,7 @@ func flattenNetworkInterfaces(networkInterfaces []*compute.NetworkInterface) ([] subnetworkUrl := strings.Split(networkInterface.Subnetwork, "/") networkInterfaceMap["subnetwork"] = subnetworkUrl[len(subnetworkUrl)-1] region = subnetworkUrl[len(subnetworkUrl)-3] + networkInterfaceMap["subnetwork_project"] = subnetworkUrl[len(subnetworkUrl)-5] } if networkInterface.AccessConfigs != nil { diff --git a/builtin/providers/google/resource_compute_instance_template_test.go b/builtin/providers/google/resource_compute_instance_template_test.go index 642e0e57fe..e287d32e2c 100644 --- a/builtin/providers/google/resource_compute_instance_template_test.go +++ b/builtin/providers/google/resource_compute_instance_template_test.go @@ -2,6 +2,7 @@ package google import ( "fmt" + "os" "strings" "testing" @@ -115,6 +116,27 @@ func TestAccComputeInstanceTemplate_subnet_custom(t *testing.T) { }) } +func TestAccComputeInstanceTemplate_subnet_xpn(t *testing.T) { + var instanceTemplate compute.InstanceTemplate + var xpn_host = os.Getenv("GOOGLE_XPN_HOST_PROJECT") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeInstanceTemplateDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeInstanceTemplate_subnet_xpn(xpn_host), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeInstanceTemplateExists( + "google_compute_instance_template.foobar", &instanceTemplate), + testAccCheckComputeInstanceTemplateSubnetwork(&instanceTemplate), + ), + }, + }, + }) +} + func TestAccComputeInstanceTemplate_metadata_startup_script(t *testing.T) { var instanceTemplate compute.InstanceTemplate @@ -467,6 +489,45 @@ resource "google_compute_instance_template" "foobar" { } }`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) +func testAccComputeInstanceTemplate_subnet_xpn(xpn_host string) string { + return fmt.Sprintf(` + resource "google_compute_network" "network" { + name = "network-%s" + auto_create_subnetworks = false + project = "%s" + } + + resource "google_compute_subnetwork" "subnetwork" { + name = "subnetwork-%s" + ip_cidr_range = "10.0.0.0/24" + region = "us-central1" + network = "${google_compute_network.network.self_link}" + project = "%s" + } + + resource "google_compute_instance_template" "foobar" { + name = "instance-test-%s" + machine_type = "n1-standard-1" + region = "us-central1" + + disk { + source_image = "debian-8-jessie-v20160803" + auto_delete = true + disk_size_gb = 10 + boot = true + } + + network_interface { + subnetwork = "${google_compute_subnetwork.subnetwork.name}" + subnetwork_project = "${google_compute_subnetwork.subnetwork.project}" + } + + metadata { + foo = "bar" + } + }`, acctest.RandString(10), xpn_host, acctest.RandString(10), xpn_host, acctest.RandString(10)) +} + var testAccComputeInstanceTemplate_startup_script = fmt.Sprintf(` resource "google_compute_instance_template" "foobar" { name = "instance-test-%s" @@ -486,6 +547,6 @@ resource "google_compute_instance_template" "foobar" { network_interface{ network = "default" } - + metadata_startup_script = "echo 'Hello'" }`, acctest.RandString(10)) diff --git a/website/source/docs/providers/google/r/compute_instance_template.html.markdown b/website/source/docs/providers/google/r/compute_instance_template.html.markdown index 201abc3333..796cb4e907 100644 --- a/website/source/docs/providers/google/r/compute_instance_template.html.markdown +++ b/website/source/docs/providers/google/r/compute_instance_template.html.markdown @@ -138,7 +138,7 @@ The following arguments are supported: * `metadata_startup_script` - (Optional) An alternative to using the startup-script metadata key, mostly to match the compute_instance resource. - This replaces the startup-script metadata key on the created instance and + This replaces the startup-script metadata key on the created instance and thus the two mechanisms are not allowed to be used simultaneously. * `network_interface` - (Required) Networks to attach to instances created from @@ -208,6 +208,9 @@ The `network_interface` block supports: to. The subnetwork must exist in the same `region` this instance will be created in. Either `network` or `subnetwork` must be provided. +* `subnetwork_project` - (Optional) The project in which the subnetwork belongs. + If it is not provided, the provider project is used. + * `access_config` - (Optional) Access configurations, i.e. IPs via which this instance can be accessed via the Internet. Omit to ensure that the instance is not accessible from the Internet (this means that ssh provisioners will