2023-04-04 11:41:04 -07:00
|
|
|
/**
|
|
|
|
* 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 {
|
|
|
|
_nva_zones = ["b", "c"]
|
|
|
|
|
|
|
|
# The configurations used to create the NVA VMs.
|
2024-02-28 22:45:19 -08:00
|
|
|
#
|
2023-04-04 11:41:04 -07:00
|
|
|
# Rendered as following:
|
|
|
|
# nva_configs = {
|
|
|
|
# primary-b = {...}
|
|
|
|
# primary-c = {...}
|
|
|
|
# secondary-b = {...}
|
|
|
|
# secondary-c = {...}
|
|
|
|
# }
|
|
|
|
nva_configs = {
|
|
|
|
for v in setproduct(keys(var.regions), local._nva_zones) :
|
|
|
|
join("-", v) => {
|
|
|
|
# Each NVA announces its trusted regional subnets
|
|
|
|
announce-to-nva = upper(v.0)
|
|
|
|
# NVAs in each region have their own ASN
|
|
|
|
# and peer with cross-regional NVAs.
|
|
|
|
asn_nva = (
|
|
|
|
v.0 == "primary"
|
|
|
|
? var.ncc_asn.nva_primary
|
|
|
|
: var.ncc_asn.nva_secondary
|
|
|
|
)
|
|
|
|
asn_nva_cross_region = (
|
|
|
|
v.0 == "primary"
|
|
|
|
? var.ncc_asn.nva_secondary
|
|
|
|
: var.ncc_asn.nva_primary
|
|
|
|
)
|
2024-02-28 22:45:19 -08:00
|
|
|
asn_landing = var.ncc_asn.landing
|
|
|
|
asn_dmz = var.ncc_asn.dmz
|
2023-04-04 11:41:04 -07:00
|
|
|
# To guarantee traffic to remain symmetric,
|
|
|
|
# NVAs need to advertise cross-region routes with a higher cost (10100)
|
2024-02-28 22:45:19 -08:00
|
|
|
cost_primary = v.0 == "primary" ? "100" : "10100"
|
|
|
|
cost_secondary = v.0 == "primary" ? "10100" : "100"
|
|
|
|
gcp_dev_primary = var.gcp_ranges.gcp_dev_primary
|
|
|
|
gcp_dev_secondary = var.gcp_ranges.gcp_dev_secondary
|
|
|
|
gcp_landing_landing_primary = var.gcp_ranges.gcp_landing_primary
|
|
|
|
gcp_landing_landing_secondary = var.gcp_ranges.gcp_landing_secondary
|
|
|
|
gcp_landing_dmz_primary = var.gcp_ranges.gcp_dmz_primary
|
|
|
|
gcp_landing_dmz_secondary = var.gcp_ranges.gcp_dmz_secondary
|
|
|
|
gcp_prod_primary = var.gcp_ranges.gcp_prod_primary
|
|
|
|
gcp_prod_secondary = var.gcp_ranges.gcp_prod_secondary
|
|
|
|
# The IPs of cross-region NVA VMs in the DMZ VPC (x.y.w.z)
|
|
|
|
ip_neighbor_cross_region_nva_0 = cidrhost(
|
|
|
|
module.dmz-vpc.subnet_ips["${local._regions_cross[v.0]}/dmz-default"], 101
|
|
|
|
)
|
|
|
|
ip_neighbor_cross_region_nva_1 = cidrhost(
|
|
|
|
module.dmz-vpc.subnet_ips["${local._regions_cross[v.0]}/dmz-default"], 102
|
|
|
|
)
|
|
|
|
# The Cloud router IPs (x.y.w.z) in the DMZ
|
|
|
|
# and in the landing VPCs, where the NVA connects to
|
|
|
|
ip_neighbor_landing_0 = cidrhost(
|
|
|
|
module.landing-vpc.subnet_ips["${var.regions[v.0]}/landing-default"], 201
|
|
|
|
)
|
|
|
|
ip_neighbor_landing_1 = cidrhost(
|
|
|
|
module.landing-vpc.subnet_ips["${var.regions[v.0]}/landing-default"], 202
|
|
|
|
)
|
|
|
|
ip_neighbor_dmz_0 = cidrhost(
|
|
|
|
module.dmz-vpc.subnet_ips["${var.regions[v.0]}/dmz-default"], 201
|
|
|
|
)
|
|
|
|
ip_neighbor_dmz_1 = cidrhost(
|
|
|
|
module.dmz-vpc.subnet_ips["${var.regions[v.0]}/dmz-default"], 202
|
|
|
|
)
|
2023-04-04 11:41:04 -07:00
|
|
|
# The IPs to assign to the NVA NICs
|
2024-02-28 22:45:19 -08:00
|
|
|
# in the landing and in the DMZ VPCs.
|
|
|
|
ip_landing = cidrhost(
|
|
|
|
module.landing-vpc.subnet_ips["${var.regions[v.0]}/landing-default"],
|
|
|
|
101 + index(var.zones, v.1)
|
|
|
|
)
|
|
|
|
ip_dmz = cidrhost(
|
|
|
|
module.dmz-vpc.subnet_ips["${var.regions[v.0]}/dmz-default"],
|
|
|
|
101 + index(var.zones, v.1)
|
|
|
|
)
|
2023-04-04 11:41:04 -07:00
|
|
|
# Either primary or secondary
|
|
|
|
name = v.0
|
|
|
|
# The name of the region where the NVA lives.
|
|
|
|
# For example, europe-west1 or europe-west4
|
|
|
|
region = var.regions[v.0]
|
|
|
|
# the short name for the region. For example, ew1 or ew4
|
|
|
|
shortname = local.region_shortnames[var.regions[v.0]]
|
|
|
|
# The zone where the NVA lives. For example, b or c
|
|
|
|
zone = v.1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# The routing_config should be aligned to the NVA NICs.
|
|
|
|
# For example:
|
|
|
|
# local.routing_config[0] configures eth0;
|
|
|
|
# local.routing_config[0] configures eth1.
|
|
|
|
routing_config = [
|
|
|
|
{
|
|
|
|
enable_masquerading = true
|
2024-02-28 22:45:19 -08:00
|
|
|
name = "dmz"
|
2023-04-04 11:41:04 -07:00
|
|
|
routes = [
|
2024-02-28 22:45:19 -08:00
|
|
|
var.gcp_ranges.gcp_dmz_primary,
|
|
|
|
var.gcp_ranges.gcp_dmz_secondary
|
2023-04-04 11:41:04 -07:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
2024-02-28 22:45:19 -08:00
|
|
|
name = "landing"
|
2023-04-04 11:41:04 -07:00
|
|
|
routes = [
|
2024-02-28 22:45:19 -08:00
|
|
|
var.gcp_ranges.gcp_landing_primary,
|
|
|
|
var.gcp_ranges.gcp_landing_secondary
|
2023-04-04 11:41:04 -07:00
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
module "nva-bgp-cloud-config" {
|
|
|
|
for_each = local.nva_configs
|
|
|
|
source = "../../../modules/cloud-config-container/simple-nva"
|
|
|
|
enable_health_checks = true
|
|
|
|
network_interfaces = local.routing_config
|
|
|
|
frr_config = {
|
|
|
|
config_file = templatefile("data/bgp-config.tftpl", each.value)
|
|
|
|
daemons_enabled = ["bgpd"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-28 22:45:19 -08:00
|
|
|
# TODO: use address module
|
|
|
|
|
|
|
|
resource "google_compute_address" "nva_static_ip_landing" {
|
2023-04-04 11:41:04 -07:00
|
|
|
for_each = local.nva_configs
|
2024-02-28 22:45:19 -08:00
|
|
|
name = "nva-ip-landing-${each.value.shortname}-${each.value.zone}"
|
2023-04-04 11:41:04 -07:00
|
|
|
project = module.landing-project.project_id
|
2024-02-28 22:45:19 -08:00
|
|
|
subnetwork = module.landing-vpc.subnet_self_links["${each.value.region}/landing-default"]
|
2023-04-04 11:41:04 -07:00
|
|
|
address_type = "INTERNAL"
|
2024-02-28 22:45:19 -08:00
|
|
|
address = each.value.ip_landing
|
2023-04-04 11:41:04 -07:00
|
|
|
region = each.value.region
|
|
|
|
}
|
|
|
|
|
2024-02-28 22:45:19 -08:00
|
|
|
resource "google_compute_address" "nva_static_ip_dmz" {
|
2023-04-04 11:41:04 -07:00
|
|
|
for_each = local.nva_configs
|
2024-02-28 22:45:19 -08:00
|
|
|
name = "nva-ip-dmz-${each.value.shortname}-${each.value.zone}"
|
2023-04-04 11:41:04 -07:00
|
|
|
project = module.landing-project.project_id
|
2024-02-28 22:45:19 -08:00
|
|
|
subnetwork = module.dmz-vpc.subnet_self_links["${each.value.region}/dmz-default"]
|
2023-04-04 11:41:04 -07:00
|
|
|
address_type = "INTERNAL"
|
2024-02-28 22:45:19 -08:00
|
|
|
address = each.value.ip_dmz
|
2023-04-04 11:41:04 -07:00
|
|
|
region = each.value.region
|
|
|
|
}
|
|
|
|
|
|
|
|
module "nva" {
|
|
|
|
for_each = local.nva_configs
|
|
|
|
source = "../../../modules/compute-vm"
|
|
|
|
project_id = module.landing-project.project_id
|
|
|
|
name = "nva-${each.value.shortname}-${each.value.zone}"
|
|
|
|
instance_type = "e2-standard-2"
|
|
|
|
can_ip_forward = true
|
|
|
|
zone = "${each.value.region}-${each.value.zone}"
|
|
|
|
tags = ["nva"]
|
|
|
|
|
|
|
|
network_interfaces = [
|
|
|
|
{
|
2024-02-28 22:45:19 -08:00
|
|
|
network = module.dmz-vpc.self_link
|
|
|
|
subnetwork = module.dmz-vpc.subnet_self_links["${each.value.region}/dmz-default"]
|
2023-04-04 11:41:04 -07:00
|
|
|
nat = false
|
|
|
|
addresses = {
|
2024-02-28 22:45:19 -08:00
|
|
|
internal = google_compute_address.nva_static_ip_dmz[each.key].address
|
2023-04-04 11:41:04 -07:00
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
2024-02-28 22:45:19 -08:00
|
|
|
network = module.landing-vpc.self_link
|
|
|
|
subnetwork = module.landing-vpc.subnet_self_links["${each.value.region}/landing-default"]
|
2023-04-04 11:41:04 -07:00
|
|
|
nat = false
|
|
|
|
addresses = {
|
2024-02-28 22:45:19 -08:00
|
|
|
internal = google_compute_address.nva_static_ip_landing[each.key].address
|
2023-04-04 11:41:04 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
boot_disk = {
|
|
|
|
initialize_params = {
|
|
|
|
image = "projects/cos-cloud/global/images/family/cos-stable"
|
|
|
|
size = 10
|
|
|
|
type = "pd-balanced"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
options = {
|
|
|
|
allow_stopping_for_update = true
|
|
|
|
deletion_protection = false
|
|
|
|
termination_action = "STOP"
|
|
|
|
}
|
|
|
|
|
|
|
|
metadata = {
|
|
|
|
user-data = module.nva-bgp-cloud-config[each.key].cloud_config
|
|
|
|
}
|
|
|
|
}
|