Documentation and tests written for GCE VPN config
This commit is contained in:
parent
b91df72371
commit
6850786422
|
@ -7,6 +7,7 @@ FEATURES:
|
||||||
* **New resource: `google_compute_project_metadata`** [GH-3065]
|
* **New resource: `google_compute_project_metadata`** [GH-3065]
|
||||||
* **New resources: `aws_ami`, `aws_ami_copy`, `aws_ami_from_instance`** [GH-2874]
|
* **New resources: `aws_ami`, `aws_ami_copy`, `aws_ami_from_instance`** [GH-2874]
|
||||||
* **New resource: `google_storage_bucket_object`** [GH-3192]
|
* **New resource: `google_storage_bucket_object`** [GH-3192]
|
||||||
|
* **New resources: `google_compute_vpn_gateway`, `google_compute_vpn_tunnel`** [GH-3213]
|
||||||
|
|
||||||
IMPROVEMENTS:
|
IMPROVEMENTS:
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@ func Provider() terraform.ResourceProvider {
|
||||||
"google_compute_project_metadata": resourceComputeProjectMetadata(),
|
"google_compute_project_metadata": resourceComputeProjectMetadata(),
|
||||||
"google_compute_route": resourceComputeRoute(),
|
"google_compute_route": resourceComputeRoute(),
|
||||||
"google_compute_target_pool": resourceComputeTargetPool(),
|
"google_compute_target_pool": resourceComputeTargetPool(),
|
||||||
|
"google_compute_vpn_gateway": resourceComputeVpnGateway(),
|
||||||
|
"google_compute_vpn_tunnel": resourceComputeVpnTunnel(),
|
||||||
"google_container_cluster": resourceContainerCluster(),
|
"google_container_cluster": resourceContainerCluster(),
|
||||||
"google_dns_managed_zone": resourceDnsManagedZone(),
|
"google_dns_managed_zone": resourceDnsManagedZone(),
|
||||||
"google_dns_record_set": resourceDnsRecordSet(),
|
"google_dns_record_set": resourceDnsRecordSet(),
|
||||||
|
|
|
@ -32,18 +32,32 @@ func resourceComputeAddress() *schema.Resource {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"region": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOptionalRegion(d *schema.ResourceData, config *Config) string {
|
||||||
|
if res, ok := d.GetOk("region"); !ok {
|
||||||
|
return config.Region
|
||||||
|
} else {
|
||||||
|
return res.(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func resourceComputeAddressCreate(d *schema.ResourceData, meta interface{}) error {
|
func resourceComputeAddressCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
region := getOptionalRegion(d, config)
|
||||||
|
|
||||||
// Build the address parameter
|
// Build the address parameter
|
||||||
addr := &compute.Address{Name: d.Get("name").(string)}
|
addr := &compute.Address{Name: d.Get("name").(string)}
|
||||||
log.Printf("[DEBUG] Address insert request: %#v", addr)
|
|
||||||
op, err := config.clientCompute.Addresses.Insert(
|
op, err := config.clientCompute.Addresses.Insert(
|
||||||
config.Project, config.Region, addr).Do()
|
config.Project, region, addr).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error creating address: %s", err)
|
return fmt.Errorf("Error creating address: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +70,7 @@ func resourceComputeAddressCreate(d *schema.ResourceData, meta interface{}) erro
|
||||||
Service: config.clientCompute,
|
Service: config.clientCompute,
|
||||||
Op: op,
|
Op: op,
|
||||||
Project: config.Project,
|
Project: config.Project,
|
||||||
Region: config.Region,
|
Region: region,
|
||||||
Type: OperationWaitRegion,
|
Type: OperationWaitRegion,
|
||||||
}
|
}
|
||||||
state := w.Conf()
|
state := w.Conf()
|
||||||
|
@ -81,8 +95,10 @@ func resourceComputeAddressCreate(d *schema.ResourceData, meta interface{}) erro
|
||||||
func resourceComputeAddressRead(d *schema.ResourceData, meta interface{}) error {
|
func resourceComputeAddressRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
region := getOptionalRegion(d, config)
|
||||||
|
|
||||||
addr, err := config.clientCompute.Addresses.Get(
|
addr, err := config.clientCompute.Addresses.Get(
|
||||||
config.Project, config.Region, d.Id()).Do()
|
config.Project, region, d.Id()).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
|
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
|
||||||
// The resource doesn't exist anymore
|
// The resource doesn't exist anymore
|
||||||
|
@ -103,10 +119,11 @@ func resourceComputeAddressRead(d *schema.ResourceData, meta interface{}) error
|
||||||
func resourceComputeAddressDelete(d *schema.ResourceData, meta interface{}) error {
|
func resourceComputeAddressDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
region := getOptionalRegion(d, config)
|
||||||
// Delete the address
|
// Delete the address
|
||||||
log.Printf("[DEBUG] address delete request")
|
log.Printf("[DEBUG] address delete request")
|
||||||
op, err := config.clientCompute.Addresses.Delete(
|
op, err := config.clientCompute.Addresses.Delete(
|
||||||
config.Project, config.Region, d.Id()).Do()
|
config.Project, region, d.Id()).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error deleting address: %s", err)
|
return fmt.Errorf("Error deleting address: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -116,7 +133,7 @@ func resourceComputeAddressDelete(d *schema.ResourceData, meta interface{}) erro
|
||||||
Service: config.clientCompute,
|
Service: config.clientCompute,
|
||||||
Op: op,
|
Op: op,
|
||||||
Project: config.Project,
|
Project: config.Project,
|
||||||
Region: config.Region,
|
Region: region,
|
||||||
Type: OperationWaitRegion,
|
Type: OperationWaitRegion,
|
||||||
}
|
}
|
||||||
state := w.Conf()
|
state := w.Conf()
|
||||||
|
|
|
@ -50,6 +50,12 @@ func resourceComputeForwardingRule() *schema.Resource {
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"region": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
"self_link": &schema.Schema{
|
"self_link": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
@ -67,6 +73,8 @@ func resourceComputeForwardingRule() *schema.Resource {
|
||||||
func resourceComputeForwardingRuleCreate(d *schema.ResourceData, meta interface{}) error {
|
func resourceComputeForwardingRuleCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
region := getOptionalRegion(d, config)
|
||||||
|
|
||||||
frule := &compute.ForwardingRule{
|
frule := &compute.ForwardingRule{
|
||||||
IPAddress: d.Get("ip_address").(string),
|
IPAddress: d.Get("ip_address").(string),
|
||||||
IPProtocol: d.Get("ip_protocol").(string),
|
IPProtocol: d.Get("ip_protocol").(string),
|
||||||
|
@ -78,7 +86,7 @@ func resourceComputeForwardingRuleCreate(d *schema.ResourceData, meta interface{
|
||||||
|
|
||||||
log.Printf("[DEBUG] ForwardingRule insert request: %#v", frule)
|
log.Printf("[DEBUG] ForwardingRule insert request: %#v", frule)
|
||||||
op, err := config.clientCompute.ForwardingRules.Insert(
|
op, err := config.clientCompute.ForwardingRules.Insert(
|
||||||
config.Project, config.Region, frule).Do()
|
config.Project, region, frule).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error creating ForwardingRule: %s", err)
|
return fmt.Errorf("Error creating ForwardingRule: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -90,7 +98,7 @@ func resourceComputeForwardingRuleCreate(d *schema.ResourceData, meta interface{
|
||||||
w := &OperationWaiter{
|
w := &OperationWaiter{
|
||||||
Service: config.clientCompute,
|
Service: config.clientCompute,
|
||||||
Op: op,
|
Op: op,
|
||||||
Region: config.Region,
|
Region: region,
|
||||||
Project: config.Project,
|
Project: config.Project,
|
||||||
Type: OperationWaitRegion,
|
Type: OperationWaitRegion,
|
||||||
}
|
}
|
||||||
|
@ -116,13 +124,15 @@ func resourceComputeForwardingRuleCreate(d *schema.ResourceData, meta interface{
|
||||||
func resourceComputeForwardingRuleUpdate(d *schema.ResourceData, meta interface{}) error {
|
func resourceComputeForwardingRuleUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
region := getOptionalRegion(d, config)
|
||||||
|
|
||||||
d.Partial(true)
|
d.Partial(true)
|
||||||
|
|
||||||
if d.HasChange("target") {
|
if d.HasChange("target") {
|
||||||
target_name := d.Get("target").(string)
|
target_name := d.Get("target").(string)
|
||||||
target_ref := &compute.TargetReference{Target: target_name}
|
target_ref := &compute.TargetReference{Target: target_name}
|
||||||
op, err := config.clientCompute.ForwardingRules.SetTarget(
|
op, err := config.clientCompute.ForwardingRules.SetTarget(
|
||||||
config.Project, config.Region, d.Id(), target_ref).Do()
|
config.Project, region, d.Id(), target_ref).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error updating target: %s", err)
|
return fmt.Errorf("Error updating target: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -131,7 +141,7 @@ func resourceComputeForwardingRuleUpdate(d *schema.ResourceData, meta interface{
|
||||||
w := &OperationWaiter{
|
w := &OperationWaiter{
|
||||||
Service: config.clientCompute,
|
Service: config.clientCompute,
|
||||||
Op: op,
|
Op: op,
|
||||||
Region: config.Region,
|
Region: region,
|
||||||
Project: config.Project,
|
Project: config.Project,
|
||||||
Type: OperationWaitRegion,
|
Type: OperationWaitRegion,
|
||||||
}
|
}
|
||||||
|
@ -161,8 +171,10 @@ func resourceComputeForwardingRuleUpdate(d *schema.ResourceData, meta interface{
|
||||||
func resourceComputeForwardingRuleRead(d *schema.ResourceData, meta interface{}) error {
|
func resourceComputeForwardingRuleRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
region := getOptionalRegion(d, config)
|
||||||
|
|
||||||
frule, err := config.clientCompute.ForwardingRules.Get(
|
frule, err := config.clientCompute.ForwardingRules.Get(
|
||||||
config.Project, config.Region, d.Id()).Do()
|
config.Project, region, d.Id()).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
|
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
|
||||||
// The resource doesn't exist anymore
|
// The resource doesn't exist anymore
|
||||||
|
@ -184,10 +196,12 @@ func resourceComputeForwardingRuleRead(d *schema.ResourceData, meta interface{})
|
||||||
func resourceComputeForwardingRuleDelete(d *schema.ResourceData, meta interface{}) error {
|
func resourceComputeForwardingRuleDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
region := getOptionalRegion(d, config)
|
||||||
|
|
||||||
// Delete the ForwardingRule
|
// Delete the ForwardingRule
|
||||||
log.Printf("[DEBUG] ForwardingRule delete request")
|
log.Printf("[DEBUG] ForwardingRule delete request")
|
||||||
op, err := config.clientCompute.ForwardingRules.Delete(
|
op, err := config.clientCompute.ForwardingRules.Delete(
|
||||||
config.Project, config.Region, d.Id()).Do()
|
config.Project, region, d.Id()).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error deleting ForwardingRule: %s", err)
|
return fmt.Errorf("Error deleting ForwardingRule: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -196,7 +210,7 @@ func resourceComputeForwardingRuleDelete(d *schema.ResourceData, meta interface{
|
||||||
w := &OperationWaiter{
|
w := &OperationWaiter{
|
||||||
Service: config.clientCompute,
|
Service: config.clientCompute,
|
||||||
Op: op,
|
Op: op,
|
||||||
Region: config.Region,
|
Region: region,
|
||||||
Project: config.Project,
|
Project: config.Project,
|
||||||
Type: OperationWaitRegion,
|
Type: OperationWaitRegion,
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,12 @@ func resourceComputeRoute() *schema.Resource {
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"next_hop_vpn_tunnel": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
"priority": &schema.Schema{
|
"priority": &schema.Schema{
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Required: true,
|
Required: true,
|
||||||
|
@ -101,13 +107,17 @@ func resourceComputeRouteCreate(d *schema.ResourceData, meta interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next hop data
|
// Next hop data
|
||||||
var nextHopInstance, nextHopIp, nextHopNetwork, nextHopGateway string
|
var nextHopInstance, nextHopIp, nextHopNetwork, nextHopGateway,
|
||||||
|
nextHopVpnTunnel string
|
||||||
if v, ok := d.GetOk("next_hop_ip"); ok {
|
if v, ok := d.GetOk("next_hop_ip"); ok {
|
||||||
nextHopIp = v.(string)
|
nextHopIp = v.(string)
|
||||||
}
|
}
|
||||||
if v, ok := d.GetOk("next_hop_gateway"); ok {
|
if v, ok := d.GetOk("next_hop_gateway"); ok {
|
||||||
nextHopGateway = v.(string)
|
nextHopGateway = v.(string)
|
||||||
}
|
}
|
||||||
|
if v, ok := d.GetOk("next_hop_vpn_tunnel"); ok {
|
||||||
|
nextHopVpnTunnel = v.(string)
|
||||||
|
}
|
||||||
if v, ok := d.GetOk("next_hop_instance"); ok {
|
if v, ok := d.GetOk("next_hop_instance"); ok {
|
||||||
nextInstance, err := config.clientCompute.Instances.Get(
|
nextInstance, err := config.clientCompute.Instances.Get(
|
||||||
config.Project,
|
config.Project,
|
||||||
|
@ -140,15 +150,16 @@ func resourceComputeRouteCreate(d *schema.ResourceData, meta interface{}) error
|
||||||
|
|
||||||
// Build the route parameter
|
// Build the route parameter
|
||||||
route := &compute.Route{
|
route := &compute.Route{
|
||||||
Name: d.Get("name").(string),
|
Name: d.Get("name").(string),
|
||||||
DestRange: d.Get("dest_range").(string),
|
DestRange: d.Get("dest_range").(string),
|
||||||
Network: network.SelfLink,
|
Network: network.SelfLink,
|
||||||
NextHopInstance: nextHopInstance,
|
NextHopInstance: nextHopInstance,
|
||||||
NextHopIp: nextHopIp,
|
NextHopVpnTunnel: nextHopVpnTunnel,
|
||||||
NextHopNetwork: nextHopNetwork,
|
NextHopIp: nextHopIp,
|
||||||
NextHopGateway: nextHopGateway,
|
NextHopNetwork: nextHopNetwork,
|
||||||
Priority: int64(d.Get("priority").(int)),
|
NextHopGateway: nextHopGateway,
|
||||||
Tags: tags,
|
Priority: int64(d.Get("priority").(int)),
|
||||||
|
Tags: tags,
|
||||||
}
|
}
|
||||||
log.Printf("[DEBUG] Route insert request: %#v", route)
|
log.Printf("[DEBUG] Route insert request: %#v", route)
|
||||||
op, err := config.clientCompute.Routes.Insert(
|
op, err := config.clientCompute.Routes.Insert(
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
|
||||||
|
"google.golang.org/api/compute/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceComputeVpnGateway() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
// Unfortunately, the VPNGatewayService does not support update
|
||||||
|
// operations. This is why everything is marked forcenew
|
||||||
|
Create: resourceComputeVpnGatewayCreate,
|
||||||
|
Read: resourceComputeVpnGatewayRead,
|
||||||
|
Delete: resourceComputeVpnGatewayDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"description": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"network": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"region": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"self_link": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeVpnGatewayCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
network := d.Get("network").(string)
|
||||||
|
region := getOptionalRegion(d, config)
|
||||||
|
project := config.Project
|
||||||
|
|
||||||
|
vpnGatewaysService := compute.NewTargetVpnGatewaysService(config.clientCompute)
|
||||||
|
|
||||||
|
vpnGateway := &compute.TargetVpnGateway{
|
||||||
|
Name: name,
|
||||||
|
Network: network,
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("description"); ok {
|
||||||
|
vpnGateway.Description = v.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
op, err := vpnGatewaysService.Insert(project, region, vpnGateway).Do()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Inserting VPN Gateway %s into network %s: %s", name, network, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = resourceOperationWaitRegion(config, op, region, "Inserting VPN Gateway")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Waiting to Insert VPN Gateway %s into network %s: %s", name, network, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceComputeVpnGatewayRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeVpnGatewayRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
region := d.Get("region").(string)
|
||||||
|
project := config.Project
|
||||||
|
|
||||||
|
vpnGatewaysService := compute.NewTargetVpnGatewaysService(config.clientCompute)
|
||||||
|
vpnGateway, err := vpnGatewaysService.Get(project, region, name).Do()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Reading VPN Gateway %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("self_link", vpnGateway.SelfLink)
|
||||||
|
d.SetId(name)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeVpnGatewayDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
region := d.Get("region").(string)
|
||||||
|
project := config.Project
|
||||||
|
|
||||||
|
vpnGatewaysService := compute.NewTargetVpnGatewaysService(config.clientCompute)
|
||||||
|
|
||||||
|
op, err := vpnGatewaysService.Delete(project, region, name).Do()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Reading VPN Gateway %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = resourceOperationWaitRegion(config, op, region, "Deleting VPN Gateway")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Waiting to Delete VPN Gateway %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
|
||||||
|
"google.golang.org/api/compute/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccComputeVpnGateway_basic(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckComputeVpnGatewayDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccComputeVpnGateway_basic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckComputeVpnGatewayExists(
|
||||||
|
"google_compute_vpn_gateway.foobar"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckComputeVpnGatewayDestroy(s *terraform.State) error {
|
||||||
|
config := testAccProvider.Meta().(*Config)
|
||||||
|
project := config.Project
|
||||||
|
|
||||||
|
vpnGatewaysService := compute.NewTargetVpnGatewaysService(config.clientCompute)
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "google_compute_network" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
region := rs.Primary.Attributes["region"]
|
||||||
|
name := rs.Primary.Attributes["name"]
|
||||||
|
|
||||||
|
_, err := vpnGatewaysService.Get(project, region, name).Do()
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return fmt.Errorf("Error, VPN Gateway %s in region %s still exists",
|
||||||
|
name, region)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckComputeVpnGatewayExists(n string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
config := testAccProvider.Meta().(*Config)
|
||||||
|
name := rs.Primary.Attributes["name"]
|
||||||
|
region := rs.Primary.Attributes["region"]
|
||||||
|
project := config.Project
|
||||||
|
|
||||||
|
vpnGatewaysService := compute.NewTargetVpnGatewaysService(config.clientCompute)
|
||||||
|
_, err := vpnGatewaysService.Get(project, region, name).Do()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Reading VPN Gateway %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccComputeVpnGateway_basic = `
|
||||||
|
resource "google_compute_network" "foobar" {
|
||||||
|
name = "tf-test-network"
|
||||||
|
ipv4_range = "10.0.0.0/16"
|
||||||
|
}
|
||||||
|
resource "google_compute_vpn_gateway" "foobar" {
|
||||||
|
name = "tf-test-vpn-gateway"
|
||||||
|
network = "${google_compute_network.foobar.self_link}"
|
||||||
|
region = "us-central1"
|
||||||
|
} `
|
|
@ -0,0 +1,178 @@
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
|
||||||
|
"google.golang.org/api/compute/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceComputeVpnTunnel() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
// Unfortunately, the VPNTunnelService does not support update
|
||||||
|
// operations. This is why everything is marked forcenew
|
||||||
|
Create: resourceComputeVpnTunnelCreate,
|
||||||
|
Read: resourceComputeVpnTunnelRead,
|
||||||
|
Delete: resourceComputeVpnTunnelDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"description": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"region": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"peer_ip": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"shared_secret": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"target_vpn_gateway": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"ike_version": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: 2,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"detailed_status": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"self_link": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceOperationWaitRegion(config *Config, op *compute.Operation, region, activity string) error {
|
||||||
|
w := &OperationWaiter{
|
||||||
|
Service: config.clientCompute,
|
||||||
|
Op: op,
|
||||||
|
Project: config.Project,
|
||||||
|
Type: OperationWaitRegion,
|
||||||
|
Region: region,
|
||||||
|
}
|
||||||
|
|
||||||
|
state := w.Conf()
|
||||||
|
state.Timeout = 2 * time.Minute
|
||||||
|
state.MinTimeout = 1 * time.Second
|
||||||
|
opRaw, err := state.WaitForState()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
op = opRaw.(*compute.Operation)
|
||||||
|
if op.Error != nil {
|
||||||
|
return OperationError(*op.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeVpnTunnelCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
region := getOptionalRegion(d, config)
|
||||||
|
peerIp := d.Get("peer_ip").(string)
|
||||||
|
sharedSecret := d.Get("shared_secret").(string)
|
||||||
|
targetVpnGateway := d.Get("target_vpn_gateway").(string)
|
||||||
|
ikeVersion := d.Get("ike_version").(int)
|
||||||
|
project := config.Project
|
||||||
|
|
||||||
|
if ikeVersion < 1 || ikeVersion > 2 {
|
||||||
|
return fmt.Errorf("Only IKE version 1 or 2 supported, not %d", ikeVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
vpnTunnelsService := compute.NewVpnTunnelsService(config.clientCompute)
|
||||||
|
|
||||||
|
vpnTunnel := &compute.VpnTunnel{
|
||||||
|
Name: name,
|
||||||
|
PeerIp: peerIp,
|
||||||
|
SharedSecret: sharedSecret,
|
||||||
|
TargetVpnGateway: targetVpnGateway,
|
||||||
|
IkeVersion: int64(ikeVersion),
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("description"); ok {
|
||||||
|
vpnTunnel.Description = v.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
op, err := vpnTunnelsService.Insert(project, region, vpnTunnel).Do()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Inserting VPN Tunnel %s : %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = resourceOperationWaitRegion(config, op, region, "Inserting VPN Tunnel")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Waiting to Insert VPN Tunnel %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceComputeVpnTunnelRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeVpnTunnelRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
region := d.Get("region").(string)
|
||||||
|
project := config.Project
|
||||||
|
|
||||||
|
vpnTunnelsService := compute.NewVpnTunnelsService(config.clientCompute)
|
||||||
|
|
||||||
|
vpnTunnel, err := vpnTunnelsService.Get(project, region, name).Do()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Reading VPN Tunnel %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("detailed_status", vpnTunnel.DetailedStatus)
|
||||||
|
d.Set("self_link", vpnTunnel.SelfLink)
|
||||||
|
|
||||||
|
d.SetId(name)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeVpnTunnelDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
region := d.Get("region").(string)
|
||||||
|
project := config.Project
|
||||||
|
|
||||||
|
vpnTunnelsService := compute.NewVpnTunnelsService(config.clientCompute)
|
||||||
|
|
||||||
|
op, err := vpnTunnelsService.Delete(project, region, name).Do()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Reading VPN Tunnel %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = resourceOperationWaitRegion(config, op, region, "Deleting VPN Tunnel")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Waiting to Delete VPN Tunnel %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
|
||||||
|
"google.golang.org/api/compute/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccComputeVpnTunnel_basic(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckComputeVpnTunnelDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccComputeVpnTunnel_basic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckComputeVpnTunnelExists(
|
||||||
|
"google_compute_vpn_tunnel.foobar"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckComputeVpnTunnelDestroy(s *terraform.State) error {
|
||||||
|
config := testAccProvider.Meta().(*Config)
|
||||||
|
project := config.Project
|
||||||
|
|
||||||
|
vpnTunnelsService := compute.NewVpnTunnelsService(config.clientCompute)
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "google_compute_network" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
region := rs.Primary.Attributes["region"]
|
||||||
|
name := rs.Primary.Attributes["name"]
|
||||||
|
|
||||||
|
_, err := vpnTunnelsService.Get(project, region, name).Do()
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return fmt.Errorf("Error, VPN Tunnel %s in region %s still exists",
|
||||||
|
name, region)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckComputeVpnTunnelExists(n string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
config := testAccProvider.Meta().(*Config)
|
||||||
|
name := rs.Primary.Attributes["name"]
|
||||||
|
region := rs.Primary.Attributes["region"]
|
||||||
|
project := config.Project
|
||||||
|
|
||||||
|
vpnTunnelsService := compute.NewVpnTunnelsService(config.clientCompute)
|
||||||
|
_, err := vpnTunnelsService.Get(project, region, name).Do()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Reading VPN Tunnel %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccComputeVpnTunnel_basic = `
|
||||||
|
resource "google_compute_network" "foobar" {
|
||||||
|
name = "tf-test-network"
|
||||||
|
ipv4_range = "10.0.0.0/16"
|
||||||
|
}
|
||||||
|
resource "google_compute_address" "foobar" {
|
||||||
|
name = "tf-test-static-ip"
|
||||||
|
region = "us-central1"
|
||||||
|
}
|
||||||
|
resource "google_compute_vpn_gateway" "foobar" {
|
||||||
|
name = "tf-test-vpn-gateway"
|
||||||
|
network = "${google_compute_network.foobar.self_link}"
|
||||||
|
region = "${google_compute_address.foobar.region}"
|
||||||
|
}
|
||||||
|
resource "google_compute_forwarding_rule" "foobar_esp" {
|
||||||
|
name = "tf-test-fr-esp"
|
||||||
|
region = "${google_compute_vpn_gateway.foobar.region}"
|
||||||
|
ip_protocol = "ESP"
|
||||||
|
ip_address = "${google_compute_address.foobar.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.foobar.self_link}"
|
||||||
|
}
|
||||||
|
resource "google_compute_forwarding_rule" "foobar_udp500" {
|
||||||
|
name = "tf-test-fr-udp500"
|
||||||
|
region = "${google_compute_forwarding_rule.foobar_esp.region}"
|
||||||
|
ip_protocol = "UDP"
|
||||||
|
port_range = "500"
|
||||||
|
ip_address = "${google_compute_address.foobar.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.foobar.self_link}"
|
||||||
|
}
|
||||||
|
resource "google_compute_forwarding_rule" "foobar_udp4500" {
|
||||||
|
name = "tf-test-fr-udp4500"
|
||||||
|
region = "${google_compute_forwarding_rule.foobar_udp500.region}"
|
||||||
|
ip_protocol = "UDP"
|
||||||
|
port_range = "4500"
|
||||||
|
ip_address = "${google_compute_address.foobar.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.foobar.self_link}"
|
||||||
|
}
|
||||||
|
resource "google_compute_vpn_tunnel" "foobar" {
|
||||||
|
name = "tf-test-vpn-tunnel"
|
||||||
|
region = "${google_compute_forwarding_rule.foobar_udp4500.region}"
|
||||||
|
target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}"
|
||||||
|
shared_secret = "unguessable"
|
||||||
|
peer_ip = "0.0.0.0"
|
||||||
|
}`
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Google Compute Engine VPN Example
|
||||||
|
|
||||||
|
This example joins two GCE networks via VPN. The firewall rules have been set up
|
||||||
|
so that you can create an instance in each network and have them communicate
|
||||||
|
using their internal IP addresses.
|
||||||
|
|
||||||
|
See this [example](https://cloud.google.com/compute/docs/vpn) for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
Run this example using
|
||||||
|
|
||||||
|
```
|
||||||
|
terraform apply \
|
||||||
|
-var="region1=us-central1" \
|
||||||
|
-var="region2=europe-west1" \
|
||||||
|
-var="project=my-project-id-123"
|
||||||
|
```
|
|
@ -0,0 +1,11 @@
|
||||||
|
variable "project" {
|
||||||
|
description = "Your project name"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "region1" {
|
||||||
|
description = "The desired region for the first network & VPN and project"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "region2" {
|
||||||
|
description = "The desired region for the second network & VPN"
|
||||||
|
}
|
|
@ -0,0 +1,172 @@
|
||||||
|
# An example of how to connect two GCE networks with a VPN
|
||||||
|
provider "google" {
|
||||||
|
account_file = "${file("~/gce/account.json")}"
|
||||||
|
project = "${var.project}"
|
||||||
|
region = "${var.region1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the two networks we want to join. They must have seperate, internal
|
||||||
|
# ranges.
|
||||||
|
resource "google_compute_network" "network1" {
|
||||||
|
name = "network1"
|
||||||
|
ipv4_range = "10.120.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_network" "network2" {
|
||||||
|
name = "network2"
|
||||||
|
ipv4_range = "10.121.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Attach a VPN gateway to each network.
|
||||||
|
resource "google_compute_vpn_gateway" "target_gateway1" {
|
||||||
|
name = "vpn1"
|
||||||
|
network = "${google_compute_network.network1.self_link}"
|
||||||
|
region = "${var.region1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_vpn_gateway" "target_gateway2" {
|
||||||
|
name = "vpn2"
|
||||||
|
network = "${google_compute_network.network2.self_link}"
|
||||||
|
region = "${var.region2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create an outward facing static IP for each VPN that will be used by the
|
||||||
|
# other VPN to connect.
|
||||||
|
resource "google_compute_address" "vpn_static_ip1" {
|
||||||
|
name = "vpn-static-ip1"
|
||||||
|
region = "${var.region1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_address" "vpn_static_ip2" {
|
||||||
|
name = "vpn-static-ip2"
|
||||||
|
region = "${var.region2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Forward IPSec traffic coming into our static IP to our VPN gateway.
|
||||||
|
resource "google_compute_forwarding_rule" "fr1_esp" {
|
||||||
|
name = "fr1-esp"
|
||||||
|
region = "${var.region1}"
|
||||||
|
ip_protocol = "ESP"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip1.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway1.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "fr2_esp" {
|
||||||
|
name = "fr2-esp"
|
||||||
|
region = "${var.region2}"
|
||||||
|
ip_protocol = "ESP"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip2.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway2.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# The following two sets of forwarding rules are used as a part of the IPSec
|
||||||
|
# protocol
|
||||||
|
resource "google_compute_forwarding_rule" "fr1_udp500" {
|
||||||
|
name = "fr1-udp500"
|
||||||
|
region = "${var.region1}"
|
||||||
|
ip_protocol = "UDP"
|
||||||
|
port_range = "500"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip1.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway1.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "fr2_udp500" {
|
||||||
|
name = "fr2-udp500"
|
||||||
|
region = "${var.region2}"
|
||||||
|
ip_protocol = "UDP"
|
||||||
|
port_range = "500"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip2.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway2.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "fr1_udp4500" {
|
||||||
|
name = "fr1-udp4500"
|
||||||
|
region = "${var.region1}"
|
||||||
|
ip_protocol = "UDP"
|
||||||
|
port_range = "4500"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip1.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway1.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "fr2_udp4500" {
|
||||||
|
name = "fr2-udp4500"
|
||||||
|
region = "${var.region2}"
|
||||||
|
ip_protocol = "UDP"
|
||||||
|
port_range = "4500"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip2.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway2.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Each tunnel is responsible for encrypting and decrypting traffic exiting
|
||||||
|
# and leaving it's associated gateway
|
||||||
|
resource "google_compute_vpn_tunnel" "tunnel1" {
|
||||||
|
name = "tunnel1"
|
||||||
|
region = "${var.region1}"
|
||||||
|
peer_ip = "${google_compute_address.vpn_static_ip2.address}"
|
||||||
|
shared_secret = "a secret message"
|
||||||
|
target_vpn_gateway = "${google_compute_vpn_gateway.target_gateway1.self_link}"
|
||||||
|
depends_on = ["google_compute_forwarding_rule.fr1_udp500",
|
||||||
|
"google_compute_forwarding_rule.fr1_udp4500",
|
||||||
|
"google_compute_forwarding_rule.fr1_esp"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_vpn_tunnel" "tunnel2" {
|
||||||
|
name = "tunnel2"
|
||||||
|
region = "${var.region2}"
|
||||||
|
peer_ip = "${google_compute_address.vpn_static_ip1.address}"
|
||||||
|
shared_secret = "a secret message"
|
||||||
|
target_vpn_gateway = "${google_compute_vpn_gateway.target_gateway2.self_link}"
|
||||||
|
depends_on = ["google_compute_forwarding_rule.fr2_udp500",
|
||||||
|
"google_compute_forwarding_rule.fr2_udp4500",
|
||||||
|
"google_compute_forwarding_rule.fr2_esp"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Each route tells the associated network to send all traffic in the dest_range
|
||||||
|
# through the VPN tunnel
|
||||||
|
resource "google_compute_route" "route1" {
|
||||||
|
name = "route1"
|
||||||
|
network = "${google_compute_network.network1.name}"
|
||||||
|
next_hop_vpn_tunnel = "${google_compute_vpn_tunnel.tunnel1.self_link}"
|
||||||
|
dest_range = "${google_compute_network.network2.ipv4_range}"
|
||||||
|
priority = 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_route" "route2" {
|
||||||
|
name = "route2"
|
||||||
|
network = "${google_compute_network.network2.name}"
|
||||||
|
next_hop_vpn_tunnel = "${google_compute_vpn_tunnel.tunnel2.self_link}"
|
||||||
|
dest_range = "${google_compute_network.network1.ipv4_range}"
|
||||||
|
priority = 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
# We want to allow the two networks to communicate, so we need to unblock
|
||||||
|
# them in the firewall
|
||||||
|
resource "google_compute_firewall" "network1-allow-network1" {
|
||||||
|
name = "network1-allow-network1"
|
||||||
|
network = "${google_compute_network.network1.name}"
|
||||||
|
source_ranges = ["${google_compute_network.network1.ipv4_range}"]
|
||||||
|
allow {
|
||||||
|
protocol = "tcp"
|
||||||
|
}
|
||||||
|
allow {
|
||||||
|
protocol = "udp"
|
||||||
|
}
|
||||||
|
allow {
|
||||||
|
protocol = "icmp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_firewall" "network1-allow-network2" {
|
||||||
|
name = "network1-allow-network2"
|
||||||
|
network = "${google_compute_network.network1.name}"
|
||||||
|
source_ranges = ["${google_compute_network.network2.ipv4_range}"]
|
||||||
|
allow {
|
||||||
|
protocol = "tcp"
|
||||||
|
}
|
||||||
|
allow {
|
||||||
|
protocol = "udp"
|
||||||
|
}
|
||||||
|
allow {
|
||||||
|
protocol = "icmp"
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,8 @@ The following arguments are supported:
|
||||||
|
|
||||||
* `name` - (Required) A unique name for the resource, required by GCE.
|
* `name` - (Required) A unique name for the resource, required by GCE.
|
||||||
Changing this forces a new resource to be created.
|
Changing this forces a new resource to be created.
|
||||||
|
* `region` - (Optional) The Region in which the created address should reside.
|
||||||
|
If it is not provided, the provider region is used.
|
||||||
|
|
||||||
## Attributes Reference
|
## Attributes Reference
|
||||||
|
|
||||||
|
@ -35,3 +37,4 @@ The following attributes are exported:
|
||||||
* `name` - The name of the resource.
|
* `name` - The name of the resource.
|
||||||
* `address` - The IP address that was allocated.
|
* `address` - The IP address that was allocated.
|
||||||
* `self_link` - The URI of the created resource.
|
* `self_link` - The URI of the created resource.
|
||||||
|
* `region` - The Region in which the created address does reside.
|
||||||
|
|
|
@ -54,6 +54,9 @@ The following arguments are supported:
|
||||||
* `next_hop_network` - (Optional) The name of the network to route to if this
|
* `next_hop_network` - (Optional) The name of the network to route to if this
|
||||||
route is matched.
|
route is matched.
|
||||||
|
|
||||||
|
* `next_hop_vpn_gateway` - (Optional) The name of the VPN to route to if this
|
||||||
|
route is matched.
|
||||||
|
|
||||||
* `priority` - (Required) The priority of this route, used to break ties.
|
* `priority` - (Required) The priority of this route, used to break ties.
|
||||||
|
|
||||||
* `tags` - (Optional) The tags that this route applies to.
|
* `tags` - (Optional) The tags that this route applies to.
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
---
|
||||||
|
layout: "google"
|
||||||
|
page_title: "Google: google_compute_vpn_gateway"
|
||||||
|
sidebar_current: "docs-google-resource-vpn-gateway"
|
||||||
|
description: |-
|
||||||
|
Manages a VPN Gateway in the GCE network
|
||||||
|
---
|
||||||
|
|
||||||
|
# google\_compute\_vpn\_gateway
|
||||||
|
|
||||||
|
Manages a VPN Gateway in the GCE network. For more info, read the
|
||||||
|
[documentation](https://cloud.google.com/compute/docs/vpn).
|
||||||
|
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "google_compute_network" "network1" {
|
||||||
|
name = "network1"
|
||||||
|
ipv4_range = "10.120.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_vpn_gateway" "target_gateway" {
|
||||||
|
name = "vpn1"
|
||||||
|
network = "${google_compute_network.network1.self_link}"
|
||||||
|
region = "${var.region}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_address" "vpn_static_ip" {
|
||||||
|
name = "vpn-static-ip"
|
||||||
|
region = "${var.region}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "fr_esp" {
|
||||||
|
name = "fr-esp"
|
||||||
|
region = "${var.region}"
|
||||||
|
ip_protocol = "ESP"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "fr_udp500" {
|
||||||
|
name = "fr-udp500"
|
||||||
|
region = "${var.region}"
|
||||||
|
ip_protocol = "UDP"
|
||||||
|
port_range = "500"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "fr_udp4500" {
|
||||||
|
name = "fr-udp4500"
|
||||||
|
region = "${var.region}"
|
||||||
|
ip_protocol = "UDP"
|
||||||
|
port_range = "4500"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_vpn_tunnel" "tunnel1" {
|
||||||
|
name = "tunnel1"
|
||||||
|
region = "${var.region}"
|
||||||
|
peer_ip = "15.0.0.120"
|
||||||
|
shared_secret = "a secret message"
|
||||||
|
target_vpn_gateway = "${google_compute_vpn_gateway.target_gateway.self_link}"
|
||||||
|
depends_on = ["google_compute_forwarding_rule.fr_esp",
|
||||||
|
"google_compute_forwarding_rule.fr_udp500",
|
||||||
|
"google_compute_forwarding_rule.fr_udp4500"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_route" "route1" {
|
||||||
|
name = "route1"
|
||||||
|
network = "${google_compute_network.network1.name}"
|
||||||
|
next_hop_vpn_tunnel = "${google_compute_vpn_tunnel.tunnel1.self_link}"
|
||||||
|
dest_range = "15.0.0.0/24"
|
||||||
|
priority = 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) A unique name for the resource, required by GCE.
|
||||||
|
Changing this forces a new resource to be created.
|
||||||
|
|
||||||
|
* `description` - (Optional) A description of the resource.
|
||||||
|
Changing this forces a new resource to be created.
|
||||||
|
|
||||||
|
* `network` - (Required) A link to the network this VPN gateway is accepting
|
||||||
|
traffic for.
|
||||||
|
Changing this forces a new resource to be created.
|
||||||
|
|
||||||
|
* `region` - (Optional) The region this gateway should sit in. If not specified,
|
||||||
|
the project region will be used. Changing this forces a new resource to be
|
||||||
|
created.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `self_link` - A GCE server assigned link to this resource.
|
|
@ -0,0 +1,112 @@
|
||||||
|
---
|
||||||
|
layout: "google"
|
||||||
|
page_title: "Google: google_compute_vpn_tunnel"
|
||||||
|
sidebar_current: "docs-google-resource-vpn-tunnel"
|
||||||
|
description: |-
|
||||||
|
Manages a VPN Tunnel to the GCE network
|
||||||
|
---
|
||||||
|
|
||||||
|
# google\_compute\_vpn\_tunnel
|
||||||
|
|
||||||
|
Manages a VPN Tunnel to the GCE network. For more info, read the
|
||||||
|
[documentation](https://cloud.google.com/compute/docs/vpn).
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "google_compute_network" "network1" {
|
||||||
|
name = "network1"
|
||||||
|
ipv4_range = "10.120.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_vpn_gateway" "target_gateway" {
|
||||||
|
name = "vpn1"
|
||||||
|
network = "${google_compute_network.network1.self_link}"
|
||||||
|
region = "${var.region}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_address" "vpn_static_ip" {
|
||||||
|
name = "vpn-static-ip"
|
||||||
|
region = "${var.region}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "fr_esp" {
|
||||||
|
name = "fr-esp"
|
||||||
|
region = "${var.region}"
|
||||||
|
ip_protocol = "ESP"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "fr_udp500" {
|
||||||
|
name = "fr-udp500"
|
||||||
|
region = "${var.region}"
|
||||||
|
ip_protocol = "UDP"
|
||||||
|
port_range = "500"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "fr_udp4500" {
|
||||||
|
name = "fr-udp4500"
|
||||||
|
region = "${var.region}"
|
||||||
|
ip_protocol = "UDP"
|
||||||
|
port_range = "4500"
|
||||||
|
ip_address = "${google_compute_address.vpn_static_ip.address}"
|
||||||
|
target = "${google_compute_vpn_gateway.target_gateway.self_link}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_vpn_tunnel" "tunnel1" {
|
||||||
|
name = "tunnel1"
|
||||||
|
region = "${var.region}"
|
||||||
|
peer_ip = "15.0.0.120"
|
||||||
|
shared_secret = "a secret message"
|
||||||
|
target_vpn_gateway = "${google_compute_vpn_gateway.target_gateway.self_link}"
|
||||||
|
depends_on = ["google_compute_forwarding_rule.fr_esp",
|
||||||
|
"google_compute_forwarding_rule.fr_udp500",
|
||||||
|
"google_compute_forwarding_rule.fr_udp4500"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_route" "route1" {
|
||||||
|
name = "route1"
|
||||||
|
network = "${google_compute_network.network1.name}"
|
||||||
|
next_hop_vpn_tunnel = "${google_compute_vpn_tunnel.tunnel1.self_link}"
|
||||||
|
dest_range = "15.0.0.0/24"
|
||||||
|
priority = 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) A unique name for the resource, required by GCE.
|
||||||
|
Changing this forces a new resource to be created.
|
||||||
|
|
||||||
|
* `description` - (Optional) A description of the resource.
|
||||||
|
Changing this forces a new resource to be created.
|
||||||
|
|
||||||
|
* `peer_ip` - (Required) The VPN gateway sitting outside of GCE.
|
||||||
|
Changing this forces a new resource to be created.
|
||||||
|
|
||||||
|
* `region` - (Optional) The region this tunnel should sit in. If not specified,
|
||||||
|
the project region will be used. Changing this forces a new resource to be
|
||||||
|
created.
|
||||||
|
|
||||||
|
* `shared_secret` - (Required) A passphrase shared between the two VPN gateways.
|
||||||
|
Changing this forces a new resource to be created.
|
||||||
|
|
||||||
|
* `target_vpn_gateway` - (Required) A link to the VPN gateway sitting inside GCE.
|
||||||
|
Changing this forces a new resource to be created.
|
||||||
|
|
||||||
|
* `ike_version` - (Optional) Either version 1 or 2. Default is 2.
|
||||||
|
Changing this forces a new resource to be created.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `self_link` - A GCE server assigned link to this resource.
|
||||||
|
|
||||||
|
* `detailed_status` - Information about the status of the VPN tunnel.
|
|
@ -69,6 +69,14 @@
|
||||||
<a href="/docs/providers/google/r/compute_target_pool.html">google_compute_target_pool</a>
|
<a href="/docs/providers/google/r/compute_target_pool.html">google_compute_target_pool</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-google-resource-vpn-gateway") %>>
|
||||||
|
<a href="/docs/providers/google/r/compute_vpn_gateway.html">google_compute_vpn_gateway</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-google-resource-vpn-tunnel") %>>
|
||||||
|
<a href="/docs/providers/google/r/compute_vpn_tunnel.html">google_compute_vpn_tunnel</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-google-resource-container-cluster") %>>
|
<li<%= sidebar_current("docs-google-resource-container-cluster") %>>
|
||||||
<a href="/docs/providers/google/r/container_cluster.html">google_container_cluster</a>
|
<a href="/docs/providers/google/r/container_cluster.html">google_container_cluster</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue