Reimplement the module to manage only one spoke

This commit is contained in:
Julio Diez 2023-03-08 14:14:02 +01:00
parent 6eb82a2214
commit 2f64fcd5f4
2 changed files with 91 additions and 66 deletions

View File

@ -15,17 +15,13 @@
*/ */
locals { locals {
spoke_vms = flatten([ spoke_vms = [
for spoke_key, spoke in var.spokes : [ for ras in var.ras : {
for nva in spoke.nvas : { ip = ras.ip
ip = nva.ip vm = ras.vm
vm = nva.vm vm_name = element(split("/", ras.vm), length(split("/", ras.vm)) - 1)
vm_name = element(split("/", nva.vm), length(split("/", nva.vm)) - 1) }
spoke_key = spoke_key ]
spoke = spoke
}
]
])
} }
resource "google_network_connectivity_hub" "hub" { resource "google_network_connectivity_hub" "hub" {
@ -34,69 +30,65 @@ resource "google_network_connectivity_hub" "hub" {
description = var.description description = var.description
} }
resource "google_network_connectivity_spoke" "spoke" { resource "google_network_connectivity_spoke" "spoke-ra" {
for_each = var.spokes
project = var.project_id project = var.project_id
hub = google_network_connectivity_hub.hub.id hub = google_network_connectivity_hub.hub.id
location = each.value.region location = var.region
name = "${var.name}-${each.key}" name = var.name
linked_router_appliance_instances { linked_router_appliance_instances {
dynamic "instances" { dynamic "instances" {
for_each = each.value.nvas for_each = var.ras
content { content {
virtual_machine = instances.value["vm"] virtual_machine = instances.value["vm"]
ip_address = instances.value["ip"] ip_address = instances.value["ip"]
} }
} }
site_to_site_data_transfer = false site_to_site_data_transfer = var.data_transfer
} }
} }
resource "google_compute_router" "cr" { resource "google_compute_router" "cr" {
for_each = var.spokes project = var.project_id
project = var.project_id name = "${var.name}-cr"
name = "${var.name}-${each.key}-cr" network = var.vpc
network = each.value.vpc region = var.region
region = each.value.region
bgp { bgp {
advertise_mode = ( advertise_mode = (
each.value.router.custom_advertise != null ? "CUSTOM" : "DEFAULT" var.custom_advertise != null ? "CUSTOM" : "DEFAULT"
) )
advertised_groups = ( advertised_groups = (
try(each.value.router.custom_advertise.all_subnets, false) try(var.custom_advertise.all_subnets, false)
? ["ALL_SUBNETS"] : [] ? ["ALL_SUBNETS"] : []
) )
dynamic "advertised_ip_ranges" { dynamic "advertised_ip_ranges" {
for_each = try(each.value.router.custom_advertise.ip_ranges, {}) for_each = try(var.custom_advertise.ip_ranges, {})
content { content {
description = advertised_ip_ranges.key description = advertised_ip_ranges.key
range = advertised_ip_ranges.value range = advertised_ip_ranges.value
} }
} }
asn = var.asn asn = var.asn
keepalive_interval = try(each.value.router.keepalive, null) keepalive_interval = try(var.keepalive, null)
} }
} }
resource "google_compute_router_interface" "intf1" { resource "google_compute_router_interface" "intf1" {
for_each = var.spokes
project = var.project_id project = var.project_id
name = "intf1" name = "intf1"
router = google_compute_router.cr[each.key].name router = google_compute_router.cr.name
region = each.value.region region = var.region
subnetwork = each.value.subnetwork subnetwork = var.subnetwork
private_ip_address = each.value.router.ip1 private_ip_address = var.ip_intf1
} }
resource "google_compute_router_interface" "intf2" { resource "google_compute_router_interface" "intf2" {
for_each = var.spokes
project = var.project_id project = var.project_id
name = "intf2" name = "intf2"
router = google_compute_router.cr[each.key].name router = google_compute_router.cr.name
region = each.value.region region = var.region
subnetwork = each.value.subnetwork subnetwork = var.subnetwork
private_ip_address = each.value.router.ip2 private_ip_address = var.ip_intf2
redundant_interface = google_compute_router_interface.intf1[each.key].name redundant_interface = google_compute_router_interface.intf1.name
} }
resource "google_compute_router_peer" "peer1" { resource "google_compute_router_peer" "peer1" {
@ -105,10 +97,10 @@ resource "google_compute_router_peer" "peer1" {
} }
project = var.project_id project = var.project_id
name = "peer1-${each.value.vm_name}" name = "peer1-${each.value.vm_name}"
router = google_compute_router.cr[each.value.spoke_key].name router = google_compute_router.cr.name
region = each.value.spoke.region region = var.region
interface = google_compute_router_interface.intf1[each.value.spoke_key].name interface = google_compute_router_interface.intf1.name
peer_asn = each.value.spoke.router.peer_asn peer_asn = var.peer_asn
peer_ip_address = each.value.ip peer_ip_address = each.value.ip
router_appliance_instance = each.value.vm router_appliance_instance = each.value.vm
} }
@ -119,10 +111,10 @@ resource "google_compute_router_peer" "peer2" {
} }
project = var.project_id project = var.project_id
name = "peer2-${each.value.vm_name}" name = "peer2-${each.value.vm_name}"
router = google_compute_router.cr[each.value.spoke_key].name router = google_compute_router.cr.name
region = each.value.spoke.region region = var.region
interface = google_compute_router_interface.intf2[each.value.spoke_key].name interface = google_compute_router_interface.intf2.name
peer_asn = each.value.spoke.router.peer_asn peer_asn = var.peer_asn
peer_ip_address = each.value.ip peer_ip_address = each.value.ip
router_appliance_instance = each.value.vm router_appliance_instance = each.value.vm
} }

