Networking Sandbox Blueprint (#1939)

This blueprint creates a networking playground showing a number of different VPC connectivity options:

Hub and spoke via HA VPN
Hub and spoke via VPC peering
Interconnecting two networks via a network virtual appliance (aka NVA)
On top of that, this blueprint implements Policy Based Routing (aka PBR) to show how to force all traffic within a VPC to be funneled through an internal network passthrough load balancer, to implement an Intrusion Prevention System (IPS). PBR is enabled in the hub VPC, matching all traffic originating from within that VPC.
This commit is contained in:
Simone Ruffilli 2023-12-21 17:50:38 +01:00 committed by GitHub
parent 717f7ecad1
commit 87548f9739
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 11354 additions and 1 deletions

View File

@ -9,7 +9,7 @@ Currently available blueprints:
- **data solutions** - [GCE and GCS CMEK via centralized Cloud KMS](./data-solutions/cmek-via-centralized-kms), [Cloud Composer version 2 private instance, supporting Shared VPC and external CMEK key](./data-solutions/composer-2), [Cloud SQL instance with multi-region read replicas](./data-solutions/cloudsql-multiregion), [Data Platform](./data-solutions/data-platform-foundations), [Minimal Data Platform](./data-solutions/data-platform-minimal), [Spinning up a foundation data pipeline on Google Cloud using Cloud Storage, Dataflow and BigQuery](./data-solutions/gcs-to-bq-with-least-privileges), [#SQL Server Always On Groups blueprint](./data-solutions/sqlserver-alwayson), [Data Playground](./data-solutions/data-playground), [MLOps with Vertex AI](./data-solutions/vertex-mlops), [Shielded Folder](./data-solutions/shielded-folder), [BigQuery ML and Vertex AI Pipeline](./data-solutions/bq-ml)
- **factories** - [The why and the how of Resource Factories](./factories), [Google Cloud Identity Group Factory](./factories/cloud-identity-group-factory), [Google Cloud BQ Factory](./factories/bigquery-factory), [Google Cloud VPC Firewall Factory](./factories/net-vpc-firewall-yaml), [Minimal Project Factory](./factories/project-factory)
- **GKE** - [Binary Authorization Pipeline Blueprint](./gke/binauthz), [Storage API](./gke/binauthz/image), [Multi-cluster mesh on GKE (fleet API)](./gke/multi-cluster-mesh-gke-fleet-api), [GKE Multitenant Blueprint](./gke/multitenant-fleet), [Shared VPC with GKE support](./networking/shared-vpc-gke/), [GKE Autopilot](./gke/autopilot)
- **networking** - [Calling a private Cloud Function from On-premises](./networking/private-cloud-function-from-onprem), [Decentralized firewall management](./networking/decentralized-firewall), [Decentralized firewall validator](./networking/decentralized-firewall/validator), [HA VPN over Interconnect](./networking/ha-vpn-over-interconnect/), [GLB and multi-regional daisy-chaining through hybrid NEGs](./networking/glb-hybrid-neg-internal), [Hybrid connectivity to on-premise services through PSC](./networking/psc-hybrid), [HTTP Load Balancer with Cloud Armor](./networking/glb-and-armor), [Hub and Spoke via VPN](./networking/hub-and-spoke-vpn), [Hub and Spoke via VPC Peering](./networking/hub-and-spoke-peering), [Internal Load Balancer as Next Hop](./networking/ilb-next-hop), On-prem DNS and Google Private Access, [PSC Producer](./networking/psc-hybrid/psc-producer), [PSC Consumer](./networking/psc-hybrid/psc-consumer), [Shared VPC with optional GKE cluster](./networking/shared-vpc-gke)
- **networking** - [Calling a private Cloud Function from On-premises](./networking/private-cloud-function-from-onprem), [Decentralized firewall management](./networking/decentralized-firewall), [Decentralized firewall validator](./networking/decentralized-firewall/validator), [HA VPN over Interconnect](./networking/ha-vpn-over-interconnect/), [GLB and multi-regional daisy-chaining through hybrid NEGs](./networking/glb-hybrid-neg-internal), [Hybrid connectivity to on-premise services through PSC](./networking/psc-hybrid), [HTTP Load Balancer with Cloud Armor](./networking/glb-and-armor), [Hub and Spoke via VPN](./networking/hub-and-spoke-vpn), [Hub and Spoke via VPC Peering](./networking/hub-and-spoke-peering), [Internal Load Balancer as Next Hop](./networking/ilb-next-hop), On-prem DNS and Google Private Access, [PSC Producer](./networking/psc-hybrid/psc-producer), [PSC Consumer](./networking/psc-hybrid/psc-consumer), [Shared VPC with optional GKE cluster](./networking/shared-vpc-gke), [VPC Connectivity Lab](./networking/vpc-connectivity-lab/)
- **serverless** - [Cloud Run series](./serverless/cloud-run-explore)
- **third party solutions** - [OpenShift on GCP user-provisioned infrastructure](./third-party-solutions/openshift), [Wordpress deployment on Cloud Run](./third-party-solutions/wordpress/cloudrun)

View File

@ -96,3 +96,9 @@ It is meant to be used as a starting point for most Shared VPC configurations, a
It is meant to be used as a starting point for users that want to explore PSC to reduce some of the complexity in their network setup.
<br clear="left">
### VPC Connectivity Lab
<a href="./vpc-connectivity-lab/" title="VPC Connectivity Lab"><img src="./vpc-connectivity-lab/diagram.png" align="left" width="280px"></a> This [blueprint](./vpc-connectivity-lab/) creates a networking playground showing a number of different VPC connectivity options (peering, HA VPN, NVA), along with PBR routing.
<br clear="left">

View File

@ -0,0 +1,112 @@
# VPC Connectivity Lab
This blueprint creates a networking playground showing a number of different VPC connectivity options:
* Hub and spoke via HA VPN
* Hub and spoke via VPC peering
* Interconnecting two networks via a network virtual appliance (aka NVA)
On top of that, this blueprint implements Policy Based Routing (aka PBR) to show how to force all traffic within a VPC to be funneled through an internal network passthrough load balancer, to implement an Intrusion Prevention System (IPS). PBR is enabled in the `hub` VPC, matching all traffic originating from within that VPC.
The blueprint has been purposefully kept simple to show how to use and wire VPCs together, and so that it can be used as a basis for experimentation.
This is the high level diagram of this blueprint:
![High-level diagram](diagram.png "High-level diagram")
## Prerequisites
This blueprint is contained within a single project to keep complexity to a minimum, even though in a real world scenario each spoke would probably use a separate project.
The blueprint can either create a new project or consume an existing one.
If the variable `var.project_create_config` is populated, the blueprint will create a new project named `var.project_id`, otherwise the blueprint will use an existing project with the same id.
## Testing reachability
After running terraform, and in case `var.test_vms` is set to true (as it is by default), a set of ping commands will be printed to check the reachability of all VMs. The blueprint is configured to ensure that all VMs can ping each other - so you can simply SSH to each one, and run the generated ping commands, e.g.:
```bash
ping -c 1 ext.example
ping -c 1 hub-a.example
ping -c 1 hub-b.example
ping -c 1 spoke-peering-a.example
ping -c 1 spoke-peering-b.example
ping -c 1 spoke-vpn-a.example
ping -c 1 spoke-vpn-b.example
```
## Testing IPS/NVA
Per blueprint setup, not all traffic will flow through the deployed test NVAs.
You should expect the following flows to be routed through them:
* `ext` to {`hub`, `peering-a`, `peering-b`, `vpn-a`, `vpn-b`}
* `peering-a` to {`ext`, `peering-b`}
* `peering-b` to {`ext`, `peering-a`}
* `vpn-a` to {`ext`}
* `vpn-b` to {`ext`}
Additional PBR routes could be configured to force all traffic coming from `vpn-{a,b}` to go through the NVA - however traffic coming from `peering-{a,b}` can NOT be subjected to PBR routes, due to product constrains.
In order to see the actual traffic flow, you'll want to manually stop one of the NVA instances (to force all traffic to be sent through a single VM), SSH to the active NVA instance and run the following commands:
```bash
# Setting the toolbox up might take a while since we're using cheap instances :)
$ toolbox
# Once inside the toolbox
$ tcpdump -i any icmp -n
```
<!-- TFDOC OPTS files:1 -->
<!-- BEGIN TFDOC -->
## Files
| name | description | modules | resources |
|---|---|---|---|
| [dns-hub.tf](./dns-hub.tf) | DNS setup. | <code>dns</code> | |
| [main.tf](./main.tf) | Project setup. | <code>project</code> | |
| [nva.tf](./nva.tf) | None | <code>compute-vm</code> · <code>simple-nva</code> | <code>google_compute_instance_group</code> |
| [outputs.tf](./outputs.tf) | Module outputs. | | |
| [test-resources.tf](./test-resources.tf) | None | | |
| [variables.tf](./variables.tf) | Module variables. | | |
| [vpc-ext.tf](./vpc-ext.tf) | External VPC. | <code>net-address</code> · <code>net-cloudnat</code> · <code>net-lb-int</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> | <code>google_compute_route</code> |
| [vpc-hub.tf](./vpc-hub.tf) | Internal Hub VPC. | <code>net-address</code> · <code>net-lb-int</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpc-peering</code> · <code>net-vpn-ha</code> | <code>google_compute_route</code> |
| [vpc-peering-a.tf](./vpc-peering-a.tf) | None | <code>net-vpc</code> · <code>net-vpc-firewall</code> | |
| [vpc-peering-b.tf](./vpc-peering-b.tf) | None | <code>net-vpc</code> · <code>net-vpc-firewall</code> | |
| [vpc-vpn-a.tf](./vpc-vpn-a.tf) | None | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpn-ha</code> | |
| [vpc-vpn-b.tf](./vpc-vpn-b.tf) | None | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpn-ha</code> | |
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [prefix](variables.tf#L37) | Prefix used for resource names. | <code>string</code> | ✓ | |
| [ip_ranges](variables.tf#L17) | Subnet/Routes IP CIDR ranges. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; ext &#61; &#34;10.255.0.0&#47;16&#34;&#10; hub-a &#61; &#34;10.0.1.0&#47;24&#34;&#10; hub-all &#61; &#34;10.0.0.0&#47;16&#34;&#10; hub-b &#61; &#34;10.0.2.0&#47;24&#34;&#10; hub-nva &#61; &#34;10.0.0.0&#47;24&#34;&#10; int &#61; &#34;10.0.0.0&#47;9&#34;&#10; peering-a &#61; &#34;10.3.0.0&#47;24&#34;&#10; peering-b &#61; &#34;10.4.0.0&#47;24&#34;&#10; rfc1918_10 &#61; &#34;10.0.0.0&#47;8&#34;&#10; rfc1918_172 &#61; &#34;172.16.0.0&#47;12&#34;&#10; rfc1918_192 &#61; &#34;192.168.0.0&#47;16&#34;&#10; vpn-a &#61; &#34;10.1.0.0&#47;24&#34;&#10; vpn-b &#61; &#34;10.2.0.0&#47;24&#34;&#10;&#125;">&#123;&#8230;&#125;</code> |
| [project_create_config](variables.tf#L46) | Populate with billing account id to trigger project creation. | <code title="object&#40;&#123;&#10; billing_account_id &#61; string&#10; parent_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [project_id](variables.tf#L55) | Project id for all resources. | <code>string</code> | | <code>&#34;net-test-02&#34;</code> |
| [region](variables.tf#L61) | Region used to deploy resources. | <code>string</code> | | <code>&#34;europe-west8&#34;</code> |
| [test_vms](variables.tf#L67) | Enable the creation of test resources. | <code>bool</code> | | <code>true</code> |
## Outputs
| name | description | sensitive |
|---|---|:---:|
| [ping_commands](outputs.tf#L17) | Ping commands that can be run to check VPC reachability. | |
<!-- END TFDOC -->
## Test
```hcl
module "test" {
source = "./fabric/blueprints/networking/vpc-connectivity-lab"
project_create_config = {
billing_account_id = "123456-123456-123456"
parent_id = "folders/123456789"
}
project_id = "net-test-04"
prefix = "fast-sr0-sbox"
}
# tftest modules=35 resources=131
```

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 196 KiB

View File

@ -0,0 +1,42 @@
/**
* Copyright 2023 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
*
* http://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 DNS setup.
module "hub-dns" {
source = "../../../modules/dns"
project_id = module.project.project_id
name = "${var.prefix}-example"
zone_config = {
domain = "example."
private = {
client_networks = [
module.hub-vpc.self_link,
module.ext-vpc.self_link,
module.spoke-peering-a-vpc.self_link,
module.spoke-peering-b-vpc.self_link,
module.spoke-vpn-a-vpc.self_link,
module.spoke-vpn-b-vpc.self_link,
]
}
}
recordsets = merge({
"A localhost" = { records = ["127.0.0.1"] }
},
var.test_vms
? { for instance, _ in local.test-vms : "A ${instance}" => { records = [module.test-vms[instance].internal_ip] } }
: {})
}

View File

@ -0,0 +1,32 @@
/**
* Copyright 2023 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
*
* http://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 Project setup.
module "project" {
source = "../../../modules/project"
name = var.project_id
parent = try(var.project_create_config.parent_id, null)
billing_account = try(var.project_create_config.billing_account_id, null)
project_create = try(var.project_create_config.billing_account_id, null) != null
prefix = var.prefix
services = [
"compute.googleapis.com",
"dns.googleapis.com",
"networkconnectivity.googleapis.com",
"stackdriver.googleapis.com",
]
}

View File

@ -0,0 +1,117 @@
/**
* Copyright 2023 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
*
* http://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.
*/
locals {
network_interfaces = [
{
addresses = null
name = "ext"
nat = false
enable_masquerading = true
network = module.ext-vpc.self_link
routes = [var.ip_ranges.ext, "0.0.0.0/0"]
subnetwork = module.ext-vpc.subnet_self_links["${var.region}/ext"]
},
{
addresses = null
name = "hub"
nat = false
network = module.hub-vpc.self_link
routes = [var.ip_ranges.int]
subnetwork = module.hub-vpc.subnet_self_links["${var.region}/hub-nva"]
}
]
}
module "cos-nva" {
source = "../../../modules/cloud-config-container/simple-nva"
enable_health_checks = true
network_interfaces = local.network_interfaces
}
module "nva-a" {
source = "../../../modules/compute-vm"
project_id = module.project.project_id
zone = "${var.region}-a"
name = "cos-nva-a"
network_interfaces = local.network_interfaces
can_ip_forward = true
instance_type = "e2-micro"
options = {
spot = true
termination_action = "STOP"
}
metadata = {
user-data = module.cos-nva.cloud_config
google-logging-enabled = true
}
boot_disk = {
initialize_params = {
image = "projects/cos-cloud/global/images/family/cos-stable"
type = "pd-ssd"
size = 10
}
}
tags = ["nva", "ssh"]
}
module "nva-b" {
source = "../../../modules/compute-vm"
project_id = module.project.project_id
zone = "${var.region}-b"
name = "cos-nva-b"
network_interfaces = local.network_interfaces
can_ip_forward = true
instance_type = "e2-micro"
options = {
spot = true
termination_action = "STOP"
}
metadata = {
user-data = module.cos-nva.cloud_config
google-logging-enabled = true
}
boot_disk = {
initialize_params = {
image = "projects/cos-cloud/global/images/family/cos-stable"
type = "pd-ssd"
size = 10
}
}
tags = ["nva", "ssh"]
}
resource "google_compute_instance_group" "nva-a" {
name = "nva-ig-a"
description = "NVA instance group for the primary region, zone a."
zone = "${var.region}-a"
project = module.project.project_id
network = module.ext-vpc.self_link
instances = toset([
module.nva-a.self_link,
])
}
resource "google_compute_instance_group" "nva-b" {
name = "nva-ig-b"
description = "NVA instance group for the primary region, zone b."
zone = "${var.region}-b"
project = module.project.project_id
network = module.ext-vpc.self_link
instances = toset([
module.nva-b.self_link,
])
}

View File

@ -0,0 +1,20 @@
/**
* Copyright 2023 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
*
* http://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.
*/
output "ping_commands" {
description = "Ping commands that can be run to check VPC reachability."
value = var.test_vms ? join("\n", [for instance, _ in local.test-vms : "ping -c 1 ${instance}.example"]) : ""
}

View File

@ -0,0 +1,82 @@
/**
* Copyright 2023 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
*
* http://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.
*/
locals {
test-vms = {
ext = {
network = module.ext-vpc.self_link
subnetwork = module.ext-vpc.subnet_self_links["${var.region}/ext"]
}
hub-a = {
network = module.hub-vpc.self_link
subnetwork = module.hub-vpc.subnet_self_links["${var.region}/hub-a"]
}
hub-b = {
network = module.hub-vpc.self_link
subnetwork = module.hub-vpc.subnet_self_links["${var.region}/hub-b"]
}
spoke-vpn-a = {
network = module.spoke-vpn-a-vpc.self_link
subnetwork = module.spoke-vpn-a-vpc.subnet_self_links["${var.region}/vpn-a"]
},
spoke-peering-a = {
network = module.spoke-peering-a-vpc.self_link
subnetwork = module.spoke-peering-a-vpc.subnet_self_links["${var.region}/peering-a"]
},
spoke-vpn-b = {
network = module.spoke-vpn-b-vpc.self_link
subnetwork = module.spoke-vpn-b-vpc.subnet_self_links["${var.region}/vpn-b"]
},
spoke-peering-b = {
network = module.spoke-peering-b-vpc.self_link
subnetwork = module.spoke-peering-b-vpc.subnet_self_links["${var.region}/peering-b"]
},
}
}
module "test-vms" {
for_each = var.test_vms ? local.test-vms : {}
source = "../../../modules/compute-vm"
project_id = module.project.project_id
zone = "${var.region}-a"
name = "test-vm-${each.key}"
network_interfaces = [{
network = each.value.network
# change the subnet name to match the values you are actually using
subnetwork = each.value.subnetwork
}]
instance_type = "e2-micro"
tags = ["ssh"]
boot_disk = {
initialize_params = {
image = "projects/debian-cloud/global/images/family/debian-11"
}
}
options = {
spot = true
termination_action = "STOP"
}
metadata = {
startup-script = <<EOF
export DEB_VERSION=`lsb_release -c | awk '{print $2}'`
echo "deb https://packages.cloud.google.com/mirror/cloud-apt/$DEB_VERSION $DEB_VERSION main" > /etc/apt/sources.list
echo "deb https://packages.cloud.google.com/mirror/cloud-apt/$DEB_VERSION-security $DEB_VERSION-security main" >> /etc/apt/sources.list
echo "deb https://packages.cloud.google.com/mirror/cloud-apt/$DEB_VERSION-updates $DEB_VERSION-updates main" >> /etc/apt/sources.list
apt update
apt install -y iputils-ping bind9-dnsutils
EOF
}
}

View File

@ -0,0 +1,72 @@
/**
* Copyright 2023 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
*
* http://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 "ip_ranges" {
description = "Subnet/Routes IP CIDR ranges."
type = map(string)
default = {
ext = "10.255.0.0/16"
hub-a = "10.0.1.0/24"
hub-all = "10.0.0.0/16"
hub-b = "10.0.2.0/24"
hub-nva = "10.0.0.0/24"
int = "10.0.0.0/9"
peering-a = "10.3.0.0/24"
peering-b = "10.4.0.0/24"
rfc1918_10 = "10.0.0.0/8"
rfc1918_172 = "172.16.0.0/12"
rfc1918_192 = "192.168.0.0/16"
vpn-a = "10.1.0.0/24"
vpn-b = "10.2.0.0/24"
}
}
variable "prefix" {
description = "Prefix used for resource names."
type = string
validation {
condition = var.prefix != ""
error_message = "Prefix cannot be empty."
}
}
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" {
description = "Project id for all resources."
type = string
default = "net-test-02"
}
variable "region" {
description = "Region used to deploy resources."
type = string
default = "europe-west8"
}
variable "test_vms" {
description = "Enable the creation of test resources."
type = bool
default = true
}

View File

@ -0,0 +1,105 @@
/**
* Copyright 2023 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
*
* http://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 External VPC.
module "ext-vpc" {
source = "../../../modules/net-vpc"
project_id = module.project.project_id
name = "ext"
mtu = 1500
subnets = [
{
name = "ext"
region = var.region
ip_cidr_range = var.ip_ranges.ext
}
]
}
module "nat" {
source = "../../../modules/net-cloudnat"
project_id = module.project.project_id
router_network = module.ext-vpc.name
region = var.region
name = "default"
}
module "ext-firewall" {
source = "../../../modules/net-vpc-firewall"
project_id = module.project.project_id
network = module.ext-vpc.name
default_rules_config = {
admin_ranges = [var.ip_ranges.rfc1918_10]
ssh_ranges = ["35.235.240.0/20", "35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]
}
}
resource "google_compute_route" "ext-rfc1918-10" {
project = module.project.project_id
network = module.ext-vpc.name
name = "ext-rfc1918-10"
description = "Terraform-managed."
dest_range = var.ip_ranges.rfc1918_10
priority = 1000
next_hop_ilb = module.ext-lb.forwarding_rule_self_links[""]
}
module "ext-addresses" {
source = "../../../modules/net-address"
project_id = module.project.project_id
internal_addresses = {
ext = {
region = var.region
subnetwork = module.ext-vpc.subnet_self_links["${var.region}/ext"]
address = cidrhost(module.ext-vpc.subnet_ips["${var.region}/ext"], -3)
}
}
}
module "ext-lb" {
source = "../../../modules/net-lb-int"
project_id = module.project.project_id
region = var.region
name = "ext-lb"
vpc_config = {
network = module.ext-vpc.name
subnetwork = module.ext-vpc.subnet_self_links["${var.region}/ext"]
}
forwarding_rules_config = {
"" = {
global_access = false
address = module.ext-addresses.internal_addresses["ext"].address
}
}
backends = [
{
failover = false
group = google_compute_instance_group.nva-a.id
balancing_mode = "CONNECTION"
},
{
failover = false
group = google_compute_instance_group.nva-b.id
balancing_mode = "CONNECTION"
},
]
health_check_config = {
tcp = {
port = 22
}
}
}

View File

@ -0,0 +1,222 @@
/**
* Copyright 2023 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
*
* http://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 Internal Hub VPC.
module "hub-vpc" {
source = "../../../modules/net-vpc"
project_id = module.project.project_id
name = "hub"
mtu = 1500
subnets = [
{
name = "hub-nva"
region = var.region
ip_cidr_range = var.ip_ranges.hub-nva
},
{
name = "hub-a"
region = var.region
ip_cidr_range = var.ip_ranges.hub-a
},
{
name = "hub-b"
region = var.region
ip_cidr_range = var.ip_ranges.hub-b
},
]
policy_based_routes = {
nva-skip = {
use_default_routing = true
priority = 100
target = {
tags = ["nva"]
}
}
default-nva = {
next_hop_ilb_ip = module.hub-lb.forwarding_rule_addresses[""]
priority = 101
filter = {
src_range = var.ip_ranges.hub-all
dest_range = "0.0.0.0/0"
}
}
}
}
module "hub-firewall" {
source = "../../../modules/net-vpc-firewall"
project_id = module.project.project_id
network = module.hub-vpc.name
default_rules_config = {
admin_ranges = [var.ip_ranges.rfc1918_10]
ssh_ranges = ["35.235.240.0/20", "35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]
}
}
resource "google_compute_route" "hub-0-0" {
project = module.project.project_id
network = module.hub-vpc.name
name = "hub-0-0"
description = "Terraform-managed."
dest_range = "0.0.0.0/0"
priority = 1000
next_hop_ilb = module.hub-lb.forwarding_rule_self_links[""]
}
module "hub-addresses" {
source = "../../../modules/net-address"
project_id = module.project.project_id
internal_addresses = {
hub = {
region = var.region
subnetwork = module.hub-vpc.subnet_self_links["${var.region}/hub-nva"]
address = cidrhost(module.hub-vpc.subnet_ips["${var.region}/hub-nva"], -3)
}
}
}
module "hub-lb" {
source = "../../../modules/net-lb-int"
project_id = module.project.project_id
region = var.region
name = "hub-lb"
vpc_config = {
network = module.hub-vpc.name
subnetwork = module.hub-vpc.subnet_self_links["${var.region}/hub-nva"]
}
forwarding_rules_config = {
"" = {
global_access = false
address = module.hub-addresses.internal_addresses["hub"].address
}
}
backends = [
{
failover = false
group = google_compute_instance_group.nva-a.id
balancing_mode = "CONNECTION"
},
{
failover = false
group = google_compute_instance_group.nva-b.id
balancing_mode = "CONNECTION"
},
]
health_check_config = {
tcp = {
port = 22
}
}
}
module "vpn-hub-a" {
source = "../../../modules/net-vpn-ha"
project_id = module.project.project_id
region = var.region
network = module.hub-vpc.self_link
name = "hub-a"
peer_gateways = {
default = { gcp = module.vpn-a-hub.self_link }
}
router_config = {
asn = 64513
custom_advertise = {
all_subnets = false
ip_ranges = {
"0.0.0.0/0" = "default"
}
}
}
tunnels = {
remote-0 = {
bgp_peer = {
address = "169.254.1.2"
asn = 64514
}
bgp_session_range = "169.254.1.1/30"
shared_secret = module.vpn-a-hub.random_secret
vpn_gateway_interface = 0
}
remote-1 = {
bgp_peer = {
address = "169.254.2.2"
asn = 64514
}
bgp_session_range = "169.254.2.1/30"
shared_secret = module.vpn-a-hub.random_secret
vpn_gateway_interface = 1
}
}
}
module "vpn-hub-b" {
source = "../../../modules/net-vpn-ha"
project_id = module.project.project_id
region = var.region
network = module.hub-vpc.self_link
name = "hub-b"
peer_gateways = {
default = { gcp = module.vpn-b-hub.self_link }
}
router_config = {
asn = 64513
custom_advertise = {
all_subnets = false
ip_ranges = {
"0.0.0.0/0" = "default"
}
}
}
tunnels = {
remote-0 = {
bgp_peer = {
address = "169.254.1.6"
asn = 64515
}
bgp_session_range = "169.254.1.5/30"
shared_secret = module.vpn-b-hub.random_secret
vpn_gateway_interface = 0
}
remote-1 = {
bgp_peer = {
address = "169.254.2.6"
asn = 64515
}
bgp_session_range = "169.254.2.5/30"
shared_secret = module.vpn-b-hub.random_secret
vpn_gateway_interface = 1
}
}
}
module "peering-hub-a" {
source = "../../../modules/net-vpc-peering"
prefix = "a"
local_network = module.hub-vpc.id
peer_network = module.spoke-peering-a-vpc.id
}
module "peering-hub-b" {
source = "../../../modules/net-vpc-peering"
prefix = "b"
local_network = module.hub-vpc.id
peer_network = module.spoke-peering-b-vpc.id
depends_on = [module.spoke-peering-a-vpc.id]
}

View File

@ -0,0 +1,48 @@
/**
* Copyright 2023 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
*
* http://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.
*/
module "spoke-peering-a-vpc" {
source = "../../../modules/net-vpc"
project_id = module.project.project_id
name = "peering-a"
mtu = 1500
subnets = [
{
name = "peering-a"
region = var.region
ip_cidr_range = var.ip_ranges.peering-a
}
]
routes = {
default = {
description = "Route to default."
dest_range = "0.0.0.0/0"
tags = null
next_hop_type = "ilb"
next_hop = module.hub-lb.forwarding_rule_addresses[""]
}
}
}
module "peering-a-firewall" {
source = "../../../modules/net-vpc-firewall"
project_id = module.project.project_id
network = module.spoke-peering-a-vpc.name
default_rules_config = {
admin_ranges = [var.ip_ranges.rfc1918_10]
}
}

View File

@ -0,0 +1,47 @@
/**
* Copyright 2023 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
*
* http://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.
*/
module "spoke-peering-b-vpc" {
source = "../../../modules/net-vpc"
project_id = module.project.project_id
name = "peering-b"
mtu = 1500
subnets = [
{
name = "peering-b"
region = var.region
ip_cidr_range = var.ip_ranges.peering-b
}
]
routes = {
default = {
description = "Route to default."
dest_range = "0.0.0.0/0"
tags = null
next_hop_type = "ilb"
next_hop = module.hub-lb.forwarding_rule_addresses[""]
}
}
}
module "peering-b-firewall" {
source = "../../../modules/net-vpc-firewall"
project_id = module.project.project_id
network = module.spoke-peering-b-vpc.name
default_rules_config = {
admin_ranges = [var.ip_ranges.rfc1918_10]
}
}

View File

@ -0,0 +1,78 @@
/**
* Copyright 2023 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
*
* http://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.
*/
module "spoke-vpn-a-vpc" {
source = "../../../modules/net-vpc"
project_id = module.project.project_id
name = "vpn-a"
mtu = 1500
subnets = [
{
name = "vpn-a"
region = var.region
ip_cidr_range = var.ip_ranges.vpn-a
}
]
}
module "vpn-a-firewall" {
source = "../../../modules/net-vpc-firewall"
project_id = module.project.project_id
network = module.spoke-vpn-a-vpc.name
default_rules_config = {
admin_ranges = [var.ip_ranges.rfc1918_10]
}
}
module "vpn-a-hub" {
source = "../../../modules/net-vpn-ha"
project_id = module.project.project_id
region = var.region
network = module.spoke-vpn-a-vpc.self_link
name = "a-hub"
peer_gateways = {
default = { gcp = module.vpn-hub-a.self_link }
}
router_config = {
asn = 64514
custom_advertise = {
all_subnets = false
ip_ranges = {
(var.ip_ranges.vpn-a) = "default"
}
}
}
tunnels = {
remote-0 = {
bgp_peer = {
address = "169.254.1.1"
asn = 64513
}
bgp_session_range = "169.254.1.2/30"
vpn_gateway_interface = 0
}
remote-1 = {
bgp_peer = {
address = "169.254.2.1"
asn = 64513
}
bgp_session_range = "169.254.2.2/30"
vpn_gateway_interface = 1
}
}
}

View File

@ -0,0 +1,76 @@
/**
* Copyright 2023 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
*
* http://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.
*/
module "spoke-vpn-b-vpc" {
source = "../../../modules/net-vpc"
project_id = module.project.project_id
name = "vpn-b"
mtu = 1500
subnets = [
{
name = "vpn-b"
region = var.region
ip_cidr_range = var.ip_ranges.vpn-b
}
]
}
module "vpn-b-firewall" {
source = "../../../modules/net-vpc-firewall"
project_id = module.project.project_id
network = module.spoke-vpn-b-vpc.name
default_rules_config = {
admin_ranges = [var.ip_ranges.rfc1918_10]
}
}
module "vpn-b-hub" {
source = "../../../modules/net-vpn-ha"
project_id = module.project.project_id
region = var.region
network = module.spoke-vpn-b-vpc.self_link
name = "b-hub"
peer_gateways = {
default = { gcp = module.vpn-hub-b.self_link }
}
router_config = {
asn = 64515
custom_advertise = {
all_subnets = false
ip_ranges = {
(var.ip_ranges.vpn-b) = "default"
}
}
}
tunnels = {
remote-0 = {
bgp_peer = {
address = "169.254.1.5"
asn = 64513
}
bgp_session_range = "169.254.1.6/30"
vpn_gateway_interface = 0
}
remote-1 = {
bgp_peer = {
address = "169.254.2.5"
asn = 64513
}
bgp_session_range = "169.254.2.6/30"
vpn_gateway_interface = 1
}
}
}