Change hub and spoke VPN example to use VPN HA (#643)
* missing outputs and diagram * fix names and outputs, update diagram * fix vm name in example * tfdoc files on * fix test * address comments
This commit is contained in:
parent
c2323fed41
commit
4114f9995f
|
@ -1,8 +1,15 @@
|
||||||
# Hub and Spoke via VPN
|
# Hub and Spoke via VPN
|
||||||
|
|
||||||
This example creates a simple **Hub and Spoke VPN** setup, where the VPC network connects satellite locations (spokes) through a single intermediary location (hub) via [IPsec VPN](https://cloud.google.com/vpn/docs/concepts/overview), optionally providing full-mesh networking via [custom route advertisements](https://cloud.google.com/router/docs/how-to/advertising-overview).
|
This example creates a simple **Hub and Spoke VPN** setup, where the VPC network connects satellite locations (spokes) through a single intermediary location (hub) via [IPsec HA VPN](https://cloud.google.com/network-connectivity/docs/vpn/concepts/overview#ha-vpn).
|
||||||
|
|
||||||
The example has been purposefully kept simple to show how to use and wire the VPC and VPN modules together, and so that it can be used as a basis for more complex scenarios. This is the high level diagram:
|
A few additional features are also shown:
|
||||||
|
|
||||||
|
- [custom BGP advertisements](https://cloud.google.com/router/docs/how-to/advertising-overview) to implement transitivity between spokes
|
||||||
|
- [VPC Global Routing](https://cloud.google.com/network-connectivity/docs/router/how-to/configuring-routing-mode) to leverage a regional set of VPN gateways in different regions as next hops (used here for illustrative/study purpose, not usually done in real life)
|
||||||
|
|
||||||
|
The example has been purposefully kept simple to show how to use and wire the VPC and VPN-HA modules together, and so that it can be used as a basis for experimentation. For a more complex scenario that better reflects real-life usage, including [Shared VPC](https://cloud.google.com/vpc/docs/shared-vpc) and [DNS cross-project binding](https://cloud.google.com/dns/docs/zones/cross-project-binding) please refer to the [FAST network stage](../../../fast/stages/02-networking-vpn/).
|
||||||
|
|
||||||
|
This is the high level diagram of this example:
|
||||||
|
|
||||||
![High-level diagram](diagram.png "High-level diagram")
|
![High-level diagram](diagram.png "High-level diagram")
|
||||||
|
|
||||||
|
@ -12,44 +19,87 @@ This sample creates several distinct groups of resources:
|
||||||
|
|
||||||
- one VPC for each hub and each spoke
|
- one VPC for each hub and each spoke
|
||||||
- one set of firewall rules for each VPC
|
- one set of firewall rules for each VPC
|
||||||
- one VPN gateway, one tunnel and one Cloud Router for each spoke
|
- one HA VPN gateway with two tunnels and one Cloud Router for each spoke
|
||||||
- two VPN gateways, two tunnels and two Cloud Routers for the hub (one for each spoke)
|
- two HA VPN gateways with two tunnels and a shared Cloud Routers for the hub
|
||||||
- one DNS private zone in the hub
|
- one DNS private zone in the hub
|
||||||
- one DNS peering zone in each spoke
|
- one DNS peering zone and one DNS private zone in each spoke
|
||||||
- one Cloud NAT configuration for each spoke
|
- one test instance for the hub each spoke
|
||||||
- one test instance for each spoke
|
|
||||||
|
|
||||||
## Operational considerations
|
## Prerequisites
|
||||||
|
|
||||||
A single pre-existing project is used in this example to keep variables and complexity to a minimum, in a real world scenarios each spoke would probably use a separate project. The provided project needs a valid billing account and the Compute and DNS APIs enabled. You can easily create such a project with the [project module](../../../modules/project) or with the following commands:
|
A single pre-existing project is used in this example to keep variables and complexity to a minimum, in a real world scenarios each spoke would probably use a separate project.
|
||||||
|
|
||||||
``` shell
|
The provided project needs a valid billing account, the Compute and DNS APIs are enabled by the example.
|
||||||
MY_PROJECT_ID="<desired project id>"
|
|
||||||
gcloud projects create $MY_PROJECT_ID
|
You can easily create such a project by commenting turning on project creation in the project module contained in `main.tf`, as shown in this snippet:
|
||||||
gcloud alpha billing projects link --billing-account=XXXXXX-XXXXXX-XXXXXX $MY_PROJECT_ID
|
|
||||||
gcloud services enable --project=$MY_PROJECT_ID {compute,dns}.googleapis.com
|
```hcl
|
||||||
|
module "project" {
|
||||||
|
source = "../../..//modules/project"
|
||||||
|
name = var.project_id
|
||||||
|
# comment or remove this line to enable project creation
|
||||||
|
# project_create = false
|
||||||
|
# add the following line with your billing account id value
|
||||||
|
billing_account = "12345-ABCD-12345"
|
||||||
|
services = [
|
||||||
|
"compute.googleapis.com",
|
||||||
|
"dns.googleapis.com"
|
||||||
|
]
|
||||||
|
service_config = {
|
||||||
|
disable_on_destroy = false
|
||||||
|
disable_dependent_services = false
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The example does not account for HA, but the VPN gateways can be easily upgraded to use HA VPN via the [net-vpn-ha module](../../../modules/net-vpn-ha).
|
## Testing
|
||||||
|
|
||||||
If a single router and VPN gateway are used in the hub to manage all tunnels, particular care must be taken in announcing ranges from hub to spokes, as Cloud Router does not explicitly support transitivity and overlapping routes received from both sides create unintended side effects. The simple workaround is to announce a single aggregated route from hub to spokes so that it does not overlap with any of the ranges advertised by each spoke to the hub.
|
Once the example is up, you can quickly test features by logging in to one of the test VMs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gcloud compute ssh hs-ha-lnd-test-r1
|
||||||
|
# test DNS resolution of the landing zone
|
||||||
|
ping test-r1.example.com
|
||||||
|
# test DNS resolution of the prod zone, and prod reachability
|
||||||
|
ping test-r1.prod.example.com
|
||||||
|
# test DNS resolution of the dev zone, and dev reachability via global routing
|
||||||
|
ping test-r2.dev.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- TFDOC OPTS files:1 -->
|
||||||
<!-- BEGIN TFDOC -->
|
<!-- BEGIN TFDOC -->
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
| name | description | modules |
|
||||||
|
|---|---|---|
|
||||||
|
| [main.tf](./main.tf) | Module-level locals and resources. | <code>compute-vm</code> · <code>project</code> |
|
||||||
|
| [net-dev.tf](./net-dev.tf) | Development spoke VPC. | <code>dns</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> |
|
||||||
|
| [net-landing.tf](./net-landing.tf) | Landing hub VPC. | <code>dns</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> |
|
||||||
|
| [net-prod.tf](./net-prod.tf) | Production spoke VPC. | <code>dns</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> |
|
||||||
|
| [outputs.tf](./outputs.tf) | Module outputs. | |
|
||||||
|
| [variables.tf](./variables.tf) | Module variables. | |
|
||||||
|
| [versions.tf](./versions.tf) | Version pins. | |
|
||||||
|
| [vpn-dev-r1.tf](./vpn-dev-r1.tf) | Landing to Development VPN for region 1. | <code>net-vpn-ha</code> |
|
||||||
|
| [vpn-prod-r1.tf](./vpn-prod-r1.tf) | Landing to Production VPN for region 1. | <code>net-vpn-ha</code> |
|
||||||
|
|
||||||
## Variables
|
## Variables
|
||||||
|
|
||||||
| name | description | type | required | default |
|
| name | description | type | required | default |
|
||||||
|---|---|:---:|:---:|:---:|
|
|---|---|:---:|:---:|:---:|
|
||||||
| [project_id](variables.tf#L56) | Project id for all resources. | <code>string</code> | ✓ | |
|
| [project_id](variables.tf#L49) | Project id for all resources. | <code>string</code> | ✓ | |
|
||||||
| [bgp_asn](variables.tf#L15) | BGP ASNs. | <code>map(number)</code> | | <code title="{ hub = 64513 spoke-1 = 64514 spoke-2 = 64515 }">{…}</code> |
|
| [ip_ranges](variables.tf#L15) | Subnet IP CIDR ranges. | <code>map(string)</code> | | <code title="{ land-0-r1 = "10.0.0.0/24" land-0-r2 = "10.0.8.0/24" dev-0-r1 = "10.0.16.0/24" dev-0-r2 = "10.0.24.0/24" prod-0-r1 = "10.0.32.0/24" prod-0-r2 = "10.0.40.0/24" }">{…}</code> |
|
||||||
| [bgp_custom_advertisements](variables.tf#L25) | BGP custom advertisement IP CIDR ranges. | <code>map(string)</code> | | <code title="{ hub-to-spoke-1 = "10.0.32.0/20" hub-to-spoke-2 = "10.0.16.0/20" }">{…}</code> |
|
| [ip_secondary_ranges](variables.tf#L28) | Subnet secondary ranges. | <code>map(map(string))</code> | | <code>{}</code> |
|
||||||
| [bgp_interface_ranges](variables.tf#L34) | BGP interface IP CIDR ranges. | <code>map(string)</code> | | <code title="{ spoke-1 = "169.254.1.0/30" spoke-2 = "169.254.1.4/30" }">{…}</code> |
|
| [prefix](variables.tf#L34) | Prefix used in resource names. | <code>string</code> | | <code>null</code> |
|
||||||
| [ip_ranges](variables.tf#L43) | IP CIDR ranges. | <code>map(string)</code> | | <code title="{ hub-a = "10.0.0.0/24" hub-b = "10.0.8.0/24" spoke-1-a = "10.0.16.0/24" spoke-1-b = "10.0.24.0/24" spoke-2-a = "10.0.32.0/24" spoke-2-b = "10.0.40.0/24" }">{…}</code> |
|
| [project_create_config](variables.tf#L40) | Populate with billing account id to trigger project creation. | <code title="object({ billing_account_id = string parent_id = string })">object({…})</code> | | <code>null</code> |
|
||||||
| [regions](variables.tf#L61) | VPC regions. | <code>map(string)</code> | | <code title="{ a = "europe-west1" b = "europe-west2" }">{…}</code> |
|
| [regions](variables.tf#L54) | VPC regions. | <code>map(string)</code> | | <code title="{ r1 = "europe-west1" r2 = "europe-west4" }">{…}</code> |
|
||||||
|
| [vpn_configs](variables.tf#L63) | VPN configurations. | <code title="map(object({ asn = number custom_ranges = map(string) }))">map(object({…}))</code> | | <code title="{ land-r1 = { asn = 64513 custom_ranges = { "10.0.0.0/8" = "internal default" } } dev-r1 = { asn = 64514 custom_ranges = null } prod-r1 = { asn = 64515 custom_ranges = null } }">{…}</code> |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
| name | description | sensitive |
|
| name | description | sensitive |
|
||||||
|---|---|:---:|
|
|---|---|:---:|
|
||||||
| [vms](outputs.tf#L15) | GCE VMs. | |
|
| [subnets](outputs.tf#L15) | Subnet details. | |
|
||||||
|
| [vms](outputs.tf#L39) | GCE VMs. | |
|
||||||
|
|
||||||
<!-- END TFDOC -->
|
<!-- END TFDOC -->
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 195 KiB After Width: | Height: | Size: 90 KiB |
|
@ -13,297 +13,71 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
vm-startup-script = join("\n", [
|
prefix = var.prefix == null ? "" : "${var.prefix}-"
|
||||||
"#! /bin/bash",
|
|
||||||
"apt-get update && apt-get install -y dnsutils"
|
|
||||||
])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################################
|
# enable services in the project used
|
||||||
# Hub networking #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
module "vpc-hub" {
|
module "project" {
|
||||||
source = "../../../modules/net-vpc"
|
source = "../../..//modules/project"
|
||||||
project_id = var.project_id
|
name = var.project_id
|
||||||
name = "hub"
|
parent = try(var.project_create_config.parent, null)
|
||||||
subnets = [
|
billing_account = try(var.project_create_config.billing_account_id, null)
|
||||||
{
|
project_create = try(var.project_create_config.billing_account_id, null) != null
|
||||||
ip_cidr_range = var.ip_ranges.hub-a
|
services = [
|
||||||
name = "hub-a"
|
"compute.googleapis.com",
|
||||||
region = var.regions.a
|
"dns.googleapis.com"
|
||||||
secondary_ip_range = {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ip_cidr_range = var.ip_ranges.hub-b
|
|
||||||
name = "hub-b"
|
|
||||||
region = var.regions.b
|
|
||||||
secondary_ip_range = {}
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
service_config = {
|
||||||
|
disable_on_destroy = false
|
||||||
module "vpc-hub-firewall" {
|
disable_dependent_services = false
|
||||||
source = "../../../modules/net-vpc-firewall"
|
|
||||||
project_id = var.project_id
|
|
||||||
network = module.vpc-hub.name
|
|
||||||
admin_ranges = values(var.ip_ranges)
|
|
||||||
}
|
|
||||||
|
|
||||||
module "vpn-hub-a" {
|
|
||||||
source = "../../../modules/net-vpn-dynamic"
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.regions.a
|
|
||||||
network = module.vpc-hub.name
|
|
||||||
name = "hub-a"
|
|
||||||
router_asn = var.bgp_asn.hub
|
|
||||||
tunnels = {
|
|
||||||
spoke-1 = {
|
|
||||||
bgp_peer = {
|
|
||||||
address = cidrhost(var.bgp_interface_ranges.spoke-1, 2)
|
|
||||||
asn = var.bgp_asn.spoke-1
|
|
||||||
}
|
|
||||||
bgp_peer_options = {
|
|
||||||
advertise_groups = ["ALL_SUBNETS"]
|
|
||||||
advertise_ip_ranges = {
|
|
||||||
(var.bgp_custom_advertisements.hub-to-spoke-1) = "spoke-2"
|
|
||||||
}
|
|
||||||
advertise_mode = "CUSTOM"
|
|
||||||
route_priority = 1000
|
|
||||||
}
|
|
||||||
bgp_session_range = "${cidrhost(var.bgp_interface_ranges.spoke-1, 1)}/30"
|
|
||||||
ike_version = 2
|
|
||||||
peer_ip = module.vpn-spoke-1.address
|
|
||||||
router = null
|
|
||||||
shared_secret = ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module "vpn-hub-b" {
|
# test VM in landing region 1
|
||||||
source = "../../../modules/net-vpn-dynamic"
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.regions.b
|
|
||||||
network = module.vpc-hub.name
|
|
||||||
name = "hub-b"
|
|
||||||
router_asn = var.bgp_asn.hub
|
|
||||||
tunnels = {
|
|
||||||
spoke-2 = {
|
|
||||||
bgp_peer = {
|
|
||||||
address = cidrhost(var.bgp_interface_ranges.spoke-2, 2)
|
|
||||||
asn = var.bgp_asn.spoke-2
|
|
||||||
}
|
|
||||||
bgp_peer_options = {
|
|
||||||
advertise_groups = ["ALL_SUBNETS"]
|
|
||||||
advertise_ip_ranges = {
|
|
||||||
(var.bgp_custom_advertisements.hub-to-spoke-2) = "spoke-1"
|
|
||||||
}
|
|
||||||
advertise_mode = "CUSTOM"
|
|
||||||
route_priority = 1000
|
|
||||||
}
|
|
||||||
bgp_session_range = "${cidrhost(var.bgp_interface_ranges.spoke-2, 1)}/30"
|
|
||||||
ike_version = 2
|
|
||||||
peer_ip = module.vpn-spoke-2.address
|
|
||||||
router = null
|
|
||||||
shared_secret = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
module "landing-r1-vm" {
|
||||||
# Spoke 1 networking #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
module "vpc-spoke-1" {
|
|
||||||
source = "../../../modules/net-vpc"
|
|
||||||
project_id = var.project_id
|
|
||||||
name = "spoke-1"
|
|
||||||
subnets = [
|
|
||||||
{
|
|
||||||
ip_cidr_range = var.ip_ranges.spoke-1-a
|
|
||||||
name = "spoke-1-a"
|
|
||||||
region = var.regions.a
|
|
||||||
secondary_ip_range = {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ip_cidr_range = var.ip_ranges.spoke-1-b
|
|
||||||
name = "spoke-1-b"
|
|
||||||
region = var.regions.b
|
|
||||||
secondary_ip_range = {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
module "vpc-spoke-1-firewall" {
|
|
||||||
source = "../../../modules/net-vpc-firewall"
|
|
||||||
project_id = var.project_id
|
|
||||||
network = module.vpc-spoke-1.name
|
|
||||||
admin_ranges = values(var.ip_ranges)
|
|
||||||
}
|
|
||||||
|
|
||||||
module "vpn-spoke-1" {
|
|
||||||
source = "../../../modules/net-vpn-dynamic"
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.regions.a
|
|
||||||
network = module.vpc-spoke-1.name
|
|
||||||
name = "spoke-1"
|
|
||||||
router_asn = var.bgp_asn.spoke-1
|
|
||||||
tunnels = {
|
|
||||||
hub = {
|
|
||||||
bgp_peer = {
|
|
||||||
address = cidrhost(var.bgp_interface_ranges.spoke-1, 1)
|
|
||||||
asn = var.bgp_asn.hub
|
|
||||||
}
|
|
||||||
bgp_peer_options = null
|
|
||||||
bgp_session_range = "${cidrhost(var.bgp_interface_ranges.spoke-1, 2)}/30"
|
|
||||||
ike_version = 2
|
|
||||||
peer_ip = module.vpn-hub-a.address
|
|
||||||
router = null
|
|
||||||
shared_secret = module.vpn-hub-a.random_secret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module "nat-spoke-1" {
|
|
||||||
source = "../../../modules/net-cloudnat"
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.regions.a
|
|
||||||
name = "spoke-1"
|
|
||||||
router_create = false
|
|
||||||
router_name = module.vpn-spoke-1.router_name
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Spoke 2 networking #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
module "vpc-spoke-2" {
|
|
||||||
source = "../../../modules/net-vpc"
|
|
||||||
project_id = var.project_id
|
|
||||||
name = "spoke-2"
|
|
||||||
subnets = [
|
|
||||||
{
|
|
||||||
ip_cidr_range = var.ip_ranges.spoke-2-a
|
|
||||||
name = "spoke-2-a"
|
|
||||||
region = var.regions.a
|
|
||||||
secondary_ip_range = {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ip_cidr_range = var.ip_ranges.spoke-2-b
|
|
||||||
name = "spoke-2-b"
|
|
||||||
region = var.regions.b
|
|
||||||
secondary_ip_range = {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
module "vpc-spoke-2-firewall" {
|
|
||||||
source = "../../../modules/net-vpc-firewall"
|
|
||||||
project_id = var.project_id
|
|
||||||
network = module.vpc-spoke-2.name
|
|
||||||
admin_ranges = values(var.ip_ranges)
|
|
||||||
}
|
|
||||||
|
|
||||||
module "vpn-spoke-2" {
|
|
||||||
source = "../../../modules/net-vpn-dynamic"
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.regions.a
|
|
||||||
network = module.vpc-spoke-2.name
|
|
||||||
name = "spoke-2"
|
|
||||||
router_asn = var.bgp_asn.spoke-2
|
|
||||||
tunnels = {
|
|
||||||
hub = {
|
|
||||||
bgp_peer = {
|
|
||||||
address = cidrhost(var.bgp_interface_ranges.spoke-2, 1)
|
|
||||||
asn = var.bgp_asn.hub
|
|
||||||
}
|
|
||||||
bgp_peer_options = null
|
|
||||||
bgp_session_range = "${cidrhost(var.bgp_interface_ranges.spoke-2, 2)}/30"
|
|
||||||
ike_version = 2
|
|
||||||
peer_ip = module.vpn-hub-b.address
|
|
||||||
router = null
|
|
||||||
shared_secret = module.vpn-hub-b.random_secret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module "nat-spoke-2" {
|
|
||||||
source = "../../../modules/net-cloudnat"
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.regions.a
|
|
||||||
name = "spoke-2"
|
|
||||||
router_create = false
|
|
||||||
router_name = module.vpn-spoke-2.router_name
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Test VMs #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
module "vm-spoke-1" {
|
|
||||||
source = "../../../modules/compute-vm"
|
source = "../../../modules/compute-vm"
|
||||||
project_id = var.project_id
|
project_id = var.project_id
|
||||||
zone = "${var.regions.b}-b"
|
name = "${local.prefix}lnd-test-r1"
|
||||||
name = "spoke-1-test"
|
zone = "${var.regions.r1}-b"
|
||||||
network_interfaces = [{
|
network_interfaces = [{
|
||||||
network = module.vpc-spoke-1.self_link
|
network = module.landing-vpc.self_link
|
||||||
subnetwork = module.vpc-spoke-1.subnet_self_links["${var.regions.b}/spoke-1-b"]
|
subnetwork = module.landing-vpc.subnet_self_links["${var.regions.r1}/${local.prefix}lnd-0"]
|
||||||
nat = false
|
nat = false
|
||||||
addresses = null
|
addresses = null
|
||||||
}]
|
}]
|
||||||
tags = ["ssh"]
|
tags = ["ssh"]
|
||||||
metadata = { startup-script = local.vm-startup-script }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module "vm-spoke-2" {
|
# test VM in prod region 1
|
||||||
|
|
||||||
|
module "prod-r1-vm" {
|
||||||
source = "../../../modules/compute-vm"
|
source = "../../../modules/compute-vm"
|
||||||
project_id = var.project_id
|
project_id = var.project_id
|
||||||
zone = "${var.regions.b}-b"
|
name = "${local.prefix}prd-test-r1"
|
||||||
name = "spoke-2-test"
|
zone = "${var.regions.r1}-b"
|
||||||
network_interfaces = [{
|
network_interfaces = [{
|
||||||
network = module.vpc-spoke-2.self_link
|
network = module.prod-vpc.self_link
|
||||||
subnetwork = module.vpc-spoke-2.subnet_self_links["${var.regions.b}/spoke-2-b"]
|
subnetwork = module.prod-vpc.subnet_self_links["${var.regions.r1}/${local.prefix}prd-0"]
|
||||||
nat = false
|
nat = false
|
||||||
addresses = null
|
addresses = null
|
||||||
}]
|
}]
|
||||||
tags = ["ssh"]
|
tags = ["ssh"]
|
||||||
metadata = { startup-script = local.vm-startup-script }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################################
|
# test VM in dev region 1
|
||||||
# DNS zones #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
module "dns-host" {
|
module "dev-r2-vm" {
|
||||||
source = "../../../modules/dns"
|
source = "../../../modules/compute-vm"
|
||||||
project_id = var.project_id
|
project_id = var.project_id
|
||||||
type = "private"
|
name = "${local.prefix}dev-test-r2"
|
||||||
name = "example"
|
zone = "${var.regions.r2}-b"
|
||||||
domain = "example.com."
|
network_interfaces = [{
|
||||||
client_networks = [module.vpc-hub.self_link]
|
network = module.dev-vpc.self_link
|
||||||
recordsets = {
|
subnetwork = module.dev-vpc.subnet_self_links["${var.regions.r2}/${local.prefix}dev-0"]
|
||||||
"A localhost" = { ttl = 300, records = ["127.0.0.1"] }
|
nat = false
|
||||||
"A spoke-1-test" = { ttl = 300, records = [module.vm-spoke-1.internal_ip] }
|
addresses = null
|
||||||
"A spoke-2-test" = { ttl = 300, records = [module.vm-spoke-2.internal_ip] }
|
}]
|
||||||
}
|
tags = ["ssh"]
|
||||||
}
|
|
||||||
|
|
||||||
module "dns-spoke-1" {
|
|
||||||
source = "../../../modules/dns"
|
|
||||||
project_id = var.project_id
|
|
||||||
type = "peering"
|
|
||||||
name = "spoke-1"
|
|
||||||
domain = "example.com."
|
|
||||||
client_networks = [module.vpc-spoke-1.self_link]
|
|
||||||
peer_network = module.vpc-hub.self_link
|
|
||||||
}
|
|
||||||
|
|
||||||
module "dns-spoke-2" {
|
|
||||||
source = "../../../modules/dns"
|
|
||||||
project_id = var.project_id
|
|
||||||
type = "peering"
|
|
||||||
name = "spoke-2"
|
|
||||||
domain = "example.com."
|
|
||||||
client_networks = [module.vpc-spoke-2.self_link]
|
|
||||||
peer_network = module.vpc-hub.self_link
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
# Copyright 2022 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# tfdoc:file:description Development spoke VPC.
|
||||||
|
|
||||||
|
module "dev-vpc" {
|
||||||
|
source = "../../../modules/net-vpc"
|
||||||
|
project_id = var.project_id
|
||||||
|
name = "${local.prefix}dev"
|
||||||
|
subnets = [
|
||||||
|
{
|
||||||
|
ip_cidr_range = var.ip_ranges.dev-0-r1
|
||||||
|
name = "${local.prefix}dev-0"
|
||||||
|
region = var.regions.r1
|
||||||
|
secondary_ip_range = try(
|
||||||
|
var.ip_secondary_ranges.dev-0-r1, {}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ip_cidr_range = var.ip_ranges.dev-0-r2
|
||||||
|
name = "${local.prefix}dev-0"
|
||||||
|
region = var.regions.r2
|
||||||
|
secondary_ip_range = try(
|
||||||
|
var.ip_secondary_ranges.dev-0-r2, {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
module "dev-firewall" {
|
||||||
|
source = "../../../modules/net-vpc-firewall"
|
||||||
|
project_id = var.project_id
|
||||||
|
network = module.dev-vpc.name
|
||||||
|
admin_ranges = values(var.ip_ranges)
|
||||||
|
}
|
||||||
|
|
||||||
|
module "dev-dns-peering" {
|
||||||
|
source = "../../../modules/dns"
|
||||||
|
project_id = var.project_id
|
||||||
|
type = "peering"
|
||||||
|
name = "${local.prefix}example-com-dev-peering"
|
||||||
|
domain = "example.com."
|
||||||
|
client_networks = [module.dev-vpc.self_link]
|
||||||
|
peer_network = module.landing-vpc.self_link
|
||||||
|
}
|
||||||
|
|
||||||
|
module "dev-dns-zone" {
|
||||||
|
source = "../../../modules/dns"
|
||||||
|
project_id = var.project_id
|
||||||
|
type = "private"
|
||||||
|
name = "${local.prefix}dev-example-com"
|
||||||
|
domain = "dev.example.com."
|
||||||
|
client_networks = [module.landing-vpc.self_link]
|
||||||
|
recordsets = {
|
||||||
|
"A localhost" = { ttl = 300, records = ["127.0.0.1"] }
|
||||||
|
"A test-r2" = { ttl = 300, records = [module.dev-r2-vm.internal_ip] }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
# Copyright 2022 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# tfdoc:file:description Landing hub VPC.
|
||||||
|
|
||||||
|
module "landing-vpc" {
|
||||||
|
source = "../../../modules/net-vpc"
|
||||||
|
project_id = var.project_id
|
||||||
|
name = "${local.prefix}lnd"
|
||||||
|
subnets = [
|
||||||
|
{
|
||||||
|
ip_cidr_range = var.ip_ranges.land-0-r1
|
||||||
|
name = "${local.prefix}lnd-0"
|
||||||
|
region = var.regions.r1
|
||||||
|
secondary_ip_range = try(
|
||||||
|
var.ip_secondary_ranges.land-0-r1, {}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ip_cidr_range = var.ip_ranges.land-0-r2
|
||||||
|
name = "${local.prefix}lnd-0"
|
||||||
|
region = var.regions.r2
|
||||||
|
secondary_ip_range = try(
|
||||||
|
var.ip_secondary_ranges.land-0-r2, {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
module "landing-firewall" {
|
||||||
|
source = "../../../modules/net-vpc-firewall"
|
||||||
|
project_id = var.project_id
|
||||||
|
network = module.landing-vpc.name
|
||||||
|
admin_ranges = values(var.ip_ranges)
|
||||||
|
}
|
||||||
|
|
||||||
|
module "landing-dns-zone" {
|
||||||
|
source = "../../../modules/dns"
|
||||||
|
project_id = var.project_id
|
||||||
|
type = "private"
|
||||||
|
name = "${local.prefix}example-com"
|
||||||
|
domain = "example.com."
|
||||||
|
client_networks = [module.landing-vpc.self_link]
|
||||||
|
recordsets = {
|
||||||
|
"A localhost" = { ttl = 300, records = ["127.0.0.1"] }
|
||||||
|
"A test-r1" = { ttl = 300, records = [module.landing-r1-vm.internal_ip] }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
# Copyright 2022 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# tfdoc:file:description Production spoke VPC.
|
||||||
|
|
||||||
|
module "prod-vpc" {
|
||||||
|
source = "../../../modules/net-vpc"
|
||||||
|
project_id = var.project_id
|
||||||
|
name = "${local.prefix}prd"
|
||||||
|
subnets = [
|
||||||
|
{
|
||||||
|
ip_cidr_range = var.ip_ranges.prod-0-r1
|
||||||
|
name = "${local.prefix}prd-0"
|
||||||
|
region = var.regions.r1
|
||||||
|
secondary_ip_range = try(
|
||||||
|
var.ip_secondary_ranges.prod-0-r1, {}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ip_cidr_range = var.ip_ranges.prod-0-r2
|
||||||
|
name = "${local.prefix}prd-0"
|
||||||
|
region = var.regions.r2
|
||||||
|
secondary_ip_range = try(
|
||||||
|
var.ip_secondary_ranges.prod-0-r2, {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
module "prod-firewall" {
|
||||||
|
source = "../../../modules/net-vpc-firewall"
|
||||||
|
project_id = var.project_id
|
||||||
|
network = module.prod-vpc.name
|
||||||
|
admin_ranges = values(var.ip_ranges)
|
||||||
|
}
|
||||||
|
|
||||||
|
module "prod-dns-peering" {
|
||||||
|
source = "../../../modules/dns"
|
||||||
|
project_id = var.project_id
|
||||||
|
type = "peering"
|
||||||
|
name = "${local.prefix}example-com-prd-peering"
|
||||||
|
domain = "example.com."
|
||||||
|
client_networks = [module.prod-vpc.self_link]
|
||||||
|
peer_network = module.landing-vpc.self_link
|
||||||
|
}
|
||||||
|
|
||||||
|
module "prod-dns-zone" {
|
||||||
|
source = "../../../modules/dns"
|
||||||
|
project_id = var.project_id
|
||||||
|
type = "private"
|
||||||
|
name = "${local.prefix}prd-example-com"
|
||||||
|
domain = "prd.example.com."
|
||||||
|
client_networks = [module.landing-vpc.self_link]
|
||||||
|
recordsets = {
|
||||||
|
"A localhost" = { ttl = 300, records = ["127.0.0.1"] }
|
||||||
|
"A test-r1" = { ttl = 300, records = [module.prod-r1-vm.internal_ip] }
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,10 +12,34 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
output "subnets" {
|
||||||
|
description = "Subnet details."
|
||||||
|
value = {
|
||||||
|
dev = {
|
||||||
|
for k, v in module.dev-vpc.subnets : k => {
|
||||||
|
id = v.id
|
||||||
|
ip_cidr_range = v.ip_cidr_range
|
||||||
|
}
|
||||||
|
}
|
||||||
|
landing = {
|
||||||
|
for k, v in module.landing-vpc.subnets : k => {
|
||||||
|
id = v.id
|
||||||
|
ip_cidr_range = v.ip_cidr_range
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prod = {
|
||||||
|
for k, v in module.prod-vpc.subnets : k => {
|
||||||
|
id = v.id
|
||||||
|
ip_cidr_range = v.ip_cidr_range
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
output "vms" {
|
output "vms" {
|
||||||
description = "GCE VMs."
|
description = "GCE VMs."
|
||||||
value = {
|
value = {
|
||||||
for instance in [module.vm-spoke-1.instance, module.vm-spoke-2.instance] :
|
for mod in [module.landing-r1-vm, module.dev-r2-vm, module.prod-r1-vm] :
|
||||||
instance.name => instance.network_interface.0.network_ip
|
mod.instance.name => mod.internal_ip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Copyright 2022 Google LLC
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
provider "google" {
|
|
||||||
}
|
|
||||||
provider "google-beta" {
|
|
||||||
}
|
|
|
@ -12,47 +12,40 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
variable "bgp_asn" {
|
|
||||||
description = "BGP ASNs."
|
|
||||||
type = map(number)
|
|
||||||
default = {
|
|
||||||
hub = 64513
|
|
||||||
spoke-1 = 64514
|
|
||||||
spoke-2 = 64515
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "bgp_custom_advertisements" {
|
|
||||||
description = "BGP custom advertisement IP CIDR ranges."
|
|
||||||
type = map(string)
|
|
||||||
default = {
|
|
||||||
hub-to-spoke-1 = "10.0.32.0/20"
|
|
||||||
hub-to-spoke-2 = "10.0.16.0/20"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "bgp_interface_ranges" {
|
|
||||||
description = "BGP interface IP CIDR ranges."
|
|
||||||
type = map(string)
|
|
||||||
default = {
|
|
||||||
spoke-1 = "169.254.1.0/30"
|
|
||||||
spoke-2 = "169.254.1.4/30"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "ip_ranges" {
|
variable "ip_ranges" {
|
||||||
description = "IP CIDR ranges."
|
description = "Subnet IP CIDR ranges."
|
||||||
type = map(string)
|
type = map(string)
|
||||||
default = {
|
default = {
|
||||||
hub-a = "10.0.0.0/24"
|
land-0-r1 = "10.0.0.0/24"
|
||||||
hub-b = "10.0.8.0/24"
|
land-0-r2 = "10.0.8.0/24"
|
||||||
spoke-1-a = "10.0.16.0/24"
|
dev-0-r1 = "10.0.16.0/24"
|
||||||
spoke-1-b = "10.0.24.0/24"
|
dev-0-r2 = "10.0.24.0/24"
|
||||||
spoke-2-a = "10.0.32.0/24"
|
prod-0-r1 = "10.0.32.0/24"
|
||||||
spoke-2-b = "10.0.40.0/24"
|
prod-0-r2 = "10.0.40.0/24"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "ip_secondary_ranges" {
|
||||||
|
description = "Subnet secondary ranges."
|
||||||
|
type = map(map(string))
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "prefix" {
|
||||||
|
description = "Prefix used in resource names."
|
||||||
|
type = string
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "project_create_config" {
|
||||||
|
description = "Populate with billing account id to trigger project creation."
|
||||||
|
type = object({
|
||||||
|
billing_account_id = string
|
||||||
|
parent_id = string
|
||||||
|
})
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
variable "project_id" {
|
variable "project_id" {
|
||||||
description = "Project id for all resources."
|
description = "Project id for all resources."
|
||||||
type = string
|
type = string
|
||||||
|
@ -62,7 +55,31 @@ variable "regions" {
|
||||||
description = "VPC regions."
|
description = "VPC regions."
|
||||||
type = map(string)
|
type = map(string)
|
||||||
default = {
|
default = {
|
||||||
a = "europe-west1"
|
r1 = "europe-west1"
|
||||||
b = "europe-west2"
|
r2 = "europe-west4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vpn_configs" {
|
||||||
|
description = "VPN configurations."
|
||||||
|
type = map(object({
|
||||||
|
asn = number
|
||||||
|
custom_ranges = map(string)
|
||||||
|
}))
|
||||||
|
default = {
|
||||||
|
land-r1 = {
|
||||||
|
asn = 64513
|
||||||
|
custom_ranges = {
|
||||||
|
"10.0.0.0/8" = "internal default"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dev-r1 = {
|
||||||
|
asn = 64514
|
||||||
|
custom_ranges = null
|
||||||
|
}
|
||||||
|
prod-r1 = {
|
||||||
|
asn = 64515
|
||||||
|
custom_ranges = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
# Copyright 2022 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# tfdoc:file:description Landing to Development VPN for region 1.
|
||||||
|
|
||||||
|
module "landing-to-dev-vpn-r1" {
|
||||||
|
source = "../../../modules/net-vpn-ha"
|
||||||
|
project_id = var.project_id
|
||||||
|
network = module.landing-vpc.self_link
|
||||||
|
region = var.regions.r1
|
||||||
|
name = "${local.prefix}lnd-to-dev-r1"
|
||||||
|
router_create = false
|
||||||
|
router_name = "${local.prefix}lnd-vpn-r1"
|
||||||
|
# router is created and managed by the production VPN module
|
||||||
|
# so we don't configure advertisements here
|
||||||
|
peer_gcp_gateway = module.dev-to-landing-vpn-r1.self_link
|
||||||
|
tunnels = {
|
||||||
|
0 = {
|
||||||
|
bgp_peer = {
|
||||||
|
address = "169.254.2.2"
|
||||||
|
asn = var.vpn_configs.dev-r1.asn
|
||||||
|
}
|
||||||
|
# use this attribute to configure different advertisements for dev
|
||||||
|
bgp_peer_options = null
|
||||||
|
bgp_session_range = "169.254.2.1/30"
|
||||||
|
ike_version = 2
|
||||||
|
peer_external_gateway_interface = null
|
||||||
|
router = null
|
||||||
|
shared_secret = null
|
||||||
|
vpn_gateway_interface = 0
|
||||||
|
}
|
||||||
|
1 = {
|
||||||
|
bgp_peer = {
|
||||||
|
address = "169.254.2.6"
|
||||||
|
asn = var.vpn_configs.dev-r1.asn
|
||||||
|
}
|
||||||
|
# use this attribute to configure different advertisements for dev
|
||||||
|
bgp_peer_options = null
|
||||||
|
bgp_session_range = "169.254.2.5/30"
|
||||||
|
ike_version = 2
|
||||||
|
peer_external_gateway_interface = null
|
||||||
|
router = null
|
||||||
|
shared_secret = null
|
||||||
|
vpn_gateway_interface = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module "dev-to-landing-vpn-r1" {
|
||||||
|
source = "../../../modules/net-vpn-ha"
|
||||||
|
project_id = var.project_id
|
||||||
|
network = module.dev-vpc.self_link
|
||||||
|
region = var.regions.r1
|
||||||
|
name = "${local.prefix}dev-to-lnd-r1"
|
||||||
|
router_create = true
|
||||||
|
router_name = "${local.prefix}dev-vpn-r1"
|
||||||
|
router_asn = var.vpn_configs.dev-r1.asn
|
||||||
|
router_advertise_config = (
|
||||||
|
var.vpn_configs.dev-r1.custom_ranges == null
|
||||||
|
? null
|
||||||
|
: {
|
||||||
|
groups = null
|
||||||
|
ip_ranges = coalesce(var.vpn_configs.dev-r1.custom_ranges, {})
|
||||||
|
mode = "CUSTOM"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
peer_gcp_gateway = module.landing-to-dev-vpn-r1.self_link
|
||||||
|
tunnels = {
|
||||||
|
0 = {
|
||||||
|
bgp_peer = {
|
||||||
|
address = "169.254.2.1"
|
||||||
|
asn = var.vpn_configs.land-r1.asn
|
||||||
|
}
|
||||||
|
bgp_peer_options = null
|
||||||
|
bgp_session_range = "169.254.2.2/30"
|
||||||
|
ike_version = 2
|
||||||
|
peer_external_gateway_interface = null
|
||||||
|
router = null
|
||||||
|
shared_secret = module.landing-to-dev-vpn-r1.random_secret
|
||||||
|
vpn_gateway_interface = 0
|
||||||
|
}
|
||||||
|
1 = {
|
||||||
|
bgp_peer = {
|
||||||
|
address = "169.254.2.5"
|
||||||
|
asn = var.vpn_configs.land-r1.asn
|
||||||
|
}
|
||||||
|
bgp_peer_options = null
|
||||||
|
bgp_session_range = "169.254.2.6/30"
|
||||||
|
ike_version = 2
|
||||||
|
peer_external_gateway_interface = null
|
||||||
|
router = null
|
||||||
|
shared_secret = module.landing-to-dev-vpn-r1.random_secret
|
||||||
|
vpn_gateway_interface = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
# Copyright 2022 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# tfdoc:file:description Landing to Production VPN for region 1.
|
||||||
|
|
||||||
|
module "landing-to-prod-vpn-r1" {
|
||||||
|
source = "../../../modules/net-vpn-ha"
|
||||||
|
project_id = var.project_id
|
||||||
|
network = module.landing-vpc.self_link
|
||||||
|
region = var.regions.r1
|
||||||
|
name = "${local.prefix}lnd-to-prd-r1"
|
||||||
|
router_create = true
|
||||||
|
router_name = "${local.prefix}lnd-vpn-r1"
|
||||||
|
router_asn = var.vpn_configs.land-r1.asn
|
||||||
|
router_advertise_config = (
|
||||||
|
var.vpn_configs.land-r1.custom_ranges == null
|
||||||
|
? null
|
||||||
|
: {
|
||||||
|
groups = null
|
||||||
|
ip_ranges = coalesce(var.vpn_configs.land-r1.custom_ranges, {})
|
||||||
|
mode = "CUSTOM"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
peer_gcp_gateway = module.prod-to-landing-vpn-r1.self_link
|
||||||
|
tunnels = {
|
||||||
|
0 = {
|
||||||
|
bgp_peer = {
|
||||||
|
address = "169.254.0.2"
|
||||||
|
asn = var.vpn_configs.prod-r1.asn
|
||||||
|
}
|
||||||
|
bgp_peer_options = null
|
||||||
|
bgp_session_range = "169.254.0.1/30"
|
||||||
|
ike_version = 2
|
||||||
|
peer_external_gateway_interface = null
|
||||||
|
router = null
|
||||||
|
shared_secret = null
|
||||||
|
vpn_gateway_interface = 0
|
||||||
|
}
|
||||||
|
1 = {
|
||||||
|
bgp_peer = {
|
||||||
|
address = "169.254.0.6"
|
||||||
|
asn = var.vpn_configs.prod-r1.asn
|
||||||
|
}
|
||||||
|
bgp_peer_options = null
|
||||||
|
bgp_session_range = "169.254.0.5/30"
|
||||||
|
ike_version = 2
|
||||||
|
peer_external_gateway_interface = null
|
||||||
|
router = null
|
||||||
|
shared_secret = null
|
||||||
|
vpn_gateway_interface = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module "prod-to-landing-vpn-r1" {
|
||||||
|
source = "../../../modules/net-vpn-ha"
|
||||||
|
project_id = var.project_id
|
||||||
|
network = module.prod-vpc.self_link
|
||||||
|
region = var.regions.r1
|
||||||
|
name = "${local.prefix}prd-to-lnd-r1"
|
||||||
|
router_create = true
|
||||||
|
router_name = "${local.prefix}prd-vpn-r1"
|
||||||
|
router_asn = var.vpn_configs.prod-r1.asn
|
||||||
|
# the router is managed here but shared with the dev VPN
|
||||||
|
router_advertise_config = (
|
||||||
|
var.vpn_configs.prod-r1.custom_ranges == null
|
||||||
|
? null
|
||||||
|
: {
|
||||||
|
groups = null
|
||||||
|
ip_ranges = coalesce(var.vpn_configs.prod-r1.custom_ranges, {})
|
||||||
|
mode = "CUSTOM"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
peer_gcp_gateway = module.landing-to-prod-vpn-r1.self_link
|
||||||
|
tunnels = {
|
||||||
|
0 = {
|
||||||
|
bgp_peer = {
|
||||||
|
address = "169.254.0.1"
|
||||||
|
asn = var.vpn_configs.land-r1.asn
|
||||||
|
}
|
||||||
|
# use this attribute to configure different advertisements for prod
|
||||||
|
bgp_peer_options = null
|
||||||
|
bgp_session_range = "169.254.0.2/30"
|
||||||
|
ike_version = 2
|
||||||
|
peer_external_gateway_interface = null
|
||||||
|
router = null
|
||||||
|
shared_secret = module.landing-to-prod-vpn-r1.random_secret
|
||||||
|
vpn_gateway_interface = 0
|
||||||
|
}
|
||||||
|
1 = {
|
||||||
|
bgp_peer = {
|
||||||
|
address = "169.254.0.5"
|
||||||
|
asn = var.vpn_configs.land-r1.asn
|
||||||
|
}
|
||||||
|
# use this attribute to configure different advertisements for prod
|
||||||
|
bgp_peer_options = null
|
||||||
|
bgp_session_range = "169.254.0.6/30"
|
||||||
|
ike_version = 2
|
||||||
|
peer_external_gateway_interface = null
|
||||||
|
router = null
|
||||||
|
shared_secret = module.landing-to-prod-vpn-r1.random_secret
|
||||||
|
vpn_gateway_interface = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module "test" {
|
module "test" {
|
||||||
source = "../../../../../examples/networking/hub-and-spoke-vpn"
|
source = "../../../../../examples/networking/hub-and-spoke-vpn"
|
||||||
project_id = var.project_id
|
project_create_config = {
|
||||||
|
billing_account_id = "ABCDE-123456-ABCDE"
|
||||||
|
parent_id = null
|
||||||
|
}
|
||||||
|
project_id = "test-1"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Copyright 2022 Google LLC
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
variable "project_id" {
|
|
||||||
type = string
|
|
||||||
default = "project-1"
|
|
||||||
}
|
|
|
@ -12,8 +12,9 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
def test_resources(e2e_plan_runner):
|
def test_resources(e2e_plan_runner):
|
||||||
"Test that plan works and the numbers of resources is as expected."
|
"Test that plan works and the numbers of resources is as expected."
|
||||||
modules, resources = e2e_plan_runner()
|
modules, resources = e2e_plan_runner()
|
||||||
assert len(modules) == 17
|
assert len(modules) == 19
|
||||||
assert len(resources) == 71
|
assert len(resources) == 73
|
||||||
|
|
Loading…
Reference in New Issue