View File

@ -15,45 +15,78 @@
*/ */
variable "asn" { variable "asn" {
description = "ASN for all CRs in the hub." description = "Autonomous System Number for the CR. All spokes in a hub should use the same ASN."
type = number type = number
} }
variable "custom_advertise" {
description = "IP ranges to advertise if not using default route advertisement (subnet ranges)."
type = object({
all_subnets = bool
ip_ranges = map(string) # map of descriptions and address ranges
})
}
variable "data_transfer" {
description = "Site-to-site data transfer feature, available only in some regions."
type = bool
}
variable "description" { variable "description" {
description = "An optional description of the NCC hub." description = "An optional description of the NCC hub."
type = string type = string
default = "Terraform-managed." default = "Terraform-managed."
} }
variable "ip_intf1" {
description = "IP address for the CR interface 1. It must belong to the primary range of the subnet."
type = string
}
variable "ip_intf2" {
description = "IP address for the CR interface 2. It must belong to the primary range of the subnet."
type = string
}
variable "keepalive" {
description = "The interval in seconds between BGP keepalive messages that are sent to the peer."
type = number
}
variable "name" { variable "name" {
description = "The name of the NCC hub being created." description = "The name of the NCC hub being created."
type = string type = string
} }
variable "peer_asn" {
description = "Peer Autonomous System Number used by the router appliances."
type = number
}
variable "project_id" { variable "project_id" {
description = "The ID of the project where the NCC hub & spokes will be created." description = "The ID of the project where the NCC hub & spokes will be created."
type = string type = string
} }
variable "spokes" { variable "ras" {
description = "List of NCC spokes." description = "List of router appliances this spoke is associated with."
type = map(object({ type = list(object({
vpc = string vm = string # URI
region = string ip = string
subnetwork = string # URI
nvas = list(object({
vm = string # URI
ip = string
}))
router = object({
custom_advertise = optional(object({
all_subnets = bool
ip_ranges = map(string) # map of descriptions and address ranges
}))
ip1 = string
ip2 = string
keepalive = optional(number)
peer_asn = number
})
})) }))
} }
variable "region" {
description = "Region where the spoke is located."
type = string
}
variable "subnetwork" {
description = "The URI of the subnetwork that CR interfaces belong to."
type = string
}
variable "vpc" {
description = "A reference to the network to which the CR belongs."
type = string
}