https://github.com/memes/terraform-google-multi-region-private-network
Terraform module to create a private global VPC network with subnets in the specified regions, with each subnet receiving a CIDR of specified size.
https://github.com/memes/terraform-google-multi-region-private-network
Last synced: 27 days ago
JSON representation
Terraform module to create a private global VPC network with subnets in the specified regions, with each subnet receiving a CIDR of specified size.
- Host: GitHub
- URL: https://github.com/memes/terraform-google-multi-region-private-network
- Owner: memes
- License: apache-2.0
- Created: 2023-02-12T01:41:08.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-01-24T23:25:48.000Z (over 1 year ago)
- Last Synced: 2025-01-25T00:22:19.636Z (over 1 year ago)
- Language: Ruby
- Size: 180 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# Multi-region VPC network module


[](CODE_OF_CONDUCT.md)
This Terraform module creates an opinionated private global VPC network that spans
the regions provided, with each subnet receiving a calculated CIDR of requested
size from the network CIDR.
The default configuration will create a VPC network with the following properties:
* For each region, a `/24` subnet from `172.16.0.0/12`, with no secondary ranges
* Private by default
* Default route to internet (0.0.0.0/0) is deleted
* Private Google API access is enabled to support VPC Service Controls
* Private connectivity route is added to support VPC Service Controls
> NOTE: Private Cloud DNS zones and bastions are not managed by this module;
> see [restricted-apis-dns] and [private-bastion] for those.
Optionally, a Cloud NAT gateway can be added to each region to allow for controlled
egress traffic, and IPv6 ULA addressing enabled.
## Opinions
1. The network should be defined as a CIDR; the module will allocate sub-CIDRs to
regions as needed.
2. The network will be **private** by default
3. Module consumers can override CIDRs, and option flags, but must explicitly set
all the `cidrs` and/or `options` fields. Nothing is inferred by omission.
4. Firewall rules, additional routes, and other per-application settings should
not be managed by this module.
> NOTE: The intent of this module is to easily repeat common VPC network patterns
> I use to deploy in Google Cloud; it is not a general purpose VPC network creation
> tool. Use Google's [network] module for that purpose.
## Examples
### Dual region (us-west1 and us-east1) private VPC network
|Item|Enabled/managed by module|Description|
|----|-----------------|-----------|
|Regions|✓|`us-west1` and `us-east1`|
|Primary IPv4 CIDR|✓|`172.16.0.0/12` (`/24` per region)|
|Primary IPv6 CIDR||Not enabled|
|Secondary IPv4 CIDRs||None added|
|VPC routing mode|✓|GLOBAL|
|Default internet route|✓|Deleted; VPC will not route to internet|
|Restricted API route|✓|A route for restricted Google API endpoints is added|
|Private API route||None added|
|MTU|✓|1460|
|Cloud NAT|||
|*Restricted Google API DNS zone(s)*||*Not managed by this module; see [restricted-apis-dns]*|
|*Bastion*||*Not managed by this module; see [private-bastion]*|
```hcl
module "vpc" {
source = "memes/multi-region-private-network/google"
version = "5.0.0"
project_id = "my-project-id"
name = "internal-us"
regions = ["us-west1", "us-east1"]
}
```
### Dual region (us-west1 and us-east1) private VPC network, with primary subnet offset and steps
|Item|Enabled/managed by module|Description|
|----|-----------------|-----------|
|Regions|✓|`us-west1` and `us-east1`|
|Primary IPv4 CIDR|✓|`172.16.0.0/12` (as `172.16.10.0/16`, `172.16.20.0/16`)|
|Primary IPv6 CIDR||Not enabled|
|Secondary IPv4 CIDRs||None added|
|VPC routing mode|✓|GLOBAL|
|Default internet route|✓|Deleted; VPC will not route to internet|
|Restricted API route|✓|A route for restricted Google API endpoints is added|
|Private API route||None added|
|MTU|✓|1460|
|Cloud NAT|||
|*Restricted Google API DNS zone(s)*||*Not managed by this module; see [restricted-apis-dns]*|
|*Bastion*||*Not managed by this module; see [private-bastion]*|
```hcl
module "vpc" {
source = "memes/multi-region-private-network/google"
version = "5.0.0"
project_id = "my-project-id"
name = "internal-us"
regions = ["us-west1", "us-east1"]
cidrs = {
primary_ipv4_subnet_offset = 10
primary_ipv4_subnet_step = 10
}
}
```
### Dual region (us-west1 and us-east1) with secondary ranges for GKE
|Item|Enabled/managed by module|Description|
|----|-----------------|-----------|
|Regions|✓|`us-west1` and `us-east1`|
|Primary IPv4 CIDR|✓|`172.16.0.0/12` (`/24` per region)|
|Primary IPv6 CIDR||Not enabled|
|Secondary IPv4 CIDRs|✓|• `pods` CIDR `10.x.0.0/16` per region
• `services` CIDR `10.100.x.0/24` per region|
|VPC routing mode|✓|GLOBAL|
|Default internet route|✓|Deleted; VPC will not route to internet|
|Restricted API route|✓|A route for restricted Google API endpoints is added|
|Private API route||None added|
|MTU|✓|1460|
|Cloud NAT||Not enabled|
|*Restricted Google API DNS zone(s)*||*Not managed by this module; see [restricted-apis-dns]*|
|*Bastion*||*Not managed by this module; see [private-bastion]*|
```hcl
module "vpc" {
source = "memes/multi-region-private-network/google"
version = "5.0.0"
project_id = "my-project-id"
regions = ["us-west1", "us-east1"]
cidrs = {
secondaries = {
pods = {
ipv4_cidr = "10.0.0.0/8"
ipv4_subnet_size = 16
}
services = {
ipv4_cidr = "10.100.0.0/16"
}
}
}
}
```
### Dual region (us-west1 and us-east1) with Cloud NAT
|Item|Managed by module|Description|
|----|-----------------|-----------|
|Regions|✓|`us-west1` and `us-east1`|
|Primary IPv4 CIDR|✓|`172.16.0.0/12` (`/24` per region)|
|Primary IPv6 CIDR||Not enabled|
|Secondary IPv4 CIDRs||None added|
|VPC routing mode|✓|GLOBAL|
|Default internet route|✓|Not deleted - Cloud NAT requires a default internet route be in place|
|Restricted API route|✓|A route for restricted Google API endpoints is added|
|Private API route||None added|
|MTU|✓|1460|
|Cloud NAT|✓|A Cloud Router and Cloud NAT will be created in each region|
|*Restricted Google API DNS zone(s)*||*Not managed by this module; see [restricted-apis-dns]*|
|*Bastion*||*Not managed by this module; see [private-bastion]*|
```hcl
module "vpc" {
source = "memes/multi-region-private-network/google"
version = "5.0.0"
project_id = "my-project-id"
regions = ["us-west1", "us-east1"]
nat = {
tags = ["allow-nat"]
}
}
```
### Dual region (us-west1 and us-east1) with auto-allocated IPv6 CIDR
|Item|Enable/managed by module|Description|
|----|-----------------|-----------|
|Regions|✓|`us-west1` and `us-east1`|
|Primary IPv4 CIDR|✓|`172.16.0.0/12` (`/24` per region)|
|Primary IPv6 CIDR|✓|Auto-allocated `/48` from `fd20::/20` (`/64` per region)|
|Secondary IPv4 CIDRs||None added|
|VPC routing mode|✓|GLOBAL|
|Default internet route|✓|Deleted; VPC will not route to internet|
|Restricted API route|✓|A route for restricted Google API endpoints is added|
|Private API route||None added|
|MTU|✓|1460|
|Cloud NAT||Not enabled|
|*Restricted Google API DNS zone(s)*||*Not managed by this module; see [restricted-apis-dns]*|
|*Bastion*||*Not managed by this module; see [private-bastion]*|
```hcl
module "vpc" {
source = "memes/multi-region-private-network/google"
version = "5.0.0"
project_id = "my-project-id"
regions = ["us-west1", "us-east1"]
options = {
ipv6_ula = true
}
}
```
### Dual region (us-west1 and us-east1) with explicit IPv6 CIDR
|Item|Enable/managed by module|Description|
|----|-----------------|-----------|
|Regions|✓|`us-west1` and `us-east1`|
|Primary IPv4 CIDR|✓|`172.16.0.0/12` (`/24` per region)|
|Primary IPv6 CIDR|✓|`fd20:0:0309:0:0:0:0:0/48` (`/64` per region)|
|Secondary IPv4 CIDRs||None added|
|VPC routing mode|✓|GLOBAL|
|Default internet route|✓|Deleted; VPC will not route to internet|
|Restricted API route|✓|A route for restricted Google API endpoints is added|
|MTU|✓|1460|
|Cloud NAT||Not enabled|
|*Restricted Google API DNS zone(s)*||*Not managed by this module; see [restricted-apis-dns]*|
|*Bastion*||*Not managed by this module; see [private-bastion]*|
```hcl
module "vpc" {
source = "memes/multi-region-private-network/google"
version = "5.0.0"
project_id = "my-project-id"
regions = ["us-west1", "us-east1"]
cidrs = {
primary_ipv6_cidr = "fd20:0:0309:0:0:0:0:0/48"
}
options = {
ipv6_ula = true
}
}
```
### Dual region (us-west1 and us-east1) with Private Google APIs access
|Item|Enabled/managed by module|Description|
|----|-----------------|-----------|
|Regions|✓|`us-west1` and `us-east1`|
|Primary IPv4 CIDR|✓|`172.16.0.0/12` (`/24` per region)|
|Primary IPv6 CIDR||Not enabled|
|Secondary IPv4 CIDRs||Not enabled|
|VPC routing mode|✓|GLOBAL|
|Default internet route|✓|Deleted; VPC will not route to internet|
|Restricted API route||None added|
|Private API route|✓|A route for private Google API endpoints is added|
|MTU|✓|1460|
|Cloud NAT||Not enabled|
|*Private Google API DNS zone(s)*||*Not managed by this module; see [restricted-apis-dns]*|
|*Bastion*||*Not managed by this module; see [private-bastion]*|
```hcl
module "vpc" {
source = "memes/multi-region-private-network/google"
version = "5.0.0"
project_id = "my-project-id"
regions = ["us-west1", "us-east1"]
options = {
enable_restricted_apis_access = false
}
}
```
### Dual region (us-west1 and us-east1) with Restricted Google APIs access via PSC
|Item|Enabled/managed by module|Description|
|----|-----------------|-----------|
|Regions|✓|`us-west1` and `us-east1`|
|Primary IPv4 CIDR|✓|`172.16.0.0/12` (`/24` per region)|
|Primary IPv6 CIDR||Not enabled|
|Secondary IPv4 CIDRs||Not enabled|
|VPC routing mode|✓|GLOBAL|
|Default internet route|✓|Deleted; VPC will not route to internet|
|Restricted API route|✓|A route for restricted Google API endpoints is added|
|Private API route|✓|A route for private Google API endpoints is added|
|MTU|✓|1460|
|Cloud NAT||Not enabled|
|PSC||`10.10.10.10`|
|*Restricted and Private Google API DNS zone(s)*||*Not managed by this module; see [restricted-apis-dns]*|
|*Bastion*||*Not managed by this module; see [private-bastion]*|
```hcl
module "vpc" {
source = "memes/multi-region-private-network/google"
version = "5.0.0"
project_id = "my-project-id"
regions = ["us-west1", "us-east1"]
psc = {
address = "10.10.10.10"
}
}
```
## Requirements
| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.5 |
| [google](#requirement\_google) | >= 7.1 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| [regions](#module\_regions) | memes/region-detail/google | 1.1.7 |
## Resources
| Name | Type |
|------|------|
| [google_compute_global_address.psc](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_global_address) | resource |
| [google_compute_global_forwarding_rule.psc](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_global_forwarding_rule) | resource |
| [google_compute_network.network](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_network) | resource |
| [google_compute_route.apis](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_route) | resource |
| [google_compute_route.tagged_nat](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_route) | resource |
| [google_compute_router.nat](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_router) | resource |
| [google_compute_router_nat.nat](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_router_nat) | resource |
| [google_compute_subnetwork.subnet](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_subnetwork) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| [project\_id](#input\_project\_id) | The GCP project identifier where the VPC network will be created. | `string` | n/a | yes |
| [regions](#input\_regions) | The list of Compute Engine regions in which to create the VPC subnetworks. | `list(string)` | n/a | yes |
| [cidrs](#input\_cidrs) | Sets the primary IPv4 CIDR and regional subnet size to use with the network, an optional IPv6 ULA CIDR to use with the
network, and any optional secondary IPv4 CIDRs and sizes. |
object({
primary_ipv4_cidr = optional(string, "172.16.0.0/12")
primary_ipv4_subnet_size = optional(number, 24)
primary_ipv4_subnet_offset = optional(number, 0)
primary_ipv4_subnet_step = optional(number, 1)
primary_ipv6_cidr = optional(string, null)
secondaries = optional(map(object({
ipv4_cidr = string
ipv4_subnet_size = optional(number, 24)
ipv4_subnet_offset = optional(number, 0)
ipv4_subnet_step = optional(number, 1)
})), null)
}) | {
"primary_ipv4_cidr": "172.16.0.0/12",
"primary_ipv4_subnet_offset": 0,
"primary_ipv4_subnet_size": 24,
"primary_ipv4_subnet_step": 1,
"primary_ipv6_cidr": null,
"secondaries": null
} | no |
| [description](#input\_description) | A descriptive value to apply to the VPC network. Default value is 'custom vpc'. | `string` | `"custom vpc"` | no |
| [flow\_logs](#input\_flow\_logs) | If not null, enable flow log collection in Cloud Logging using the provided parameters. If null (default), flow log
collection will be disabled. | object({
aggregation_interval = optional(string, "INTERVAL_5_SEC")
flow_sampling = optional(number, 0.5)
metadata = optional(string, "INCLUDE_ALL_METADATA")
metadata_fields = optional(set(string), [])
filter_expr = optional(string, "true")
}) | `null` | no |
| [labels](#input\_labels) | An optional map of key:value labels to apply to the resources. Default value is an empty map. | `map(string)` | `{}` | no |
| [name](#input\_name) | The name to use when naming resources managed by this module. Must be RFC1035 compliant and between 1 and 55 characters
in length, inclusive. | `string` | `"restricted"` | no |
| [nat](#input\_nat) | If not null, Cloud NAT instances and supporting Cloud Routers will be added to each subnet along with supporting
routes with tags, if applicable. Log collection is controlled by the presence of a non empty logging\_filter field. | object({
tags = optional(set(string), [])
logging_filter = optional(string, null)
}) | `null` | no |
| [options](#input\_options) | The set of options to use when creating the VPC network. The default value will create a VPC network with MTU of 1460,
GLOBAL routing mode, and IPv6 ULA disabled. Default routes (0.0.0.0/0, ::0) to the default gateway are deleted; routes
will be added to support Restricted (default) or Private Google APIs access unless PSC for Google APIs is enabled
through the `psc` variable. | object({
mtu = optional(number, 1460)
delete_default_routes = optional(bool, true)
enable_restricted_apis_access = optional(bool, true)
regional_routing_mode = optional(bool, false)
ipv6_ula = optional(bool, false)
}) | {
"delete_default_routes": true,
"enable_restricted_apis_access": true,
"ipv6_ula": false,
"mtu": 1460,
"regional_routing_mode": false
} | no |
| [psc](#input\_psc) | If set, create a Private Service Connect for Google APIs resource to provide Private or Restricted Google APIs access
via a PSC in the VPC. If a valid service\_directory field is present automatic DNS registration via Service Directory
will be activated. The value of `options.enable_restricted_apis_access` determines if the PSC will be to Restricted
(default) or Private Google APIs bundle. | object({
address = string
service_directory = optional(object({
namespace = string
region = string
}), null)
name = optional(string)
description = optional(string)
}) | `null` | no |
## Outputs
| Name | Description |
|------|-------------|
| [id](#output\_id) | The qualified id of the created VPC network. |
| [self\_link](#output\_self\_link) | The fully-qualified self-link URI of the created VPC network. |
| [subnets\_by\_name](#output\_subnets\_by\_name) | A map of subnet name to region, self\_link, and CIDRs. |
| [subnets\_by\_region](#output\_subnets\_by\_region) | A map of subnet region to name, self\_link, and CIDRs. |
[network]: https://registry.terraform.io/modules/terraform-google-modules/network/google/latest?tab=readme
[restricted-apis-dns]: https://registry.terraform.io/modules/memes/restricted-apis-dns/google/latest?tab=readme
[private-bastion]: https://registry.terraform.io/modules/memes/private-bastion/google/latest?tab=readme