Simplify VPN implementation in FAST networking stages (#1228)
* peering stage * fix link, toc * vpn stage * fix link * nva stage * fix examples and test * separate envs stage * tfdoc
This commit is contained in:
parent
1b7864af2e
commit
be06554bba
|
@ -40,6 +40,7 @@ The following diagram illustrates the high-level design, and should be used as a
|
|||
- [Post-deployment activities](#post-deployment-activities)
|
||||
- [Customizations](#customizations)
|
||||
- [Changing default regions](#changing-default-regions)
|
||||
- [Configuring the VPN to on prem](#configuring-the-vpn-to-on-prem)
|
||||
- [Adding an environment](#adding-an-environment)
|
||||
|
||||
## Design overview and choices
|
||||
|
@ -164,7 +165,7 @@ Subnets for [L7 ILBs](https://cloud.google.com/load-balancing/docs/l7-internal/p
|
|||
|
||||
### VPNs
|
||||
|
||||
Connectivity to on-prem is implemented with HA VPN ([`net-vpn`](../../../modules/net-vpn-ha)) and defined in [`vpn-onprem.tf`](./vpn-onprem.tf). The file provisionally implements a single logical connection between onprem and landing at `europe-west1`, and the relevant parameters for its configuration are found in variable `vpn_onprem_configs`.
|
||||
Connectivity to on-prem is implemented with HA VPN ([`net-vpn`](../../../modules/net-vpn-ha)) and defined in [`vpn-onprem.tf`](./vpn-onprem.tf). The file provisionally implements a single logical connection between onprem and landing at `europe-west1`, and the relevant parameters for its configuration are found in variable `vpn_onprem_primary_configs`. An example configuration is provided [below](#configuring-the-vpn-to-on-prem).
|
||||
|
||||
### Routing and BGP
|
||||
|
||||
|
@ -302,6 +303,55 @@ Regions are defined via the `regions` variable which sets up a mapping between t
|
|||
- change the values of the mappings in the `regions` variable to the regions you are going to use
|
||||
- change the regions in the factory subnet files in the `data` folder
|
||||
|
||||
### Configuring the VPN to on prem
|
||||
|
||||
This stage includes basic support for an HA VPN connecting the landing zone in the primary region to on prem. Configuration is via the `vpn_onprem_primary_config` variable, that closely mirrors the variables defined in the [`net-vpn-ha`](../../../modules/net-vpn-ha/).
|
||||
|
||||
Support for the onprem VPN is disabled by default so that no resources are created, this is an example of how to configure the variable to enable the VPN:
|
||||
|
||||
```hcl
|
||||
vpn_onprem_primary_config = {
|
||||
peer_external_gateways = {
|
||||
default = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
}
|
||||
router_config = {
|
||||
asn = 65501
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
"10.1.0.0/16" = "gcp"
|
||||
"35.199.192.0/19" = "gcp-dns"
|
||||
"199.36.153.4/30" = "gcp-restricted"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
"0" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.1"
|
||||
asn = 65500
|
||||
}
|
||||
bgp_session_range = "169.254.1.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
"1" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.2.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest skip
|
||||
```
|
||||
|
||||
### Adding an environment
|
||||
|
||||
To create a new environment (e.g. `staging`), a few changes are required.
|
||||
|
@ -346,20 +396,18 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L92) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L102) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L118) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [custom_adv](variables.tf#L38) | Custom advertisement definitions in name => range format. | <code>map(string)</code> | | <code title="{ cloud_dns = "35.199.192.0/19" gcp_all = "10.128.0.0/16" gcp_dev = "10.128.32.0/19" gcp_landing = "10.128.0.0/19" gcp_prod = "10.128.64.0/19" googleapis_private = "199.36.153.8/30" googleapis_restricted = "199.36.153.4/30" rfc_1918_10 = "10.0.0.0/8" rfc_1918_172 = "172.16.0.0/12" rfc_1918_192 = "192.168.0.0/16" }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L55) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L64) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L72) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") firewall_policy_name = optional(string, "factory") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L112) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L85) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L101) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L47) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") firewall_policy_name = optional(string, "factory") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L95) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [peering_configs](variables-peerings.tf#L19) | Peering configurations. | <code title="map(object({ export_local_custom_routes = bool export_peer_custom_routes = bool }))">map(object({…}))</code> | | <code title="{ dev = { export_local_custom_routes = true export_peer_custom_routes = true } prod = { export_local_custom_routes = true export_peer_custom_routes = true } }">{…}</code> | |
|
||||
| [psa_ranges](variables.tf#L129) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code title="object({ dev = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) prod = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L166) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [router_onprem_configs](variables.tf#L178) | Configurations for routers used for onprem connectivity. | <code title="map(object({ adv = object({ custom = list(string) default = bool }) asn = number }))">map(object({…}))</code> | | <code title="{ landing-primary = { asn = "65533" adv = null } }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L196) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_configs](variables.tf#L210) | VPN gateway configuration for onprem interconnection. | <code title="map(object({ adv = object({ default = bool custom = list(string) }) peer_external_gateway = object({ redundancy_type = string interfaces = list(string) }) tunnels = list(object({ peer_asn = number peer_external_gateway_interface = number secret = string session_range = string vpn_gateway_interface = number })) }))">map(object({…}))</code> | | <code title="{ landing-primary = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = ["8.8.8.8"] } tunnels = [ { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } }">{…}</code> | |
|
||||
| [psa_ranges](variables.tf#L112) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object({ dev = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) prod = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L133) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L145) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L159) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ output "tfvars" {
|
|||
|
||||
output "vpn_gateway_endpoints" {
|
||||
description = "External IP Addresses for the GCP VPN gateways."
|
||||
value = local.enable_onprem_vpn == false ? null : {
|
||||
value = var.vpn_onprem_primary_config == null ? null : {
|
||||
onprem-primary = {
|
||||
for v in module.landing-to-onprem-primary-vpn[0].gateway.vpn_interfaces :
|
||||
v.id => v.ip_address
|
||||
|
|
|
@ -35,23 +35,6 @@ variable "billing_account" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "custom_adv" {
|
||||
description = "Custom advertisement definitions in name => range format."
|
||||
type = map(string)
|
||||
default = {
|
||||
cloud_dns = "35.199.192.0/19"
|
||||
gcp_all = "10.128.0.0/16"
|
||||
gcp_dev = "10.128.32.0/19"
|
||||
gcp_landing = "10.128.0.0/19"
|
||||
gcp_prod = "10.128.64.0/19"
|
||||
googleapis_private = "199.36.153.8/30"
|
||||
googleapis_restricted = "199.36.153.4/30"
|
||||
rfc_1918_10 = "10.0.0.0/8"
|
||||
rfc_1918_172 = "172.16.0.0/12"
|
||||
rfc_1918_192 = "192.168.0.0/16"
|
||||
}
|
||||
}
|
||||
|
||||
variable "custom_roles" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Custom roles defined at the org level, in key => id format."
|
||||
|
@ -127,7 +110,7 @@ variable "prefix" {
|
|||
}
|
||||
|
||||
variable "psa_ranges" {
|
||||
description = "IP ranges used for Private Service Access (e.g. CloudSQL)."
|
||||
description = "IP ranges used for Private Service Access (CloudSQL, etc.)."
|
||||
type = object({
|
||||
dev = object({
|
||||
ranges = map(string)
|
||||
|
@ -145,22 +128,6 @@ variable "psa_ranges" {
|
|||
})
|
||||
})
|
||||
default = null
|
||||
# default = {
|
||||
# dev = {
|
||||
# ranges = {
|
||||
# cloudsql-mysql = "10.128.62.0/24"
|
||||
# cloudsql-sqlserver = "10.128.63.0/24"
|
||||
# }
|
||||
# routes = null
|
||||
# }
|
||||
# prod = {
|
||||
# ranges = {
|
||||
# cloudsql-mysql = "10.128.94.0/24"
|
||||
# cloudsql-sqlserver = "10.128.95.0/24"
|
||||
# }
|
||||
# routes = null
|
||||
# }
|
||||
# }
|
||||
}
|
||||
|
||||
variable "regions" {
|
||||
|
@ -175,24 +142,6 @@ variable "regions" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "router_onprem_configs" {
|
||||
description = "Configurations for routers used for onprem connectivity."
|
||||
type = map(object({
|
||||
adv = object({
|
||||
custom = list(string)
|
||||
default = bool
|
||||
})
|
||||
asn = number
|
||||
}))
|
||||
default = {
|
||||
landing-primary = {
|
||||
asn = "65533"
|
||||
adv = null
|
||||
# adv = { default = false, custom = [] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "service_accounts" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Automation service accounts in name => email format."
|
||||
|
@ -207,53 +156,45 @@ variable "service_accounts" {
|
|||
default = null
|
||||
}
|
||||
|
||||
variable "vpn_onprem_configs" {
|
||||
description = "VPN gateway configuration for onprem interconnection."
|
||||
type = map(object({
|
||||
adv = object({
|
||||
default = bool
|
||||
custom = list(string)
|
||||
})
|
||||
peer_external_gateway = object({
|
||||
variable "vpn_onprem_primary_config" {
|
||||
description = "VPN gateway configuration for onprem interconnection in the primary region."
|
||||
type = object({
|
||||
peer_external_gateways = map(object({
|
||||
redundancy_type = string
|
||||
interfaces = list(string)
|
||||
}))
|
||||
router_config = object({
|
||||
create = optional(bool, true)
|
||||
asn = number
|
||||
name = optional(string)
|
||||
keepalive = optional(number)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
tunnels = list(object({
|
||||
peer_asn = number
|
||||
peer_external_gateway_interface = number
|
||||
secret = string
|
||||
session_range = string
|
||||
tunnels = map(object({
|
||||
bgp_peer = object({
|
||||
address = string
|
||||
asn = number
|
||||
route_priority = optional(number, 1000)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
all_vpc_subnets = bool
|
||||
all_peer_vpc_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
# each BGP session on the same Cloud Router must use a unique /30 CIDR
|
||||
# from the 169.254.0.0/16 block.
|
||||
bgp_session_range = string
|
||||
ike_version = optional(number, 2)
|
||||
peer_external_gateway_interface = optional(number)
|
||||
peer_gateway = optional(string, "default")
|
||||
router = optional(string)
|
||||
shared_secret = optional(string)
|
||||
vpn_gateway_interface = number
|
||||
}))
|
||||
}))
|
||||
default = {
|
||||
landing-primary = {
|
||||
adv = {
|
||||
default = false
|
||||
custom = [
|
||||
"cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all"
|
||||
]
|
||||
}
|
||||
peer_external_gateway = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
tunnels = [
|
||||
{
|
||||
peer_asn = 65534
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.0/30"
|
||||
vpn_gateway_interface = 0
|
||||
},
|
||||
{
|
||||
peer_asn = 65534
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.4/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
|
|
@ -17,54 +17,21 @@
|
|||
# tfdoc:file:description VPN between landing and onprem.
|
||||
|
||||
locals {
|
||||
enable_onprem_vpn = var.vpn_onprem_configs != null
|
||||
bgp_peer_options_onprem = local.enable_onprem_vpn == false ? null : {
|
||||
for k, v in var.vpn_onprem_configs :
|
||||
k => v.adv == null ? null : {
|
||||
advertise_groups = []
|
||||
advertise_ip_ranges = {
|
||||
for adv in(v.adv == null ? [] : v.adv.custom) :
|
||||
var.custom_adv[adv] => adv
|
||||
}
|
||||
advertise_mode = try(v.adv.default, false) ? "DEFAULT" : "CUSTOM"
|
||||
route_priority = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moved {
|
||||
from = module.landing-to-onprem-ew1-vpn
|
||||
to = module.landing-to-onprem-primary-vpn
|
||||
onprem_peer_gateways = try(
|
||||
var.vpn_onprem_primary_config.peer_external_gateways, {}
|
||||
)
|
||||
}
|
||||
|
||||
module "landing-to-onprem-primary-vpn" {
|
||||
count = local.enable_onprem_vpn ? 1 : 0
|
||||
count = var.vpn_onprem_primary_config == null ? 0 : 1
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.landing-project.project_id
|
||||
network = module.landing-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-onprem-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = {
|
||||
name = "landing-onprem-vpn-${local.region_shortnames[var.regions.primary]}"
|
||||
asn = var.router_onprem_configs.landing-primary.asn
|
||||
}
|
||||
router_config = try(var.vpn_onprem_primary_config.router_config, {})
|
||||
peer_gateways = {
|
||||
default = {
|
||||
external = var.vpn_onprem_configs.landing-primary.peer_external_gateway
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
for t in var.vpn_onprem_configs.landing-primary.tunnels :
|
||||
"remote-${t.vpn_gateway_interface}-${t.peer_external_gateway_interface}" => {
|
||||
bgp_peer = {
|
||||
address = cidrhost(t.session_range, 1)
|
||||
asn = t.peer_asn
|
||||
}
|
||||
bgp_peer_options = local.bgp_peer_options_onprem.landing-primary
|
||||
bgp_session_range = "${cidrhost(t.session_range, 2)}/30"
|
||||
peer_external_gateway_interface = t.peer_external_gateway_interface
|
||||
shared_secret = t.secret
|
||||
vpn_gateway_interface = t.vpn_gateway_interface
|
||||
}
|
||||
for k, v in local.onprem_peer_gateways : k => { external = v }
|
||||
}
|
||||
tunnels = try(var.vpn_onprem_primary_config.tunnels, {})
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ The following diagram illustrates the high-level design, and should be used as a
|
|||
- [Post-deployment activities](#post-deployment-activities)
|
||||
- [Customizations](#customizations)
|
||||
- [Changing default regions](#changing-default-regions)
|
||||
- [Configuring the VPN to on prem](#configuring-the-vpn-to-on-prem)
|
||||
- [Adding an environment](#adding-an-environment)
|
||||
|
||||
## Design overview and choices
|
||||
|
@ -172,7 +173,7 @@ Subnets for [L7 ILBs](https://cloud.google.com/load-balancing/docs/l7-internal/p
|
|||
|
||||
#### External
|
||||
|
||||
Connectivity to on-prem is implemented with HA VPN ([`net-vpn`](../../../modules/net-vpn-ha)) and defined in [`vpn-onprem.tf`](./vpn-onprem.tf). The file provisionally implements a single logical connection between onprem and landing at `europe-west1`, and the relevant parameters for its configuration are found in variable `vpn_onprem_configs`.
|
||||
Connectivity to on-prem is implemented with HA VPN ([`net-vpn`](../../../modules/net-vpn-ha)) and defined in [`vpn-onprem.tf`](./vpn-onprem.tf). The file provisionally implements a single logical connection between onprem and landing at `europe-west1`, and the relevant parameters for its configuration are found in variable `vpn_onprem_primary_configs`. An example configuration is provided [below](#configuring-the-vpn-to-on-prem).
|
||||
|
||||
#### Internal
|
||||
|
||||
|
@ -316,6 +317,55 @@ Regions are defined via the `regions` variable which sets up a mapping between t
|
|||
- change the values of the mappings in the `regions` variable to the regions you are going to use
|
||||
- change the regions in the factory subnet files in the `data` folder
|
||||
|
||||
### Configuring the VPN to on prem
|
||||
|
||||
This stage includes basic support for an HA VPN connecting the landing zone in the primary region to on prem. Configuration is via the `vpn_onprem_primary_config` variable, that closely mirrors the variables defined in the [`net-vpn-ha`](../../../modules/net-vpn-ha/).
|
||||
|
||||
Support for the onprem VPN is disabled by default so that no resources are created, this is an example of how to configure the variable to enable the VPN:
|
||||
|
||||
```hcl
|
||||
vpn_onprem_primary_config = {
|
||||
peer_external_gateways = {
|
||||
default = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
}
|
||||
router_config = {
|
||||
asn = 65501
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
"10.1.0.0/16" = "gcp"
|
||||
"35.199.192.0/19" = "gcp-dns"
|
||||
"199.36.153.4/30" = "gcp-restricted"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
"0" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.1"
|
||||
asn = 65500
|
||||
}
|
||||
bgp_session_range = "169.254.1.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
"1" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.2.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest skip
|
||||
```
|
||||
|
||||
### Adding an environment
|
||||
|
||||
To create a new environment (e.g. `staging`), a few changes are required.
|
||||
|
@ -360,10 +410,10 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
| [test-resources.tf](./test-resources.tf) | temporary instances for testing | <code>compute-vm</code> | |
|
||||
| [variables-vpn.tf](./variables-vpn.tf) | None | | |
|
||||
| [variables.tf](./variables.tf) | Module variables. | | |
|
||||
| [vpn-landing.tf](./vpn-landing.tf) | None | <code>net-vpn-ha</code> | |
|
||||
| [vpn-onprem.tf](./vpn-onprem.tf) | VPN between landing and onprem. | <code>net-vpn-ha</code> | |
|
||||
| [vpn-spoke-dev.tf](./vpn-spoke-dev.tf) | VPN between landing and development spoke. | <code>net-vpn-ha</code> | |
|
||||
| [vpn-spoke-prod-primary.tf](./vpn-spoke-prod-primary.tf) | VPN between landing and production spoke in ew1. | <code>net-vpn-ha</code> | |
|
||||
| [vpn-spoke-prod-secondary.tf](./vpn-spoke-prod-secondary.tf) | VPN between landing and production spoke in ew4. | <code>net-vpn-ha</code> | |
|
||||
| [vpn-spoke-prod.tf](./vpn-spoke-prod.tf) | VPN between landing and production spoke in ew1. | <code>net-vpn-ha</code> | |
|
||||
|
||||
## Variables
|
||||
|
||||
|
@ -371,21 +421,18 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L92) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L102) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L118) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [custom_adv](variables.tf#L38) | Custom advertisement definitions in name => range format. | <code>map(string)</code> | | <code title="{ cloud_dns = "35.199.192.0/19" gcp_all = "10.128.0.0/16" gcp_dev = "10.128.32.0/19" gcp_landing = "10.128.0.0/19" gcp_prod = "10.128.64.0/19" googleapis_private = "199.36.153.8/30" googleapis_restricted = "199.36.153.4/30" rfc_1918_10 = "10.0.0.0/8" rfc_1918_172 = "172.16.0.0/12" rfc_1918_192 = "192.168.0.0/16" }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L55) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L64) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L72) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") firewall_policy_name = optional(string, "factory") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L112) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L129) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code title="object({ dev = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) prod = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L166) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [router_onprem_configs](variables.tf#L178) | Configurations for routers used for onprem connectivity. | <code title="map(object({ adv = object({ custom = list(string) default = bool }) asn = number }))">map(object({…}))</code> | | <code title="{ landing-primary = { asn = "65533" adv = null } }">{…}</code> | |
|
||||
| [router_spoke_configs](variables-vpn.tf#L18) | Configurations for routers used for internal connectivity. | <code title="map(object({ adv = object({ custom = list(string) default = bool }) asn = number }))">map(object({…}))</code> | | <code title="{ landing-primary = { asn = "64512", adv = null } landing-secondary = { asn = "64512", adv = null } spoke-dev-primary = { asn = "64513", adv = null } spoke-dev-secondary = { asn = "64513", adv = null } spoke-prod-primary = { asn = "64514", adv = null } spoke-prod-secondary = { asn = "64514", adv = null } }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L196) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_configs](variables.tf#L210) | VPN gateway configuration for onprem interconnection. | <code title="map(object({ adv = object({ default = bool custom = list(string) }) peer_external_gateway = object({ redundancy_type = string interfaces = list(string) }) tunnels = list(object({ peer_asn = number peer_external_gateway_interface = number secret = string session_range = string vpn_gateway_interface = number })) }))">map(object({…}))</code> | | <code title="{ landing-primary = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = ["8.8.8.8"] } tunnels = [ { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } }">{…}</code> | |
|
||||
| [vpn_spoke_configs](variables-vpn.tf#L37) | VPN gateway configuration for spokes. | <code title="map(object({ default = bool custom = list(string) }))">map(object({…}))</code> | | <code title="{ landing-primary = { default = false custom = ["rfc_1918_10", "rfc_1918_172", "rfc_1918_192"] } landing-secondary = { default = false custom = ["rfc_1918_10", "rfc_1918_172", "rfc_1918_192"] } dev-primary = { default = false custom = ["gcp_dev"] } prod-primary = { default = false custom = ["gcp_prod"] } prod-secondary = { default = false custom = ["gcp_prod"] } }">{…}</code> | |
|
||||
| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L85) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L101) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L47) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") firewall_policy_name = optional(string, "factory") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L95) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L112) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object({ dev = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) prod = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L133) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L145) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_configs](variables-vpn.tf#L17) | Hub to spokes VPN configurations. | <code title="object({ dev = object({ asn = number custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) landing = object({ asn = number custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) prod = object({ asn = number custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) })">object({…})</code> | | <code title="{ dev = { asn = 65501 } landing = { asn = 65500 } prod = { asn = 65502 } }">{…}</code> | |
|
||||
| [vpn_onprem_primary_config](variables.tf#L159) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ output "tfvars" {
|
|||
|
||||
output "vpn_gateway_endpoints" {
|
||||
description = "External IP Addresses for the GCP VPN gateways."
|
||||
value = local.enable_onprem_vpn == false ? null : {
|
||||
value = var.vpn_onprem_primary_config == null ? null : {
|
||||
onprem-primary = {
|
||||
for v in module.landing-to-onprem-primary-vpn[0].gateway.vpn_interfaces :
|
||||
v.id => v.ip_address
|
||||
|
|
|
@ -14,52 +14,40 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
variable "router_spoke_configs" {
|
||||
description = "Configurations for routers used for internal connectivity."
|
||||
type = map(object({
|
||||
adv = object({
|
||||
custom = list(string)
|
||||
default = bool
|
||||
})
|
||||
variable "vpn_configs" {
|
||||
description = "Hub to spokes VPN configurations."
|
||||
type = object({
|
||||
dev = object({
|
||||
asn = number
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
default = {
|
||||
landing-primary = { asn = "64512", adv = null }
|
||||
landing-secondary = { asn = "64512", adv = null }
|
||||
spoke-dev-primary = { asn = "64513", adv = null }
|
||||
spoke-dev-secondary = { asn = "64513", adv = null }
|
||||
spoke-prod-primary = { asn = "64514", adv = null }
|
||||
spoke-prod-secondary = { asn = "64514", adv = null }
|
||||
}
|
||||
}
|
||||
|
||||
variable "vpn_spoke_configs" {
|
||||
description = "VPN gateway configuration for spokes."
|
||||
type = map(object({
|
||||
default = bool
|
||||
custom = list(string)
|
||||
})
|
||||
landing = object({
|
||||
asn = number
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
prod = object({
|
||||
asn = number
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
})
|
||||
default = {
|
||||
landing-primary = {
|
||||
default = false
|
||||
custom = ["rfc_1918_10", "rfc_1918_172", "rfc_1918_192"]
|
||||
dev = {
|
||||
asn = 65501
|
||||
}
|
||||
landing-secondary = {
|
||||
default = false
|
||||
custom = ["rfc_1918_10", "rfc_1918_172", "rfc_1918_192"]
|
||||
landing = {
|
||||
asn = 65500
|
||||
}
|
||||
dev-primary = {
|
||||
default = false
|
||||
custom = ["gcp_dev"]
|
||||
}
|
||||
prod-primary = {
|
||||
default = false
|
||||
custom = ["gcp_prod"]
|
||||
}
|
||||
prod-secondary = {
|
||||
default = false
|
||||
custom = ["gcp_prod"]
|
||||
prod = {
|
||||
asn = 65502
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,23 +35,6 @@ variable "billing_account" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "custom_adv" {
|
||||
description = "Custom advertisement definitions in name => range format."
|
||||
type = map(string)
|
||||
default = {
|
||||
cloud_dns = "35.199.192.0/19"
|
||||
gcp_all = "10.128.0.0/16"
|
||||
gcp_dev = "10.128.32.0/19"
|
||||
gcp_landing = "10.128.0.0/19"
|
||||
gcp_prod = "10.128.64.0/19"
|
||||
googleapis_private = "199.36.153.8/30"
|
||||
googleapis_restricted = "199.36.153.4/30"
|
||||
rfc_1918_10 = "10.0.0.0/8"
|
||||
rfc_1918_172 = "172.16.0.0/12"
|
||||
rfc_1918_192 = "192.168.0.0/16"
|
||||
}
|
||||
}
|
||||
|
||||
variable "custom_roles" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Custom roles defined at the org level, in key => id format."
|
||||
|
@ -127,7 +110,7 @@ variable "prefix" {
|
|||
}
|
||||
|
||||
variable "psa_ranges" {
|
||||
description = "IP ranges used for Private Service Access (e.g. CloudSQL)."
|
||||
description = "IP ranges used for Private Service Access (CloudSQL, etc.)."
|
||||
type = object({
|
||||
dev = object({
|
||||
ranges = map(string)
|
||||
|
@ -145,22 +128,6 @@ variable "psa_ranges" {
|
|||
})
|
||||
})
|
||||
default = null
|
||||
# default = {
|
||||
# dev = {
|
||||
# ranges = {
|
||||
# cloudsql-mysql = "10.128.62.0/24"
|
||||
# cloudsql-sqlserver = "10.128.63.0/24"
|
||||
# }
|
||||
# routes = null
|
||||
# }
|
||||
# prod = {
|
||||
# ranges = {
|
||||
# cloudsql-mysql = "10.128.94.0/24"
|
||||
# cloudsql-sqlserver = "10.128.95.0/24"
|
||||
# }
|
||||
# routes = null
|
||||
# }
|
||||
# }
|
||||
}
|
||||
|
||||
variable "regions" {
|
||||
|
@ -175,24 +142,6 @@ variable "regions" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "router_onprem_configs" {
|
||||
description = "Configurations for routers used for onprem connectivity."
|
||||
type = map(object({
|
||||
adv = object({
|
||||
custom = list(string)
|
||||
default = bool
|
||||
})
|
||||
asn = number
|
||||
}))
|
||||
default = {
|
||||
landing-primary = {
|
||||
asn = "65533"
|
||||
adv = null
|
||||
# adv = { default = false, custom = [] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "service_accounts" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Automation service accounts in name => email format."
|
||||
|
@ -207,53 +156,45 @@ variable "service_accounts" {
|
|||
default = null
|
||||
}
|
||||
|
||||
variable "vpn_onprem_configs" {
|
||||
description = "VPN gateway configuration for onprem interconnection."
|
||||
type = map(object({
|
||||
adv = object({
|
||||
default = bool
|
||||
custom = list(string)
|
||||
})
|
||||
peer_external_gateway = object({
|
||||
variable "vpn_onprem_primary_config" {
|
||||
description = "VPN gateway configuration for onprem interconnection in the primary region."
|
||||
type = object({
|
||||
peer_external_gateways = map(object({
|
||||
redundancy_type = string
|
||||
interfaces = list(string)
|
||||
}))
|
||||
router_config = object({
|
||||
create = optional(bool, true)
|
||||
asn = number
|
||||
name = optional(string)
|
||||
keepalive = optional(number)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
tunnels = list(object({
|
||||
peer_asn = number
|
||||
peer_external_gateway_interface = number
|
||||
secret = string
|
||||
session_range = string
|
||||
tunnels = map(object({
|
||||
bgp_peer = object({
|
||||
address = string
|
||||
asn = number
|
||||
route_priority = optional(number, 1000)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
all_vpc_subnets = bool
|
||||
all_peer_vpc_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
# each BGP session on the same Cloud Router must use a unique /30 CIDR
|
||||
# from the 169.254.0.0/16 block.
|
||||
bgp_session_range = string
|
||||
ike_version = optional(number, 2)
|
||||
peer_external_gateway_interface = optional(number)
|
||||
peer_gateway = optional(string, "default")
|
||||
router = optional(string)
|
||||
shared_secret = optional(string)
|
||||
vpn_gateway_interface = number
|
||||
}))
|
||||
}))
|
||||
default = {
|
||||
landing-primary = {
|
||||
adv = {
|
||||
default = false
|
||||
custom = [
|
||||
"cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all"
|
||||
]
|
||||
}
|
||||
peer_external_gateway = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
tunnels = [
|
||||
{
|
||||
peer_asn = 65534
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.0/30"
|
||||
vpn_gateway_interface = 0
|
||||
},
|
||||
{
|
||||
peer_asn = 65534
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.4/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/**
|
||||
* 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 {
|
||||
# persistent_counter.units.values[k]
|
||||
bgp_sessions_range_0 = "169.254.250.0/25"
|
||||
bgp_sessions_range_1 = "169.254.250.128/25"
|
||||
bgp_session_ranges = {
|
||||
prod-primary = {
|
||||
0 = cidrsubnet(local.bgp_sessions_range_0, 5, 0)
|
||||
1 = cidrsubnet(local.bgp_sessions_range_1, 5, 0)
|
||||
}
|
||||
prod-secondary = {
|
||||
0 = cidrsubnet(local.bgp_sessions_range_0, 5, 1)
|
||||
1 = cidrsubnet(local.bgp_sessions_range_1, 5, 1)
|
||||
}
|
||||
dev-primary = {
|
||||
0 = cidrsubnet(local.bgp_sessions_range_0, 5, 2)
|
||||
1 = cidrsubnet(local.bgp_sessions_range_1, 5, 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output "foo" {
|
||||
value = local.bgp_session_ranges
|
||||
}
|
||||
|
||||
module "landing-to-spokes-primary-vpn" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.landing-project.project_id
|
||||
network = module.landing-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "to-spokes-${local.region_shortnames[var.regions.primary]}"
|
||||
peer_gateways = {
|
||||
dev = { gcp = module.dev-to-landing-primary-vpn.self_link }
|
||||
prod = { gcp = module.prod-to-landing-primary-vpn.self_link }
|
||||
}
|
||||
router_config = {
|
||||
asn = var.vpn_configs.landing.asn
|
||||
custom_advertise = var.vpn_configs.landing.custom_advertise
|
||||
}
|
||||
tunnels = {
|
||||
dev-0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost(local.bgp_session_ranges.dev-primary.0, 2)
|
||||
asn = var.vpn_configs.dev.asn
|
||||
}
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.dev-primary.0, 1)}/30"
|
||||
peer_gateway = "dev"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
dev-1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost(local.bgp_session_ranges.dev-primary.1, 2)
|
||||
asn = var.vpn_configs.dev.asn
|
||||
}
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.dev-primary.1, 1)}/30"
|
||||
peer_gateway = "dev"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
prod-0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost(local.bgp_session_ranges.prod-primary.0, 2)
|
||||
asn = var.vpn_configs.prod.asn
|
||||
}
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.prod-primary.0, 1)}/30"
|
||||
peer_gateway = "prod"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
prod-1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost(local.bgp_session_ranges.prod-primary.1, 2)
|
||||
asn = var.vpn_configs.prod.asn
|
||||
}
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.prod-primary.1, 1)}/30"
|
||||
peer_gateway = "prod"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "landing-to-spokes-secondary-vpn" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.landing-project.project_id
|
||||
network = module.landing-vpc.self_link
|
||||
region = var.regions.secondary
|
||||
name = "to-spokes-${local.region_shortnames[var.regions.secondary]}"
|
||||
peer_gateways = {
|
||||
prod = { gcp = module.prod-to-landing-secondary-vpn.self_link }
|
||||
}
|
||||
router_config = {
|
||||
asn = var.vpn_configs.landing.asn
|
||||
custom_advertise = var.vpn_configs.landing.custom_advertise
|
||||
}
|
||||
tunnels = {
|
||||
prod-0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost(local.bgp_session_ranges.prod-secondary.0, 2)
|
||||
asn = var.vpn_configs.prod.asn
|
||||
}
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.prod-secondary.0, 1)}/30"
|
||||
peer_gateway = "prod"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
prod-1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost(local.bgp_session_ranges.prod-secondary.1, 2)
|
||||
asn = var.vpn_configs.prod.asn
|
||||
}
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.prod-secondary.1, 1)}/30"
|
||||
peer_gateway = "prod"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,54 +17,21 @@
|
|||
# tfdoc:file:description VPN between landing and onprem.
|
||||
|
||||
locals {
|
||||
enable_onprem_vpn = var.vpn_onprem_configs != null
|
||||
bgp_peer_options_onprem = local.enable_onprem_vpn == false ? null : {
|
||||
for k, v in var.vpn_onprem_configs :
|
||||
k => v.adv == null ? null : {
|
||||
advertise_groups = []
|
||||
advertise_ip_ranges = {
|
||||
for adv in(v.adv == null ? [] : v.adv.custom) :
|
||||
var.custom_adv[adv] => adv
|
||||
}
|
||||
advertise_mode = try(v.adv.default, false) ? "DEFAULT" : "CUSTOM"
|
||||
route_priority = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moved {
|
||||
from = module.landing-to-onprem-ew1-vpn
|
||||
to = module.landing-to-onprem-primary-vpn
|
||||
onprem_peer_gateways = try(
|
||||
var.vpn_onprem_primary_config.peer_external_gateways, {}
|
||||
)
|
||||
}
|
||||
|
||||
module "landing-to-onprem-primary-vpn" {
|
||||
count = local.enable_onprem_vpn ? 1 : 0
|
||||
count = var.vpn_onprem_primary_config == null ? 0 : 1
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.landing-project.project_id
|
||||
network = module.landing-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-onprem-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = {
|
||||
name = "landing-onprem-vpn-${local.region_shortnames[var.regions.primary]}"
|
||||
asn = var.router_onprem_configs.landing-primary.asn
|
||||
}
|
||||
router_config = try(var.vpn_onprem_primary_config.router_config, {})
|
||||
peer_gateways = {
|
||||
default = {
|
||||
external = var.vpn_onprem_configs.landing-primary.peer_external_gateway
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
for t in var.vpn_onprem_configs.landing-primary.tunnels :
|
||||
"remote-${t.vpn_gateway_interface}-${t.peer_external_gateway_interface}" => {
|
||||
bgp_peer = {
|
||||
address = cidrhost(t.session_range, 1)
|
||||
asn = t.peer_asn
|
||||
}
|
||||
bgp_peer_options = local.bgp_peer_options_onprem.landing-primary
|
||||
bgp_session_range = "${cidrhost(t.session_range, 2)}/30"
|
||||
peer_external_gateway_interface = t.peer_external_gateway_interface
|
||||
shared_secret = t.secret
|
||||
vpn_gateway_interface = t.vpn_gateway_interface
|
||||
}
|
||||
for k, v in local.onprem_peer_gateways : k => { external = v }
|
||||
}
|
||||
tunnels = try(var.vpn_onprem_primary_config.tunnels, {})
|
||||
}
|
||||
|
|
|
@ -16,113 +16,34 @@
|
|||
|
||||
# tfdoc:file:description VPN between landing and development spoke.
|
||||
|
||||
locals {
|
||||
# define the structures used for BGP peers in the VPN resources
|
||||
vpn_spoke_bgp_peer_options = {
|
||||
for k, v in var.vpn_spoke_configs : k => v == null ? null : {
|
||||
advertise_groups = []
|
||||
advertise_ip_ranges = {
|
||||
for range in(v == null ? [] : v.custom) :
|
||||
try(var.custom_adv[range], range) => range
|
||||
}
|
||||
advertise_mode = try(v.default, false) ? "DEFAULT" : "CUSTOM"
|
||||
route_priority = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# development spoke
|
||||
|
||||
moved {
|
||||
from = module.landing-to-dev-ew1-vpn
|
||||
to = module.landing-to-dev-primary-vpn
|
||||
}
|
||||
|
||||
module "landing-to-dev-primary-vpn" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.landing-project.project_id
|
||||
network = module.landing-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-dev-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = {
|
||||
# The router used for this VPN is managed in vpn-prod.tf
|
||||
create = false
|
||||
name = "landing-vpn-${local.region_shortnames[var.regions.primary]}"
|
||||
asn = var.router_spoke_configs.landing-primary.asn
|
||||
}
|
||||
peer_gateways = {
|
||||
default = { gcp = module.dev-to-landing-primary-vpn.self_link }
|
||||
}
|
||||
tunnels = {
|
||||
0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.0/27", 1)
|
||||
asn = var.router_spoke_configs.spoke-dev-primary.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.landing-primary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.0/27", 2)
|
||||
}/30"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.0/27", 5)
|
||||
asn = var.router_spoke_configs.spoke-dev-primary.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.landing-primary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.0/27", 6)
|
||||
}/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
depends_on = [
|
||||
module.landing-to-prod-primary-vpn.router
|
||||
]
|
||||
}
|
||||
|
||||
moved {
|
||||
from = module.dev-to-landing-ew1-vpn
|
||||
to = module.dev-to-landing-primary-vpn
|
||||
}
|
||||
|
||||
module "dev-to-landing-primary-vpn" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.dev-spoke-project.project_id
|
||||
network = module.dev-spoke-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-landing-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = {
|
||||
name = "dev-spoke-vpn-${local.region_shortnames[var.regions.primary]}"
|
||||
asn = var.router_spoke_configs.spoke-dev-primary.asn
|
||||
}
|
||||
name = "to-landing-${local.region_shortnames[var.regions.primary]}"
|
||||
peer_gateways = {
|
||||
default = { gcp = module.landing-to-dev-primary-vpn.self_link }
|
||||
default = { gcp = module.landing-to-spokes-primary-vpn.self_link }
|
||||
}
|
||||
router_config = {
|
||||
asn = var.vpn_configs.dev.asn
|
||||
custom_advertise = var.vpn_configs.dev.custom_advertise
|
||||
}
|
||||
tunnels = {
|
||||
0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.0/27", 2)
|
||||
asn = var.router_spoke_configs.landing-primary.asn
|
||||
address = cidrhost(local.bgp_session_ranges.dev-primary.0, 1)
|
||||
asn = var.vpn_configs.landing.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.dev-primary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.0/27", 1)
|
||||
}/30"
|
||||
shared_secret = module.landing-to-dev-primary-vpn.random_secret
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.dev-primary.0, 2)}/30"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.0/27", 6)
|
||||
asn = var.router_spoke_configs.landing-primary.asn
|
||||
address = cidrhost(local.bgp_session_ranges.dev-primary.1, 1)
|
||||
asn = var.vpn_configs.landing.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.dev-primary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.0/27", 5)
|
||||
}/30"
|
||||
shared_secret = module.landing-to-dev-primary-vpn.random_secret
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.dev-primary.1, 2)}/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,109 +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
|
||||
*
|
||||
* 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 VPN between landing and production spoke in ew1.
|
||||
|
||||
# local.vpn_spoke_bgp_peer_options is defined in the dev VPN file
|
||||
|
||||
moved {
|
||||
from = module.landing-to-prod-ew1-vpn
|
||||
to = module.landing-to-prod-primary-vpn
|
||||
}
|
||||
|
||||
module "landing-to-prod-primary-vpn" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.landing-project.project_id
|
||||
network = module.landing-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-prod-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = {
|
||||
name = "landing-vpn-${local.region_shortnames[var.regions.primary]}"
|
||||
asn = var.router_spoke_configs.landing-primary.asn
|
||||
}
|
||||
peer_gateways = {
|
||||
default = { gcp = module.prod-to-landing-primary-vpn.self_link }
|
||||
}
|
||||
tunnels = {
|
||||
0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.64/27", 1)
|
||||
asn = var.router_spoke_configs.spoke-prod-primary.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.landing-primary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.64/27", 2)
|
||||
}/30"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.64/27", 5)
|
||||
asn = var.router_spoke_configs.spoke-prod-primary.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.landing-primary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.64/27", 6)
|
||||
}/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moved {
|
||||
from = module.prod-to-landing-ew1-vpn
|
||||
to = module.prod-to-landing-primary-vpn
|
||||
}
|
||||
|
||||
module "prod-to-landing-primary-vpn" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.prod-spoke-project.project_id
|
||||
network = module.prod-spoke-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-landing-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = {
|
||||
name = "prod-spoke-vpn-${local.region_shortnames[var.regions.primary]}"
|
||||
asn = var.router_spoke_configs.spoke-prod-primary.asn
|
||||
}
|
||||
peer_gateways = {
|
||||
default = { gcp = module.landing-to-prod-primary-vpn.self_link }
|
||||
}
|
||||
tunnels = {
|
||||
0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.64/27", 2)
|
||||
asn = var.router_spoke_configs.landing-primary.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.prod-primary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.64/27", 1)
|
||||
}/30"
|
||||
shared_secret = module.landing-to-prod-primary-vpn.random_secret
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.64/27", 6)
|
||||
asn = var.router_spoke_configs.landing-primary.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.prod-primary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.64/27", 5)
|
||||
}/30"
|
||||
shared_secret = module.landing-to-prod-primary-vpn.random_secret
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,109 +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
|
||||
*
|
||||
* 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 VPN between landing and production spoke in ew4.
|
||||
|
||||
# local.vpn_spoke_bgp_peer_options is defined in the dev VPN file
|
||||
|
||||
moved {
|
||||
from = module.landing-to-prod-ew4-vpn
|
||||
to = module.landing-to-prod-secondary-vpn
|
||||
}
|
||||
|
||||
module "landing-to-prod-secondary-vpn" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.landing-project.project_id
|
||||
network = module.landing-vpc.self_link
|
||||
region = var.regions.secondary
|
||||
name = "vpn-to-prod-${local.region_shortnames[var.regions.secondary]}"
|
||||
router_config = {
|
||||
name = "landing-vpn-${local.region_shortnames[var.regions.secondary]}"
|
||||
asn = var.router_spoke_configs.landing-secondary.asn
|
||||
}
|
||||
peer_gateways = {
|
||||
default = { gcp = module.prod-to-landing-secondary-vpn.self_link }
|
||||
}
|
||||
tunnels = {
|
||||
0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.96/27", 1)
|
||||
asn = var.router_spoke_configs.spoke-prod-secondary.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.landing-secondary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.96/27", 2)
|
||||
}/30"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.96/27", 5)
|
||||
asn = var.router_spoke_configs.spoke-prod-secondary.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.landing-secondary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.96/27", 6)
|
||||
}/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moved {
|
||||
from = module.prod-to-landing-ew4-vpn
|
||||
to = module.prod-to-landing-secondary-vpn
|
||||
}
|
||||
|
||||
module "prod-to-landing-secondary-vpn" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.prod-spoke-project.project_id
|
||||
network = module.prod-spoke-vpc.self_link
|
||||
region = var.regions.secondary
|
||||
name = "vpn-to-landing-${local.region_shortnames[var.regions.secondary]}"
|
||||
router_config = {
|
||||
name = "prod-spoke-vpn-${local.region_shortnames[var.regions.secondary]}"
|
||||
asn = var.router_spoke_configs.spoke-prod-secondary.asn
|
||||
}
|
||||
peer_gateways = {
|
||||
default = { gcp = module.landing-to-prod-secondary-vpn.self_link }
|
||||
}
|
||||
tunnels = {
|
||||
0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.96/27", 2)
|
||||
asn = var.router_spoke_configs.landing-secondary.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.prod-secondary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.96/27", 1)
|
||||
}/30"
|
||||
shared_secret = module.landing-to-prod-secondary-vpn.random_secret
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost("169.254.0.96/27", 6)
|
||||
asn = var.router_spoke_configs.landing-secondary.asn
|
||||
}
|
||||
bgp_peer_options = local.vpn_spoke_bgp_peer_options.prod-secondary
|
||||
bgp_session_range = "${
|
||||
cidrhost("169.254.0.96/27", 5)
|
||||
}/30"
|
||||
shared_secret = module.landing-to-prod-secondary-vpn.random_secret
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* 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
|
||||
*
|
||||
* 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 VPN between landing and production spoke in ew1.
|
||||
|
||||
module "prod-to-landing-primary-vpn" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.prod-spoke-project.project_id
|
||||
network = module.prod-spoke-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "to-landing-${local.region_shortnames[var.regions.primary]}"
|
||||
peer_gateways = {
|
||||
default = { gcp = module.landing-to-spokes-primary-vpn.self_link }
|
||||
}
|
||||
router_config = {
|
||||
asn = var.vpn_configs.prod.asn
|
||||
custom_advertise = var.vpn_configs.prod.custom_advertise
|
||||
}
|
||||
tunnels = {
|
||||
0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost(local.bgp_session_ranges.prod-primary.0, 1)
|
||||
asn = var.vpn_configs.landing.asn
|
||||
}
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.prod-primary.0, 2)}/30"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost(local.bgp_session_ranges.prod-primary.1, 1)
|
||||
asn = var.vpn_configs.landing.asn
|
||||
}
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.prod-primary.1, 2)}/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "prod-to-landing-secondary-vpn" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.prod-spoke-project.project_id
|
||||
network = module.prod-spoke-vpc.self_link
|
||||
region = var.regions.secondary
|
||||
name = "to-landing-${local.region_shortnames[var.regions.secondary]}"
|
||||
peer_gateways = {
|
||||
default = { gcp = module.landing-to-spokes-secondary-vpn.self_link }
|
||||
}
|
||||
router_config = {
|
||||
asn = var.vpn_configs.prod.asn
|
||||
custom_advertise = var.vpn_configs.prod.custom_advertise
|
||||
}
|
||||
tunnels = {
|
||||
0 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost(local.bgp_session_ranges.prod-secondary.0, 1)
|
||||
asn = var.vpn_configs.landing.asn
|
||||
}
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.prod-secondary.0, 2)}/30"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
1 = {
|
||||
bgp_peer = {
|
||||
address = cidrhost(local.bgp_session_ranges.prod-secondary.1, 1)
|
||||
asn = var.vpn_configs.landing.asn
|
||||
}
|
||||
bgp_session_range = "${cidrhost(local.bgp_session_ranges.prod-secondary.1, 2)}/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,6 +47,7 @@ The final number of subnets, and their IP addressing will depend on the user-spe
|
|||
- [Post-deployment activities](#post-deployment-activities)
|
||||
- [Customizations](#customizations)
|
||||
- [Changing default regions](#changing-default-regions)
|
||||
- [Configuring the VPNs to on prem](#configuring-the-vpns-to-on-prem)
|
||||
- [Adding an environment](#adding-an-environment)
|
||||
|
||||
## Design overview and choices
|
||||
|
@ -235,7 +236,7 @@ Subnets for [L7 ILBs](https://cloud.google.com/load-balancing/docs/l7-internal/p
|
|||
|
||||
### VPNs
|
||||
|
||||
The connectivity between on-premises and GCP (the trusted landing VPC) is implemented with Cloud HA VPN ([`net-vpn`](../../../modules/net-vpn-ha)) and defined in [`vpn-onprem.tf`](./vpn-onprem.tf). The file implements a single logical connection between on-premises and the trusted landing VPC, both in `europe-west1` and `europe-west4`. The relevant parameters for its configuration are found in the variable `vpn_onprem_configs`.
|
||||
The connectivity between on-premises and GCP (the trusted landing VPC) is implemented with Cloud HA VPN ([`net-vpn`](../../../modules/net-vpn-ha)) and defined in [`vpn-onprem.tf`](./vpn-onprem.tf). The file implements a single logical connection between on-premises and the trusted landing VPC, both in `europe-west1` and `europe-west4`. The relevant parameters for its configuration are found in the variables `vpn_onprem_primary_config` and `vpn_onprem_secondary_config`.
|
||||
|
||||
### Routing and BGP
|
||||
|
||||
|
@ -375,6 +376,55 @@ Regions are defined via the `regions` variable which sets up a mapping between t
|
|||
- change the values of the mappings in the `regions` variable to the regions you are going to use
|
||||
- change the regions in the factory subnet files in the `data` folder
|
||||
|
||||
### Configuring the VPNs to on prem
|
||||
|
||||
This stage includes basic support for an HA VPN connecting the landing zone in the primary region to on prem. Configuration is via the `vpn_onprem_primary_config` and `vpn_onprem_secondary_config` variables, that closely mirrors the variables defined in the [`net-vpn-ha`](../../../modules/net-vpn-ha/).
|
||||
|
||||
Support for the onprem VPNs is disabled by default so that no resources are created, this is an example of how to configure one variable to enable the VPN in the primary region:
|
||||
|
||||
```hcl
|
||||
vpn_onprem_primary_config = {
|
||||
peer_external_gateways = {
|
||||
default = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
}
|
||||
router_config = {
|
||||
asn = 65501
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
"10.1.0.0/16" = "gcp"
|
||||
"35.199.192.0/19" = "gcp-dns"
|
||||
"199.36.153.4/30" = "gcp-restricted"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
"0" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.1"
|
||||
asn = 65500
|
||||
}
|
||||
bgp_session_range = "169.254.1.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
"1" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.2.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest skip
|
||||
```
|
||||
|
||||
### Adding an environment
|
||||
|
||||
To create a new environment (e.g. `staging`), a few changes are required:
|
||||
|
@ -383,8 +433,8 @@ Create a `spoke-staging.tf` file by copying `spoke-prod.tf` file.
|
|||
Adapt the new file by replacing the value "prod" with the value "staging".
|
||||
Running `diff spoke-dev.tf spoke-prod.tf` can help to see how environment files differ.
|
||||
|
||||
The new VPC requires a set of dedicated CIDRs, one per region, added to variable `custom_adv` (for example as `spoke_staging_ew1` and `spoke_staging_ew4`).
|
||||
>`custom_adv` is a map that "resolves" CIDR names to the actual addresses, and will be used later to configure routing.
|
||||
The new VPC requires a set of dedicated CIDRs, one per region, added to variable `gcp_ranges` (for example as `spoke_staging_ew1` and `spoke_staging_ew4`).
|
||||
>`gcp_ranges` is a map that "resolves" CIDR names to the actual addresses, and will be used later to configure routing.
|
||||
>
|
||||
Variables managing L7 Internal Load Balancers (`l7ilb_subnets`) and Private Service Access (`psa_ranges`) should also be adapted, and subnets and firewall rules for the new spoke should be added, as described above.
|
||||
|
||||
|
@ -420,20 +470,20 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L97) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L115) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L131) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [custom_adv](variables.tf#L38) | Custom advertisement definitions in name => range format. | <code>map(string)</code> | | <code title="{ cloud_dns = "35.199.192.0/19" gcp_all = "10.128.0.0/16" gcp_dev_primary = "10.128.128.0/19" gcp_dev_secondary = "10.128.160.0/19" gcp_landing_trusted_primary = "10.128.64.0/19" gcp_landing_trusted_secondary = "10.128.96.0/19" gcp_landing_untrusted_primary = "10.128.0.0/19" gcp_landing_untrusted_secondary = "10.128.32.0/19" gcp_prod_primary = "10.128.192.0/19" gcp_prod_secondary = "10.128.224.0/19" googleapis_private = "199.36.153.8/30" googleapis_restricted = "199.36.153.4/30" rfc_1918_10 = "10.0.0.0/8" rfc_1918_172 = "172.16.0.0/12" rfc_1918_192 = "192.168.0.0/16" }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L60) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L69) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L77) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") firewall_policy_name = optional(string, "factory") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [onprem_cidr](variables.tf#L107) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L125) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L142) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object({ dev = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) prod = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L163) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [router_configs](variables.tf#L175) | Configurations for CRs and onprem routers. | <code title="map(object({ adv = object({ custom = list(string) default = bool }) asn = number }))">map(object({…}))</code> | | <code title="{ landing-trusted-primary = { asn = "64512" adv = null } landing-trusted-secondary = { asn = "64512" adv = null } }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L198) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_configs](variables.tf#L212) | VPN gateway configuration for onprem interconnection. | <code title="map(object({ adv = object({ default = bool custom = list(string) }) peer_external_gateway = object({ redundancy_type = string interfaces = list(string) }) tunnels = list(object({ peer_asn = number peer_external_gateway_interface = number secret = string session_range = string vpn_gateway_interface = number })) }))">map(object({…}))</code> | | <code title="{ landing-trusted-primary = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = ["8.8.8.8"] } tunnels = [ { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } landing-trusted-secondary = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = ["8.8.8.8"] } tunnels = [ { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } }">{…}</code> | |
|
||||
| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L108) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L124) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L47) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") firewall_policy_name = optional(string, "factory") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [gcp_ranges](variables.tf#L85) | GCP address ranges in name => range format. | <code>map(string)</code> | | <code title="{ gcp_dev_primary = "10.128.128.0/19" gcp_dev_secondary = "10.128.160.0/19" gcp_landing_trusted_primary = "10.128.64.0/19" gcp_landing_trusted_secondary = "10.128.96.0/19" gcp_landing_untrusted_primary = "10.128.0.0/19" gcp_landing_untrusted_secondary = "10.128.32.0/19" gcp_prod_primary = "10.128.192.0/19" gcp_prod_secondary = "10.128.224.0/19" }">{…}</code> | |
|
||||
| [onprem_cidr](variables.tf#L100) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L118) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L135) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object({ dev = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) prod = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L156) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L168) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L182) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_secondary_config](variables.tf#L225) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -21,19 +21,19 @@ locals {
|
|||
{
|
||||
name = "untrusted"
|
||||
routes = [
|
||||
var.custom_adv.gcp_landing_untrusted_primary,
|
||||
var.custom_adv.gcp_landing_untrusted_secondary,
|
||||
var.gcp_ranges.gcp_landing_untrusted_primary,
|
||||
var.gcp_ranges.gcp_landing_untrusted_secondary,
|
||||
]
|
||||
},
|
||||
{
|
||||
name = "trusted"
|
||||
routes = [
|
||||
var.custom_adv.gcp_dev_primary,
|
||||
var.custom_adv.gcp_dev_secondary,
|
||||
var.custom_adv.gcp_landing_trusted_primary,
|
||||
var.custom_adv.gcp_landing_trusted_secondary,
|
||||
var.custom_adv.gcp_prod_primary,
|
||||
var.custom_adv.gcp_prod_secondary,
|
||||
var.gcp_ranges.gcp_dev_primary,
|
||||
var.gcp_ranges.gcp_dev_secondary,
|
||||
var.gcp_ranges.gcp_landing_trusted_primary,
|
||||
var.gcp_ranges.gcp_landing_trusted_secondary,
|
||||
var.gcp_ranges.gcp_prod_primary,
|
||||
var.gcp_ranges.gcp_prod_secondary,
|
||||
]
|
||||
},
|
||||
]
|
||||
|
|
|
@ -78,13 +78,13 @@ output "tfvars" {
|
|||
|
||||
output "vpn_gateway_endpoints" {
|
||||
description = "External IP Addresses for the GCP VPN gateways."
|
||||
value = local.enable_onprem_vpn == false ? null : {
|
||||
onprem-primary = {
|
||||
for v in module.landing-to-onprem-primary-vpn[0].gateway.vpn_interfaces :
|
||||
value = {
|
||||
onprem-primary = var.vpn_onprem_primary_config == null ? {} : {
|
||||
for v in module.landing-to-onprem-primary-vpn.0.gateway.vpn_interfaces :
|
||||
v.id => v.ip_address
|
||||
}
|
||||
onprem-secondary = {
|
||||
for v in module.landing-to-onprem-secondary-vpn[0].gateway.vpn_interfaces :
|
||||
onprem-secondary = var.vpn_onprem_secondary_config == null ? {} : {
|
||||
for v in module.landing-to-onprem-secondary-vpn.0.gateway.vpn_interfaces :
|
||||
v.id => v.ip_address
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,28 +35,6 @@ variable "billing_account" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "custom_adv" {
|
||||
description = "Custom advertisement definitions in name => range format."
|
||||
type = map(string)
|
||||
default = {
|
||||
cloud_dns = "35.199.192.0/19"
|
||||
gcp_all = "10.128.0.0/16"
|
||||
gcp_dev_primary = "10.128.128.0/19"
|
||||
gcp_dev_secondary = "10.128.160.0/19"
|
||||
gcp_landing_trusted_primary = "10.128.64.0/19"
|
||||
gcp_landing_trusted_secondary = "10.128.96.0/19"
|
||||
gcp_landing_untrusted_primary = "10.128.0.0/19"
|
||||
gcp_landing_untrusted_secondary = "10.128.32.0/19"
|
||||
gcp_prod_primary = "10.128.192.0/19"
|
||||
gcp_prod_secondary = "10.128.224.0/19"
|
||||
googleapis_private = "199.36.153.8/30"
|
||||
googleapis_restricted = "199.36.153.4/30"
|
||||
rfc_1918_10 = "10.0.0.0/8"
|
||||
rfc_1918_172 = "172.16.0.0/12"
|
||||
rfc_1918_192 = "192.168.0.0/16"
|
||||
}
|
||||
}
|
||||
|
||||
variable "custom_roles" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Custom roles defined at the org level, in key => id format."
|
||||
|
@ -104,6 +82,21 @@ variable "folder_ids" {
|
|||
})
|
||||
}
|
||||
|
||||
variable "gcp_ranges" {
|
||||
description = "GCP address ranges in name => range format."
|
||||
type = map(string)
|
||||
default = {
|
||||
gcp_dev_primary = "10.128.128.0/19"
|
||||
gcp_dev_secondary = "10.128.160.0/19"
|
||||
gcp_landing_trusted_primary = "10.128.64.0/19"
|
||||
gcp_landing_trusted_secondary = "10.128.96.0/19"
|
||||
gcp_landing_untrusted_primary = "10.128.0.0/19"
|
||||
gcp_landing_untrusted_secondary = "10.128.32.0/19"
|
||||
gcp_prod_primary = "10.128.192.0/19"
|
||||
gcp_prod_secondary = "10.128.224.0/19"
|
||||
}
|
||||
}
|
||||
|
||||
variable "onprem_cidr" {
|
||||
description = "Onprem addresses in name => range format."
|
||||
type = map(string)
|
||||
|
@ -172,29 +165,6 @@ variable "regions" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "router_configs" {
|
||||
description = "Configurations for CRs and onprem routers."
|
||||
type = map(object({
|
||||
adv = object({
|
||||
custom = list(string)
|
||||
default = bool
|
||||
})
|
||||
asn = number
|
||||
}))
|
||||
default = {
|
||||
landing-trusted-primary = {
|
||||
asn = "64512"
|
||||
adv = null
|
||||
# adv = { default = false, custom = [] }
|
||||
}
|
||||
landing-trusted-secondary = {
|
||||
asn = "64512"
|
||||
adv = null
|
||||
# adv = { default = false, custom = [] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "service_accounts" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Automation service accounts in name => email format."
|
||||
|
@ -209,81 +179,88 @@ variable "service_accounts" {
|
|||
default = null
|
||||
}
|
||||
|
||||
variable "vpn_onprem_configs" {
|
||||
description = "VPN gateway configuration for onprem interconnection."
|
||||
type = map(object({
|
||||
adv = object({
|
||||
default = bool
|
||||
custom = list(string)
|
||||
})
|
||||
peer_external_gateway = object({
|
||||
variable "vpn_onprem_primary_config" {
|
||||
description = "VPN gateway configuration for onprem interconnection in the primary region."
|
||||
type = object({
|
||||
peer_external_gateways = map(object({
|
||||
redundancy_type = string
|
||||
interfaces = list(string)
|
||||
}))
|
||||
router_config = object({
|
||||
create = optional(bool, true)
|
||||
asn = number
|
||||
name = optional(string)
|
||||
keepalive = optional(number)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
tunnels = list(object({
|
||||
peer_asn = number
|
||||
peer_external_gateway_interface = number
|
||||
secret = string
|
||||
session_range = string
|
||||
tunnels = map(object({
|
||||
bgp_peer = object({
|
||||
address = string
|
||||
asn = number
|
||||
route_priority = optional(number, 1000)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
all_vpc_subnets = bool
|
||||
all_peer_vpc_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
# each BGP session on the same Cloud Router must use a unique /30 CIDR
|
||||
# from the 169.254.0.0/16 block.
|
||||
bgp_session_range = string
|
||||
ike_version = optional(number, 2)
|
||||
peer_external_gateway_interface = optional(number)
|
||||
peer_gateway = optional(string, "default")
|
||||
router = optional(string)
|
||||
shared_secret = optional(string)
|
||||
vpn_gateway_interface = number
|
||||
}))
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "vpn_onprem_secondary_config" {
|
||||
description = "VPN gateway configuration for onprem interconnection in the secondary region."
|
||||
type = object({
|
||||
peer_external_gateways = map(object({
|
||||
redundancy_type = string
|
||||
interfaces = list(string)
|
||||
}))
|
||||
default = {
|
||||
landing-trusted-primary = {
|
||||
adv = {
|
||||
default = false
|
||||
custom = [
|
||||
"cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all"
|
||||
]
|
||||
}
|
||||
peer_external_gateway = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
tunnels = [
|
||||
{
|
||||
peer_asn = 65534
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.0/30"
|
||||
vpn_gateway_interface = 0
|
||||
},
|
||||
{
|
||||
peer_asn = 65534
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.4/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
]
|
||||
}
|
||||
landing-trusted-secondary = {
|
||||
adv = {
|
||||
default = false
|
||||
custom = [
|
||||
"cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all"
|
||||
]
|
||||
}
|
||||
peer_external_gateway = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
tunnels = [
|
||||
{
|
||||
peer_asn = 65534
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.0/30"
|
||||
vpn_gateway_interface = 0
|
||||
},
|
||||
{
|
||||
peer_asn = 65534
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.4/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
router_config = object({
|
||||
create = optional(bool, true)
|
||||
asn = number
|
||||
name = optional(string)
|
||||
keepalive = optional(number)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
tunnels = map(object({
|
||||
bgp_peer = object({
|
||||
address = string
|
||||
asn = number
|
||||
route_priority = optional(number, 1000)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
all_vpc_subnets = bool
|
||||
all_peer_vpc_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
# each BGP session on the same Cloud Router must use a unique /30 CIDR
|
||||
# from the 169.254.0.0/16 block.
|
||||
bgp_session_range = string
|
||||
ike_version = optional(number, 2)
|
||||
peer_external_gateway_interface = optional(number)
|
||||
peer_gateway = optional(string, "default")
|
||||
router = optional(string)
|
||||
shared_secret = optional(string)
|
||||
vpn_gateway_interface = number
|
||||
}))
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
|
|
@ -17,92 +17,40 @@
|
|||
# tfdoc:file:description VPN between landing and onprem.
|
||||
|
||||
locals {
|
||||
enable_onprem_vpn = var.vpn_onprem_configs != null
|
||||
bgp_peer_options_onprem = local.enable_onprem_vpn == false ? null : {
|
||||
for k, v in var.vpn_onprem_configs :
|
||||
k => v.adv == null ? null : {
|
||||
custom_advertise = try(v.adv.default, false) ? null : {
|
||||
all_subnets = false
|
||||
all_vpc_subnets = false
|
||||
all_peer_vpc_subnets = false
|
||||
ip_ranges = {
|
||||
for adv in(v.adv == null ? [] : v.adv.custom) :
|
||||
var.custom_adv[adv] => adv
|
||||
onprem_peer_gateways = {
|
||||
primary = try(
|
||||
var.vpn_onprem_primary_config.peer_external_gateways, {}
|
||||
)
|
||||
secondary = try(
|
||||
var.vpn_onprem_secondary_config.peer_external_gateways, {}
|
||||
)
|
||||
}
|
||||
}
|
||||
route_priority = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moved {
|
||||
from = module.landing-to-onprem-ew1-vpn
|
||||
to = module.landing-to-onprem-primary-vpn
|
||||
}
|
||||
|
||||
module "landing-to-onprem-primary-vpn" {
|
||||
count = local.enable_onprem_vpn ? 1 : 0
|
||||
count = var.vpn_onprem_primary_config == null ? 0 : 1
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.landing-project.project_id
|
||||
network = module.landing-trusted-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-onprem-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = {
|
||||
name = "landing-onprem-vpn-${local.region_shortnames[var.regions.primary]}"
|
||||
asn = var.router_configs.landing-trusted-primary.asn
|
||||
}
|
||||
router_config = try(var.vpn_onprem_primary_config.router_config, {})
|
||||
peer_gateways = {
|
||||
default = {
|
||||
external = var.vpn_onprem_configs.landing-trusted-primary.peer_external_gateway
|
||||
for k, v in local.onprem_peer_gateways.primary : k => { external = v }
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
for t in var.vpn_onprem_configs.landing-trusted-primary.tunnels :
|
||||
"remote-${t.vpn_gateway_interface}-${t.peer_external_gateway_interface}" => {
|
||||
bgp_peer = merge(
|
||||
{ address = cidrhost(t.session_range, 1), asn = t.peer_asn },
|
||||
local.bgp_peer_options_onprem.landing-trusted-primary
|
||||
)
|
||||
bgp_session_range = "${cidrhost(t.session_range, 2)}/30"
|
||||
peer_external_gateway_interface = t.peer_external_gateway_interface
|
||||
shared_secret = t.secret
|
||||
vpn_gateway_interface = t.vpn_gateway_interface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moved {
|
||||
from = module.landing-to-onprem-ew4-vpn
|
||||
to = module.landing-to-onprem-secondary-vpn
|
||||
tunnels = try(var.vpn_onprem_primary_config.tunnels, {})
|
||||
}
|
||||
|
||||
module "landing-to-onprem-secondary-vpn" {
|
||||
count = local.enable_onprem_vpn ? 1 : 0
|
||||
count = var.vpn_onprem_secondary_config == null ? 0 : 1
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.landing-project.project_id
|
||||
network = module.landing-trusted-vpc.self_link
|
||||
region = var.regions.secondary
|
||||
name = "vpn-to-onprem-${local.region_shortnames[var.regions.secondary]}"
|
||||
router_config = {
|
||||
name = "landing-onprem-vpn-${local.region_shortnames[var.regions.secondary]}"
|
||||
asn = var.router_configs.landing-trusted-secondary.asn
|
||||
}
|
||||
router_config = try(var.vpn_onprem_secondary_config.router_config, {})
|
||||
peer_gateways = {
|
||||
default = {
|
||||
external = var.vpn_onprem_configs.landing-trusted-secondary.peer_external_gateway
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
for t in var.vpn_onprem_configs.landing-trusted-secondary.tunnels :
|
||||
"remote-${t.vpn_gateway_interface}-${t.peer_external_gateway_interface}" => {
|
||||
bgp_peer = merge(
|
||||
{ address = cidrhost(t.session_range, 1), asn = t.peer_asn },
|
||||
local.bgp_peer_options_onprem.landing-trusted-secondary
|
||||
)
|
||||
bgp_session_range = "${cidrhost(t.session_range, 2)}/30"
|
||||
peer_external_gateway_interface = t.peer_external_gateway_interface
|
||||
shared_secret = t.secret
|
||||
vpn_gateway_interface = t.vpn_gateway_interface
|
||||
}
|
||||
for k, v in local.onprem_peer_gateways.secondary : k => { external = v }
|
||||
}
|
||||
tunnels = try(var.vpn_onprem_secondary_config.tunnels, {})
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ The following diagram illustrates the high-level design, and should be used as a
|
|||
- [Running the stage](#running-the-stage)
|
||||
- [Post-deployment activities](#post-deployment-activities)
|
||||
- [Customizations](#customizations)
|
||||
- [Configuring the VPNs to on prem](#configuring-the-vpns-to-on-prem)
|
||||
- [Changing default regions](#changing-default-regions)
|
||||
|
||||
## Design overview and choices
|
||||
|
@ -129,7 +130,7 @@ Subnets for [L7 ILBs](https://cloud.google.com/load-balancing/docs/l7-internal/p
|
|||
|
||||
### VPNs
|
||||
|
||||
Connectivity to on-prem is implemented with HA VPN ([`net-vpn`](../../../modules/net-vpn-ha)) and defined in `vpn-onprem-{dev,prod}.tf`. The files provisionally implement each a single logical connection between onprem and environment at `europe-west1`, and the relevant parameters for its configuration are found in variable `vpn_onprem_configs`.
|
||||
Connectivity to on-prem is implemented with HA VPN ([`net-vpn`](../../../modules/net-vpn-ha)) and defined in `vpn-onprem.tf`. The file implements a single logical connection between each environment and onprem in the primary region, and the relevant parameters for its configuration are found in the `vpn_onprem_dev_primary_config` and `vpn_onprem_prod_primary_config` variables.
|
||||
|
||||
### Routing and BGP
|
||||
|
||||
|
@ -257,6 +258,55 @@ Per variable `vpn_onprem_configs` such ranges are advertised to onprem - further
|
|||
|
||||
## Customizations
|
||||
|
||||
### Configuring the VPNs to on prem
|
||||
|
||||
This stage includes basic support for an HA VPN connecting each environment landing zone in the primary region to on prem. Configuration is via the `vpn_onprem_dev_primary_config` and `vpn_onprem_prod_primary_config` variables, that closely mirrors the variables defined in the [`net-vpn-ha`](../../../modules/net-vpn-ha/).
|
||||
|
||||
Support for the onprem VPNs is disabled by default so that no resources are created, this is an example of how to configure one variable to enable the VPN for dev in the primary region:
|
||||
|
||||
```hcl
|
||||
vpn_onprem_dev_primary_config = {
|
||||
peer_external_gateways = {
|
||||
default = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
}
|
||||
router_config = {
|
||||
asn = 65501
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
"10.1.0.0/16" = "gcp"
|
||||
"35.199.192.0/19" = "gcp-dns"
|
||||
"199.36.153.4/30" = "gcp-restricted"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
"0" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.1"
|
||||
asn = 65500
|
||||
}
|
||||
bgp_session_range = "169.254.1.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
"1" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.2.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest skip
|
||||
```
|
||||
|
||||
### Changing default regions
|
||||
|
||||
Regions are defined via the `regions` variable which sets up a mapping between the `regions.primary` and `regions.secondary` logical names and actual GCP region names. If you need to change regions from the defaults:
|
||||
|
@ -281,8 +331,7 @@ Regions are defined via the `regions` variable which sets up a mapping between t
|
|||
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | <code>google_project_iam_binding</code> |
|
||||
| [test-resources.tf](./test-resources.tf) | Temporary instances for testing | <code>compute-vm</code> | |
|
||||
| [variables.tf](./variables.tf) | Module variables. | | |
|
||||
| [vpn-onprem-dev.tf](./vpn-onprem-dev.tf) | VPN between dev and onprem. | <code>net-vpn-ha</code> | |
|
||||
| [vpn-onprem-prod.tf](./vpn-onprem-prod.tf) | VPN between prod and onprem. | <code>net-vpn-ha</code> | |
|
||||
| [vpn-onprem.tf](./vpn-onprem.tf) | VPN between landing and onprem. | <code>net-vpn-ha</code> | |
|
||||
|
||||
## Variables
|
||||
|
||||
|
@ -290,19 +339,18 @@ Regions are defined via the `regions` variable which sets up a mapping between t
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L92) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L102) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L118) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [custom_adv](variables.tf#L38) | Custom advertisement definitions in name => range format. | <code>map(string)</code> | | <code title="{ cloud_dns = "35.199.192.0/19" gcp_all = "10.128.0.0/16" gcp_dev = "10.128.32.0/19" gcp_prod = "10.128.64.0/19" googleapis_private = "199.36.153.8/30" googleapis_restricted = "199.36.153.4/30" rfc_1918_10 = "10.0.0.0/8" rfc_1918_172 = "172.16.0.0/12" rfc_1918_192 = "192.168.0.0/16" }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L54) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L63) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ prod = ["10.0.1.1"] dev = ["10.0.2.1"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L72) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") firewall_policy_name = optional(string, "factory") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L112) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L129) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code title="object({ dev = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) prod = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L166) | Region definitions. | <code title="object({ primary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" }">{…}</code> | |
|
||||
| [router_onprem_configs](variables.tf#L176) | Configurations for routers used for onprem connectivity. | <code title="map(object({ adv = object({ custom = list(string) default = bool }) asn = number }))">map(object({…}))</code> | | <code title="{ prod-primary = { asn = "65533" adv = null } dev-primary = { asn = "65534" adv = null } }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L199) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_configs](variables.tf#L211) | VPN gateway configuration for onprem interconnection. | <code title="map(object({ adv = object({ default = bool custom = list(string) }) peer_external_gateway = object({ redundancy_type = string interfaces = list(string) }) tunnels = list(object({ peer_asn = number peer_external_gateway_interface = number secret = string session_range = string vpn_gateway_interface = number })) }))">map(object({…}))</code> | | <code title="{ dev-primary = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_dev" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = ["8.8.8.8"] } tunnels = [ { peer_asn = 65544 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65544 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } prod-primary = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_prod" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = ["8.8.8.8"] } tunnels = [ { peer_asn = 65543 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65543 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } }">{…}</code> | |
|
||||
| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L86) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L102) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L47) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ prod = ["10.0.1.1"] dev = ["10.0.2.1"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L56) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") firewall_policy_name = optional(string, "factory") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L96) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L113) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code title="object({ dev = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) prod = object({ ranges = map(string) routes = object({ export = bool import = bool }) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L134) | Region definitions. | <code title="object({ primary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L144) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_dev_primary_config](variables.tf#L156) | VPN gateway configuration for onprem interconnection from dev in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_prod_primary_config](variables.tf#L199) | VPN gateway configuration for onprem interconnection from prod in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -89,13 +89,13 @@ output "tfvars" {
|
|||
|
||||
output "vpn_gateway_endpoints" {
|
||||
description = "External IP Addresses for the GCP VPN gateways."
|
||||
value = local.enable_onprem_vpn == false ? null : {
|
||||
dev-onprem-primary = {
|
||||
for v in module.dev-to-onprem-primary-vpn[0].gateway.vpn_interfaces :
|
||||
value = {
|
||||
dev-primary = var.vpn_onprem_dev_primary_config == null ? {} : {
|
||||
for v in module.landing-to-onprem-dev-primary-vpn.0.gateway.vpn_interfaces :
|
||||
v.id => v.ip_address
|
||||
}
|
||||
prod-onprem-primary = {
|
||||
for v in module.prod-to-onprem-primary-vpn[0].gateway.vpn_interfaces :
|
||||
prod-primary = var.vpn_onprem_prod_primary_config == null ? {} : {
|
||||
for v in module.landing-to-onprem-prod-primary-vpn.0.gateway.vpn_interfaces :
|
||||
v.id => v.ip_address
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,22 +35,6 @@ variable "billing_account" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "custom_adv" {
|
||||
description = "Custom advertisement definitions in name => range format."
|
||||
type = map(string)
|
||||
default = {
|
||||
cloud_dns = "35.199.192.0/19"
|
||||
gcp_all = "10.128.0.0/16"
|
||||
gcp_dev = "10.128.32.0/19"
|
||||
gcp_prod = "10.128.64.0/19"
|
||||
googleapis_private = "199.36.153.8/30"
|
||||
googleapis_restricted = "199.36.153.4/30"
|
||||
rfc_1918_10 = "10.0.0.0/8"
|
||||
rfc_1918_172 = "172.16.0.0/12"
|
||||
rfc_1918_192 = "192.168.0.0/16"
|
||||
}
|
||||
}
|
||||
|
||||
variable "custom_roles" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Custom roles defined at the org level, in key => id format."
|
||||
|
@ -145,22 +129,6 @@ variable "psa_ranges" {
|
|||
})
|
||||
})
|
||||
default = null
|
||||
# default = {
|
||||
# dev = {
|
||||
# ranges = {
|
||||
# cloudsql-mysql = "10.128.62.0/24"
|
||||
# cloudsql-sqlserver = "10.128.63.0/24"
|
||||
# }
|
||||
# routes = null
|
||||
# }
|
||||
# prod = {
|
||||
# ranges = {
|
||||
# cloudsql-mysql = "10.128.94.0/24"
|
||||
# cloudsql-sqlserver = "10.128.95.0/24"
|
||||
# }
|
||||
# routes = null
|
||||
# }
|
||||
# }
|
||||
}
|
||||
|
||||
variable "regions" {
|
||||
|
@ -173,29 +141,6 @@ variable "regions" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "router_onprem_configs" {
|
||||
description = "Configurations for routers used for onprem connectivity."
|
||||
type = map(object({
|
||||
adv = object({
|
||||
custom = list(string)
|
||||
default = bool
|
||||
})
|
||||
asn = number
|
||||
}))
|
||||
default = {
|
||||
prod-primary = {
|
||||
asn = "65533"
|
||||
adv = null
|
||||
# adv = { default = false, custom = [] }
|
||||
}
|
||||
dev-primary = {
|
||||
asn = "65534"
|
||||
adv = null
|
||||
# adv = { default = false, custom = [] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "service_accounts" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Automation service accounts in name => email format."
|
||||
|
@ -208,82 +153,88 @@ variable "service_accounts" {
|
|||
default = null
|
||||
}
|
||||
|
||||
variable "vpn_onprem_configs" {
|
||||
description = "VPN gateway configuration for onprem interconnection."
|
||||
type = map(object({
|
||||
adv = object({
|
||||
default = bool
|
||||
custom = list(string)
|
||||
})
|
||||
peer_external_gateway = object({
|
||||
variable "vpn_onprem_dev_primary_config" {
|
||||
description = "VPN gateway configuration for onprem interconnection from dev in the primary region."
|
||||
type = object({
|
||||
peer_external_gateways = map(object({
|
||||
redundancy_type = string
|
||||
interfaces = list(string)
|
||||
}))
|
||||
router_config = object({
|
||||
create = optional(bool, true)
|
||||
asn = number
|
||||
name = optional(string)
|
||||
keepalive = optional(number)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
tunnels = list(object({
|
||||
peer_asn = number
|
||||
peer_external_gateway_interface = number
|
||||
secret = string
|
||||
session_range = string
|
||||
tunnels = map(object({
|
||||
bgp_peer = object({
|
||||
address = string
|
||||
asn = number
|
||||
route_priority = optional(number, 1000)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
all_vpc_subnets = bool
|
||||
all_peer_vpc_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
# each BGP session on the same Cloud Router must use a unique /30 CIDR
|
||||
# from the 169.254.0.0/16 block.
|
||||
bgp_session_range = string
|
||||
ike_version = optional(number, 2)
|
||||
peer_external_gateway_interface = optional(number)
|
||||
peer_gateway = optional(string, "default")
|
||||
router = optional(string)
|
||||
shared_secret = optional(string)
|
||||
vpn_gateway_interface = number
|
||||
}))
|
||||
}))
|
||||
default = {
|
||||
dev-primary = {
|
||||
adv = {
|
||||
default = false
|
||||
custom = [
|
||||
"cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_dev"
|
||||
]
|
||||
})
|
||||
default = null
|
||||
}
|
||||
peer_external_gateway = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
|
||||
}
|
||||
tunnels = [
|
||||
{
|
||||
peer_asn = 65544
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.0/30"
|
||||
vpn_gateway_interface = 0
|
||||
},
|
||||
{
|
||||
peer_asn = 65544
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.4/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
]
|
||||
}
|
||||
prod-primary = {
|
||||
adv = {
|
||||
default = false
|
||||
custom = [
|
||||
"cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_prod"
|
||||
]
|
||||
}
|
||||
peer_external_gateway = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
tunnels = [
|
||||
{
|
||||
peer_asn = 65543
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.0/30"
|
||||
vpn_gateway_interface = 0
|
||||
},
|
||||
{
|
||||
peer_asn = 65543
|
||||
peer_external_gateway_interface = 0
|
||||
secret = "foobar"
|
||||
session_range = "169.254.1.4/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
variable "vpn_onprem_prod_primary_config" {
|
||||
description = "VPN gateway configuration for onprem interconnection from prod in the primary region."
|
||||
type = object({
|
||||
peer_external_gateways = map(object({
|
||||
redundancy_type = string
|
||||
interfaces = list(string)
|
||||
}))
|
||||
router_config = object({
|
||||
create = optional(bool, true)
|
||||
asn = number
|
||||
name = optional(string)
|
||||
keepalive = optional(number)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
tunnels = map(object({
|
||||
bgp_peer = object({
|
||||
address = string
|
||||
asn = number
|
||||
route_priority = optional(number, 1000)
|
||||
custom_advertise = optional(object({
|
||||
all_subnets = bool
|
||||
all_vpc_subnets = bool
|
||||
all_peer_vpc_subnets = bool
|
||||
ip_ranges = map(string)
|
||||
}))
|
||||
})
|
||||
# each BGP session on the same Cloud Router must use a unique /30 CIDR
|
||||
# from the 169.254.0.0/16 block.
|
||||
bgp_session_range = string
|
||||
ike_version = optional(number, 2)
|
||||
peer_external_gateway_interface = optional(number)
|
||||
peer_gateway = optional(string, "default")
|
||||
router = optional(string)
|
||||
shared_secret = optional(string)
|
||||
vpn_gateway_interface = number
|
||||
}))
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
|
|
@ -1,70 +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
|
||||
*
|
||||
* 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 VPN between dev and onprem.
|
||||
|
||||
locals {
|
||||
enable_onprem_vpn = var.vpn_onprem_configs != null
|
||||
bgp_peer_options_onprem = local.enable_onprem_vpn == false ? null : {
|
||||
for k, v in var.vpn_onprem_configs :
|
||||
k => v.adv == null ? null : {
|
||||
advertise_groups = []
|
||||
advertise_ip_ranges = {
|
||||
for adv in(v.adv == null ? [] : v.adv.custom) :
|
||||
var.custom_adv[adv] => adv
|
||||
}
|
||||
advertise_mode = try(v.adv.default, false) ? "DEFAULT" : "CUSTOM"
|
||||
route_priority = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moved {
|
||||
from = module.dev-to-onprem-ew1-vpn
|
||||
to = module.dev-to-onprem-primary-vpn
|
||||
}
|
||||
|
||||
module "dev-to-onprem-primary-vpn" {
|
||||
count = local.enable_onprem_vpn ? 1 : 0
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.dev-spoke-project.project_id
|
||||
network = module.dev-spoke-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-onprem-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = {
|
||||
name = "dev-onprem-vpn-${local.region_shortnames[var.regions.primary]}"
|
||||
asn = var.router_onprem_configs.dev-primary.asn
|
||||
}
|
||||
peer_gateways = {
|
||||
default = {
|
||||
external = var.vpn_onprem_configs.dev-primary.peer_external_gateway
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
for t in var.vpn_onprem_configs.dev-primary.tunnels :
|
||||
"remote-${t.vpn_gateway_interface}-${t.peer_external_gateway_interface}" => {
|
||||
bgp_peer = {
|
||||
address = cidrhost(t.session_range, 1)
|
||||
asn = t.peer_asn
|
||||
}
|
||||
bgp_peer_options = local.bgp_peer_options_onprem.dev-primary
|
||||
bgp_session_range = "${cidrhost(t.session_range, 2)}/30"
|
||||
peer_external_gateway_interface = t.peer_external_gateway_interface
|
||||
shared_secret = t.secret
|
||||
vpn_gateway_interface = t.vpn_gateway_interface
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,54 +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
|
||||
*
|
||||
* 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 VPN between prod and onprem.
|
||||
|
||||
moved {
|
||||
from = module.prod-to-onprem-ew1-vpn
|
||||
to = module.prod-to-onprem-primary-vpn
|
||||
}
|
||||
|
||||
module "prod-to-onprem-primary-vpn" {
|
||||
count = local.enable_onprem_vpn ? 1 : 0
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.prod-spoke-project.project_id
|
||||
network = module.prod-spoke-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-onprem-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = {
|
||||
name = "prod-onprem-vpn-${local.region_shortnames[var.regions.primary]}"
|
||||
asn = var.router_onprem_configs.prod-primary.asn
|
||||
}
|
||||
peer_gateways = {
|
||||
default = {
|
||||
external = var.vpn_onprem_configs.prod-primary.peer_external_gateway
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
for t in var.vpn_onprem_configs.prod-primary.tunnels :
|
||||
"remote-${t.vpn_gateway_interface}-${t.peer_external_gateway_interface}" => {
|
||||
bgp_peer = {
|
||||
address = cidrhost(t.session_range, 1)
|
||||
asn = t.peer_asn
|
||||
}
|
||||
bgp_peer_options = local.bgp_peer_options_onprem.prod-primary
|
||||
bgp_session_range = "${cidrhost(t.session_range, 2)}/30"
|
||||
peer_external_gateway_interface = t.peer_external_gateway_interface
|
||||
shared_secret = t.secret
|
||||
vpn_gateway_interface = t.vpn_gateway_interface
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* 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
|
||||
*
|
||||
* 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 VPN between landing and onprem.
|
||||
|
||||
locals {
|
||||
onprem_peer_gateways = {
|
||||
dev = try(
|
||||
var.vpn_onprem_dev_primary_config.peer_external_gateways, {}
|
||||
)
|
||||
prod = try(
|
||||
var.vpn_onprem_prod_primary_config.peer_external_gateways, {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module "landing-to-onprem-dev-primary-vpn" {
|
||||
count = var.vpn_onprem_dev_primary_config == null ? 0 : 1
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.dev-spoke-project.project_id
|
||||
network = module.dev-spoke-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-onprem-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = try(var.vpn_onprem_dev_primary_config.router_config, {})
|
||||
peer_gateways = {
|
||||
for k, v in local.onprem_peer_gateways.dev : k => { external = v }
|
||||
}
|
||||
tunnels = try(var.vpn_onprem_dev_primary_config.tunnels, {})
|
||||
}
|
||||
|
||||
module "landing-to-onprem-prod-primary-vpn" {
|
||||
count = var.vpn_onprem_prod_primary_config == null ? 0 : 1
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.prod-spoke-project.project_id
|
||||
network = module.prod-spoke-vpc.self_link
|
||||
region = var.regions.primary
|
||||
name = "vpn-to-onprem-${local.region_shortnames[var.regions.primary]}"
|
||||
router_config = try(var.vpn_onprem_prod_primary_config.router_config, {})
|
||||
peer_gateways = {
|
||||
for k, v in local.onprem_peer_gateways.prod : k => { external = v }
|
||||
}
|
||||
tunnels = try(var.vpn_onprem_prod_primary_config.tunnels, {})
|
||||
}
|
|
@ -27,3 +27,38 @@ organization = {
|
|||
customer_id = "C00000000"
|
||||
}
|
||||
prefix = "fast2"
|
||||
vpn_onprem_primary_config = {
|
||||
peer_external_gateways = {
|
||||
default = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
}
|
||||
router_config = {
|
||||
asn = 65501
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = { "10.1.0.0/16" = "gcp" }
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
"0" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.1"
|
||||
asn = 65500
|
||||
}
|
||||
bgp_session_range = "169.254.1.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
"1" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.2.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,6 @@ folder_ids = {
|
|||
networking-dev = null
|
||||
networking-prod = null
|
||||
}
|
||||
region_trigram = {
|
||||
europe-west1 = "ew1"
|
||||
europe-west3 = "ew3"
|
||||
europe-west8 = "ew8"
|
||||
}
|
||||
service_accounts = {
|
||||
data-platform-dev = "string"
|
||||
data-platform-prod = "string"
|
||||
|
|
|
@ -27,3 +27,81 @@ organization = {
|
|||
customer_id = "C00000000"
|
||||
}
|
||||
prefix = "fast2"
|
||||
vpn_onprem_primary_config = {
|
||||
peer_external_gateways = {
|
||||
default = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
}
|
||||
router_config = {
|
||||
asn = 65501
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
"10.1.0.0/16" = "gcp"
|
||||
"35.199.192.0/19" = "gcp-dns"
|
||||
"199.36.153.4/30" = "gcp-restricted"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
"0" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.1"
|
||||
asn = 65500
|
||||
}
|
||||
bgp_session_range = "169.254.1.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
"1" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.2.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
vpn_onprem_secondary_config = {
|
||||
peer_external_gateways = {
|
||||
default = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.4.4"]
|
||||
}
|
||||
}
|
||||
router_config = {
|
||||
asn = 65501
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
"10.1.0.0/16" = "gcp"
|
||||
"35.199.192.0/19" = "gcp-dns"
|
||||
"199.36.153.4/30" = "gcp-restricted"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
"0" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.1"
|
||||
asn = 65500
|
||||
}
|
||||
bgp_session_range = "169.254.3.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
"1" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.4.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,3 +25,81 @@ organization = {
|
|||
customer_id = "C00000000"
|
||||
}
|
||||
prefix = "fast2"
|
||||
vpn_onprem_dev_primary_config = {
|
||||
peer_external_gateways = {
|
||||
default = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.8.8"]
|
||||
}
|
||||
}
|
||||
router_config = {
|
||||
asn = 65501
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
"10.1.0.0/16" = "gcp"
|
||||
"35.199.192.0/19" = "gcp-dns"
|
||||
"199.36.153.4/30" = "gcp-restricted"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
"0" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.1"
|
||||
asn = 65500
|
||||
}
|
||||
bgp_session_range = "169.254.1.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
"1" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.2.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
vpn_onprem_prod_primary_config = {
|
||||
peer_external_gateways = {
|
||||
default = {
|
||||
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
|
||||
interfaces = ["8.8.4.4"]
|
||||
}
|
||||
}
|
||||
router_config = {
|
||||
asn = 65501
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
"10.1.0.0/16" = "gcp"
|
||||
"35.199.192.0/19" = "gcp-dns"
|
||||
"199.36.153.4/30" = "gcp-restricted"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
"0" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.1"
|
||||
asn = 65500
|
||||
}
|
||||
bgp_session_range = "169.254.3.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
"1" = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.4.2/30"
|
||||
shared_secret = "foo"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue