From cd6f23e8ab0611863fd0d0149f10952e9d424060 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Thu, 13 Jun 2019 20:32:27 +0000 Subject: [PATCH] Add terraform support for external vpn gateway Signed-off-by: Modular Magician --- google-beta/provider_compute_gen.go | 1 + .../resource_compute_external_vpn_gateway.go | 351 ++++++++++++++++++ ...ute_external_vpn_gateway_generated_test.go | 187 ++++++++++ google-beta/resource_compute_vpn_tunnel.go | 18 +- ...compute_external_vpn_gateway.html.markdown | 229 ++++++++++++ website/google.erb | 5 + 6 files changed, 786 insertions(+), 5 deletions(-) create mode 100644 google-beta/resource_compute_external_vpn_gateway.go create mode 100644 google-beta/resource_compute_external_vpn_gateway_generated_test.go create mode 100644 website/docs/r/compute_external_vpn_gateway.html.markdown diff --git a/google-beta/provider_compute_gen.go b/google-beta/provider_compute_gen.go index 8eea9b3081..ca3dbbfe91 100644 --- a/google-beta/provider_compute_gen.go +++ b/google-beta/provider_compute_gen.go @@ -69,6 +69,7 @@ var GeneratedComputeResourcesMap = map[string]*schema.Resource{ "google_compute_target_tcp_proxy": resourceComputeTargetTcpProxy(), "google_compute_vpn_gateway": resourceComputeVpnGateway(), "google_compute_ha_vpn_gateway": resourceComputeHaVpnGateway(), + "google_compute_external_vpn_gateway": resourceComputeExternalVpnGateway(), "google_compute_url_map": resourceComputeUrlMap(), "google_compute_vpn_tunnel": resourceComputeVpnTunnel(), } diff --git a/google-beta/resource_compute_external_vpn_gateway.go b/google-beta/resource_compute_external_vpn_gateway.go new file mode 100644 index 0000000000..58c6e125b3 --- /dev/null +++ b/google-beta/resource_compute_external_vpn_gateway.go @@ -0,0 +1,351 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "strconv" + "time" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "google.golang.org/api/compute/v1" +) + +func resourceComputeExternalVpnGateway() *schema.Resource { + return &schema.Resource{ + Create: resourceComputeExternalVpnGatewayCreate, + Read: resourceComputeExternalVpnGatewayRead, + Delete: resourceComputeExternalVpnGatewayDelete, + + Importer: &schema.ResourceImporter{ + State: resourceComputeExternalVpnGatewayImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(240 * time.Second), + Delete: schema.DefaultTimeout(240 * time.Second), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "interface": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + "ip_address": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + }, + }, + "redundancy_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"FOUR_IPS_REDUNDANCY", "SINGLE_IP_INTERNALLY_REDUNDANT", "TWO_IPS_REDUNDANCY", ""}, false), + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "self_link": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceComputeExternalVpnGatewayCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + descriptionProp, err := expandComputeExternalVpnGatewayDescription(d.Get("description"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + nameProp, err := expandComputeExternalVpnGatewayName(d.Get("name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { + obj["name"] = nameProp + } + redundancyTypeProp, err := expandComputeExternalVpnGatewayRedundancyType(d.Get("redundancy_type"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("redundancy_type"); !isEmptyValue(reflect.ValueOf(redundancyTypeProp)) && (ok || !reflect.DeepEqual(v, redundancyTypeProp)) { + obj["redundancyType"] = redundancyTypeProp + } + interfacesProp, err := expandComputeExternalVpnGatewayInterface(d.Get("interface"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("interface"); !isEmptyValue(reflect.ValueOf(interfacesProp)) && (ok || !reflect.DeepEqual(v, interfacesProp)) { + obj["interfaces"] = interfacesProp + } + + url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/global/externalVpnGateways") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new ExternalVpnGateway: %#v", obj) + res, err := sendRequestWithTimeout(config, "POST", url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating ExternalVpnGateway: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + project, err := getProject(d, config) + if err != nil { + return err + } + op := &compute.Operation{} + err = Convert(res, op) + if err != nil { + return err + } + + waitErr := computeOperationWaitTime( + config.clientCompute, op, project, "Creating ExternalVpnGateway", + int(d.Timeout(schema.TimeoutCreate).Minutes())) + + if waitErr != nil { + // The resource didn't actually create + d.SetId("") + return fmt.Errorf("Error waiting to create ExternalVpnGateway: %s", waitErr) + } + + log.Printf("[DEBUG] Finished creating ExternalVpnGateway %q: %#v", d.Id(), res) + + return resourceComputeExternalVpnGatewayRead(d, meta) +} + +func resourceComputeExternalVpnGatewayRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/global/externalVpnGateways/{{name}}") + if err != nil { + return err + } + + res, err := sendRequest(config, "GET", url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("ComputeExternalVpnGateway %q", d.Id())) + } + + project, err := getProject(d, config) + if err != nil { + return err + } + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading ExternalVpnGateway: %s", err) + } + + if err := d.Set("description", flattenComputeExternalVpnGatewayDescription(res["description"], d)); err != nil { + return fmt.Errorf("Error reading ExternalVpnGateway: %s", err) + } + if err := d.Set("name", flattenComputeExternalVpnGatewayName(res["name"], d)); err != nil { + return fmt.Errorf("Error reading ExternalVpnGateway: %s", err) + } + if err := d.Set("redundancy_type", flattenComputeExternalVpnGatewayRedundancyType(res["redundancyType"], d)); err != nil { + return fmt.Errorf("Error reading ExternalVpnGateway: %s", err) + } + if err := d.Set("interface", flattenComputeExternalVpnGatewayInterface(res["interfaces"], d)); err != nil { + return fmt.Errorf("Error reading ExternalVpnGateway: %s", err) + } + if err := d.Set("self_link", ConvertSelfLinkToV1(res["selfLink"].(string))); err != nil { + return fmt.Errorf("Error reading ExternalVpnGateway: %s", err) + } + + return nil +} + +func resourceComputeExternalVpnGatewayDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/global/externalVpnGateways/{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting ExternalVpnGateway %q", d.Id()) + res, err := sendRequestWithTimeout(config, "DELETE", url, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "ExternalVpnGateway") + } + + project, err := getProject(d, config) + if err != nil { + return err + } + op := &compute.Operation{} + err = Convert(res, op) + if err != nil { + return err + } + + err = computeOperationWaitTime( + config.clientCompute, op, project, "Deleting ExternalVpnGateway", + int(d.Timeout(schema.TimeoutDelete).Minutes())) + + if err != nil { + return err + } + + log.Printf("[DEBUG] Finished deleting ExternalVpnGateway %q: %#v", d.Id(), res) + return nil +} + +func resourceComputeExternalVpnGatewayImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{"projects/(?P[^/]+)/global/externalVpnGateways/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenComputeExternalVpnGatewayDescription(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeExternalVpnGatewayName(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeExternalVpnGatewayRedundancyType(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeExternalVpnGatewayInterface(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "id": flattenComputeExternalVpnGatewayInterfaceId(original["id"], d), + "ip_address": flattenComputeExternalVpnGatewayInterfaceIpAddress(original["ipAddress"], d), + }) + } + return transformed +} +func flattenComputeExternalVpnGatewayInterfaceId(v interface{}, d *schema.ResourceData) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { + return intVal + } // let terraform core handle it if we can't convert the string to an int. + } + return v +} + +func flattenComputeExternalVpnGatewayInterfaceIpAddress(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func expandComputeExternalVpnGatewayDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeExternalVpnGatewayName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeExternalVpnGatewayRedundancyType(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeExternalVpnGatewayInterface(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedId, err := expandComputeExternalVpnGatewayInterfaceId(original["id"], d, config) + if err != nil { + return nil, err + } else { + transformed["id"] = transformedId + } + + transformedIpAddress, err := expandComputeExternalVpnGatewayInterfaceIpAddress(original["ip_address"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIpAddress); val.IsValid() && !isEmptyValue(val) { + transformed["ipAddress"] = transformedIpAddress + } + + req = append(req, transformed) + } + return req, nil +} + +func expandComputeExternalVpnGatewayInterfaceId(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeExternalVpnGatewayInterfaceIpAddress(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google-beta/resource_compute_external_vpn_gateway_generated_test.go b/google-beta/resource_compute_external_vpn_gateway_generated_test.go new file mode 100644 index 0000000000..b2ff8a3768 --- /dev/null +++ b/google-beta/resource_compute_external_vpn_gateway_generated_test.go @@ -0,0 +1,187 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccComputeExternalVpnGateway_externalVpnGatewayExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProvidersOiCS, + CheckDestroy: testAccCheckComputeExternalVpnGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccComputeExternalVpnGateway_externalVpnGatewayExample(context), + }, + }, + }) +} + +func testAccComputeExternalVpnGateway_externalVpnGatewayExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_ha_vpn_gateway" "ha_gateway" { + provider = "google-beta" + region = "us-central1" + name = "ha-vpn-%{random_suffix}" + network = "${google_compute_network.network.self_link}" +} + +resource "google_compute_external_vpn_gateway" "external_gateway" { + provider = "google-beta" + name = "external-gateway-%{random_suffix}" + redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" + description = "An externally managed VPN gateway" + interface { + id = 0 + ip_address = "8.8.8.8" + } +} + +resource "google_compute_network" "network" { + provider = "google-beta" + name = "network-%{random_suffix}" + routing_mode = "GLOBAL" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "network_subnet1" { + provider = "google-beta" + name = "ha-vpn-subnet-1" + ip_cidr_range = "10.0.1.0/24" + region = "us-central1" + network = "${google_compute_network.network.self_link}" +} + +resource "google_compute_subnetwork" "network_subnet2" { + provider = "google-beta" + name = "ha-vpn-subnet-2" + ip_cidr_range = "10.0.2.0/24" + region = "us-west1" + network = "${google_compute_network.network.self_link}" +} + +resource "google_compute_router" "router1" { + provider = "google-beta" + name = "ha-vpn-router1" + network = "${google_compute_network.network.name}" + bgp { + asn = 64514 + } +} + +resource "google_compute_vpn_tunnel" "tunnel1" { + provider = "google-beta" + name = "ha-vpn-tunnel1" + region = "us-central1" + vpn_gateway = "${google_compute_ha_vpn_gateway.ha_gateway.self_link}" + peer_external_gateway = "${google_compute_external_vpn_gateway.external_gateway.self_link}" + peer_external_gateway_interface = 0 + shared_secret = "a secret message" + router = "${google_compute_router.router1.self_link}" + vpn_gateway_interface = 0 +} + +resource "google_compute_vpn_tunnel" "tunnel2" { + provider = "google-beta" + name = "ha-vpn-tunnel2" + region = "us-central1" + vpn_gateway = "${google_compute_ha_vpn_gateway.ha_gateway.self_link}" + peer_external_gateway = "${google_compute_external_vpn_gateway.external_gateway.self_link}" + peer_external_gateway_interface = 0 + shared_secret = "a secret message" + router = " ${google_compute_router.router1.self_link}" + vpn_gateway_interface = 1 +} + +resource "google_compute_router_interface" "router1_interface1" { + provider = "google-beta" + name = "router1-interface1" + router = "${google_compute_router.router1.name}" + region = "us-central1" + ip_range = "169.254.0.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.tunnel1.name}" +} + +resource "google_compute_router_peer" "router1_peer1" { + provider = "google-beta" + name = "router1-peer1" + router = "${google_compute_router.router1.name}" + region = "us-central1" + peer_ip_address = "169.254.0.2" + peer_asn = 64515 + advertised_route_priority = 100 + interface = "${google_compute_router_interface.router1_interface1.name}" +} + +resource "google_compute_router_interface" "router1_interface2" { + provider = "google-beta" + name = "router1-interface2" + router = "${google_compute_router.router1.name}" + region = "us-central1" + ip_range = "169.254.1.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.tunnel2.name}" +} + +resource "google_compute_router_peer" "router1_peer2" { + provider = "google-beta" + name = "router1-peer2" + router = "${google_compute_router.router1.name}" + region = "us-central1" + peer_ip_address = "169.254.1.2" + peer_asn = 64515 + advertised_route_priority = 100 + interface = "${google_compute_router_interface.router1_interface2.name}" +} +`, context) +} + +func testAccCheckComputeExternalVpnGatewayDestroy(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_external_vpn_gateway" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := testAccProvider.Meta().(*Config) + + url, err := replaceVarsForTest(rs, "{{ComputeBasePath}}projects/{{project}}/global/externalVpnGateways/{{name}}") + if err != nil { + return err + } + + _, err = sendRequest(config, "GET", url, nil) + if err == nil { + return fmt.Errorf("ComputeExternalVpnGateway still exists at %s", url) + } + } + + return nil +} diff --git a/google-beta/resource_compute_vpn_tunnel.go b/google-beta/resource_compute_vpn_tunnel.go index d0a2bc0829..cb5d220ee3 100644 --- a/google-beta/resource_compute_vpn_tunnel.go +++ b/google-beta/resource_compute_vpn_tunnel.go @@ -185,9 +185,10 @@ func resourceComputeVpnTunnel() *schema.Resource { Set: schema.HashString, }, "peer_external_gateway": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, }, "peer_external_gateway_interface": { Type: schema.TypeInt, @@ -704,7 +705,10 @@ func flattenComputeVpnTunnelVpnGatewayInterface(v interface{}, d *schema.Resourc } func flattenComputeVpnTunnelPeerExternalGateway(v interface{}, d *schema.ResourceData) interface{} { - return v + if v == nil { + return v + } + return ConvertSelfLinkToV1(v.(string)) } func flattenComputeVpnTunnelPeerExternalGatewayInterface(v interface{}, d *schema.ResourceData) interface{} { @@ -811,7 +815,11 @@ func expandComputeVpnTunnelVpnGatewayInterface(v interface{}, d TerraformResourc } func expandComputeVpnTunnelPeerExternalGateway(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { - return v, nil + f, err := parseGlobalFieldValue("externalVpnGateways", v.(string), "project", d, config, true) + if err != nil { + return nil, fmt.Errorf("Invalid value for peer_external_gateway: %s", err) + } + return f.RelativeLink(), nil } func expandComputeVpnTunnelPeerExternalGatewayInterface(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { diff --git a/website/docs/r/compute_external_vpn_gateway.html.markdown b/website/docs/r/compute_external_vpn_gateway.html.markdown new file mode 100644 index 0000000000..ebab1423b2 --- /dev/null +++ b/website/docs/r/compute_external_vpn_gateway.html.markdown @@ -0,0 +1,229 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +layout: "google" +page_title: "Google: google_compute_external_vpn_gateway" +sidebar_current: "docs-google-compute-external-vpn-gateway" +description: |- + Represents a VPN gateway managed outside of GCP. +--- + +# google\_compute\_external\_vpn\_gateway + +Represents a VPN gateway managed outside of GCP. + +~> **Warning:** This resource is in beta, and should be used with the terraform-provider-google-beta provider. +See [Provider Versions](https://terraform.io/docs/providers/google/provider_versions.html) for more details on beta resources. + +To get more information about ExternalVpnGateway, see: + +* [API documentation](https://cloud.google.com/compute/docs/reference/rest/beta/externalVpnGateways) + + +## Example Usage - External Vpn Gateway + + +```hcl +resource "google_compute_ha_vpn_gateway" "ha_gateway" { + provider = "google-beta" + region = "us-central1" + name = "ha-vpn" + network = "${google_compute_network.network.self_link}" +} + +resource "google_compute_external_vpn_gateway" "external_gateway" { + provider = "google-beta" + name = "external-gateway" + redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" + description = "An externally managed VPN gateway" + interface { + id = 0 + ip_address = "8.8.8.8" + } +} + +resource "google_compute_network" "network" { + provider = "google-beta" + name = "network" + routing_mode = "GLOBAL" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "network_subnet1" { + provider = "google-beta" + name = "ha-vpn-subnet-1" + ip_cidr_range = "10.0.1.0/24" + region = "us-central1" + network = "${google_compute_network.network.self_link}" +} + +resource "google_compute_subnetwork" "network_subnet2" { + provider = "google-beta" + name = "ha-vpn-subnet-2" + ip_cidr_range = "10.0.2.0/24" + region = "us-west1" + network = "${google_compute_network.network.self_link}" +} + +resource "google_compute_router" "router1" { + provider = "google-beta" + name = "ha-vpn-router1" + network = "${google_compute_network.network.name}" + bgp { + asn = 64514 + } +} + +resource "google_compute_vpn_tunnel" "tunnel1" { + provider = "google-beta" + name = "ha-vpn-tunnel1" + region = "us-central1" + vpn_gateway = "${google_compute_ha_vpn_gateway.ha_gateway.self_link}" + peer_external_gateway = "${google_compute_external_vpn_gateway.external_gateway.self_link}" + peer_external_gateway_interface = 0 + shared_secret = "a secret message" + router = "${google_compute_router.router1.self_link}" + vpn_gateway_interface = 0 +} + +resource "google_compute_vpn_tunnel" "tunnel2" { + provider = "google-beta" + name = "ha-vpn-tunnel2" + region = "us-central1" + vpn_gateway = "${google_compute_ha_vpn_gateway.ha_gateway.self_link}" + peer_external_gateway = "${google_compute_external_vpn_gateway.external_gateway.self_link}" + peer_external_gateway_interface = 0 + shared_secret = "a secret message" + router = " ${google_compute_router.router1.self_link}" + vpn_gateway_interface = 1 +} + +resource "google_compute_router_interface" "router1_interface1" { + provider = "google-beta" + name = "router1-interface1" + router = "${google_compute_router.router1.name}" + region = "us-central1" + ip_range = "169.254.0.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.tunnel1.name}" +} + +resource "google_compute_router_peer" "router1_peer1" { + provider = "google-beta" + name = "router1-peer1" + router = "${google_compute_router.router1.name}" + region = "us-central1" + peer_ip_address = "169.254.0.2" + peer_asn = 64515 + advertised_route_priority = 100 + interface = "${google_compute_router_interface.router1_interface1.name}" +} + +resource "google_compute_router_interface" "router1_interface2" { + provider = "google-beta" + name = "router1-interface2" + router = "${google_compute_router.router1.name}" + region = "us-central1" + ip_range = "169.254.1.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.tunnel2.name}" +} + +resource "google_compute_router_peer" "router1_peer2" { + provider = "google-beta" + name = "router1-peer2" + router = "${google_compute_router.router1.name}" + region = "us-central1" + peer_ip_address = "169.254.1.2" + peer_asn = 64515 + advertised_route_priority = 100 + interface = "${google_compute_router_interface.router1_interface2.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `name` - + (Required) + Name of the resource. Provided by the client when the resource is + created. The name must be 1-63 characters long, and comply with + RFC1035. Specifically, the name must be 1-63 characters long and + match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means + the first character must be a lowercase letter, and all following + characters must be a dash, lowercase letter, or digit, except the last + character, which cannot be a dash. + + +- - - + + +* `description` - + (Optional) + An optional description of this resource. + +* `redundancy_type` - + (Optional) + Indicates the redundancy type of this external VPN gateway + +* `interface` - + (Optional) + A list of interfaces on this external VPN gateway. Structure is documented below. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + +The `interface` block supports: + +* `id` - + (Optional) + The numberic ID for this interface. Allowed values are based on the redundancy type + of this external VPN gateway + * `0 - SINGLE_IP_INTERNALLY_REDUNDANT` + * `0, 1 - TWO_IPS_REDUNDANCY` + * `0, 1, 2, 3 - FOUR_IPS_REDUNDANCY` + +* `ip_address` - + (Optional) + IP address of the interface in the external VPN gateway. + Only IPv4 is supported. This IP address can be either from + your on-premise gateway or another Cloud provider’s VPN gateway, + it cannot be an IP address from Google Compute Engine. + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +ExternalVpnGateway can be imported using any of these accepted formats: + +``` +$ terraform import -provider=google-beta google_compute_external_vpn_gateway.default projects/{{project}}/global/externalVpnGateways/{{name}} +$ terraform import -provider=google-beta google_compute_external_vpn_gateway.default {{project}}/{{name}} +$ terraform import -provider=google-beta google_compute_external_vpn_gateway.default {{name}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. diff --git a/website/google.erb b/website/google.erb index 807a4bc163..22f3988fc7 100644 --- a/website/google.erb +++ b/website/google.erb @@ -411,6 +411,11 @@ google_compute_disk + + > + google_compute_external_vpn_gateway + + > google_compute_firewall