From f3901fc5671ea0c7e1bd449eada23638b43441d9 Mon Sep 17 00:00:00 2001 From: dsiviglia Date: Wed, 16 Jun 2021 13:56:40 +0200 Subject: [PATCH] module for VLAN attachment+cloud router+bgp (#254) * module for VLAN attachment+cloud router+bgp * fix vlan attachments review comments * run terraform fmt * fix code review comment and build errors * fix for code review comments * code review changes * changes after review * changes after code review * changes after code review --- .../README.md | 131 ++++++++++++++++++ .../main.tf | 98 +++++++++++++ .../outputs.tf | 31 +++++ .../variables.tf | 115 +++++++++++++++ .../versions.tf | 18 +++ 5 files changed, 393 insertions(+) create mode 100644 modules/net-interconnect-attachment-direct/README.md create mode 100644 modules/net-interconnect-attachment-direct/main.tf create mode 100644 modules/net-interconnect-attachment-direct/outputs.tf create mode 100644 modules/net-interconnect-attachment-direct/variables.tf create mode 100644 modules/net-interconnect-attachment-direct/versions.tf diff --git a/modules/net-interconnect-attachment-direct/README.md b/modules/net-interconnect-attachment-direct/README.md new file mode 100644 index 000000000..e9e4c15c1 --- /dev/null +++ b/modules/net-interconnect-attachment-direct/README.md @@ -0,0 +1,131 @@ +# Direct Interconnect VLAN Attachment and router + +This module allows creation of a VLAN attachment for Direct Interconnect and router (router creation is optional). + +## Examples + +### Direct Interconnect VLAN attachment using default parameters for bgp session and router + +```hcl +module "vlan-attachment-1" { + source = "./modules/net-interconnect-attachment-direct" + project_id = "dedicated-ic-5-8492" + region = "us-west2" + router_network = "myvpc" + name = "vlan-604-x" + interconnect = "https://www.googleapis.com/compute/v1/projects/mylab/global/interconnects/mylab-interconnect-1" + peer = { + ip_address = "169.254.63.2" + asn = 65418 + } +} +# tftest:modules=1:resources=4 +``` +#### Direct Interconnect VLAN attachments to achieve 99.9% SLA setup + +```hcl +module "vlan-attachment-1" { + source = "./modules/net-interconnect-attachment-direct" + project_id = "dedicated-ic-3-8386" + region = "us-west2" + router_name = "router-1" + router_config = { + description = "" + asn = 65003 + advertise_config = { + groups = ["ALL_SUBNETS"] + ip_ranges = { + "199.36.153.8/30" = "custom" + } + mode = "CUSTOM" + } + } + router_network = "myvpc" + name = "vlan-603-1" + interconnect = "https://www.googleapis.com/compute/v1/projects/mylab/global/interconnects/mylab-interconnect-1" + + config = { + description = "" + vlan_id = 603 + bandwidth = "BPS_10G" + admin_enabled = true + mtu = 1440 + } + peer = { + ip_address = "169.254.63.2" + asn = 65418 + } + bgp = { + session_range = "169.254.63.1/29" + advertised_route_priority = 0 + candidate_ip_ranges = ["169.254.63.0/29"] + } +} + +module "vlan-attachment-2" { + source = "./modules/net-interconnect-attachment-direct" + project_id = "dedicated-ic-3-8386" + region = "us-west2" + router_name = "router-2" + router_config = { + description = "" + asn = 65003 + advertise_config = { + groups = ["ALL_SUBNETS"] + ip_ranges = { + "199.36.153.8/30" = "custom" + } + mode = "CUSTOM" + } + + } + router_network = "myvpc" + name = "vlan-603-2" + + interconnect = "https://www.googleapis.com/compute/v1/projects/mylab/global/interconnects/mylab-interconnect-2" + + config = { + description = "" + vlan_id = 603 + bandwidth = "BPS_10G" + admin_enabled = true + mtu = 1440 + } + peer = { + ip_address = "169.254.63.10" + asn = 65418 + } + bgp = { + session_range = "169.254.63.9/29" + advertised_route_priority = 0 + candidate_ip_ranges = ["169.254.63.8/29"] + } +} +# tftest:modules=2:resources=8 +``` + + +## Variables + +| name | description | type | required | default | +|---|---|:---: |:---:|:---:| +| interconnect | URL of the underlying Interconnect object that this attachment's traffic will traverse through. | string | ✓ | | +| peer | Peer Ip address and asn. Only IPv4 supported | object({...}) | ✓ | | +| project_id | The project containing the resources | string | ✓ | | +| *bgp* | Bgp session parameters | object({...}) | | null | +| *config* | VLAN attachment parameters: description, vlan_id, bandwidth, admin_enabled, interconnect | object({...}) | | ... | +| *name* | The name of the vlan attachment | string | | vlan-attachment | +| *region* | Region where the router resides | string | | europe-west1-b | +| *router_config* | Router asn and custom advertisement configuration, ip_ranges is a map of address ranges and descriptions.. | object({...}) | | ... | +| *router_create* | Create router. | bool | | true | +| *router_name* | Router name used for auto created router, or to specify an existing router to use if `router_create` is set to `true`. Leave blank to use vlan attachment name for auto created router. | string | | router-vlan-attachment | +| *router_network* | A reference to the network to which this router belongs | string | | null | + +## Outputs + +| name | description | sensitive | +|---|---|:---:| +| bgpsession | bgp session | | +| interconnect_attachment | interconnect attachment | | +| router | Router resource (only if auto-created). | | + diff --git a/modules/net-interconnect-attachment-direct/main.tf b/modules/net-interconnect-attachment-direct/main.tf new file mode 100644 index 000000000..01dd8dbca --- /dev/null +++ b/modules/net-interconnect-attachment-direct/main.tf @@ -0,0 +1,98 @@ + +/** + * Copyright 2021 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 { + router = ( + var.router_create + ? try(google_compute_router.router[0].name, null) + : var.router_name + ) + vlan_interconnect = try(google_compute_interconnect_attachment.interconnect_vlan_attachment.name) +} + +resource "google_compute_router" "router" { + count = var.router_create ? 1 : 0 + project = var.project_id + region = var.region + name = var.router_name == "" ? "router-${var.name}" : var.router_name + description = var.router_config.description + network = var.router_network + bgp { + advertise_mode = ( + var.router_config.advertise_config == null + ? null + : var.router_config.advertise_config.mode + ) + advertised_groups = ( + var.router_config.advertise_config == null ? null : ( + var.router_config.advertise_config.mode != "CUSTOM" + ? null + : var.router_config.advertise_config.groups + ) + ) + dynamic "advertised_ip_ranges" { + for_each = ( + var.router_config.advertise_config == null ? {} : ( + var.router_config.advertise_config.mode != "CUSTOM" + ? null + : var.router_config.advertise_config.ip_ranges + ) + ) + iterator = range + content { + range = range.key + description = range.value + } + } + asn = var.router_config.asn + } +} + +resource "google_compute_interconnect_attachment" "interconnect_vlan_attachment" { + project = var.project_id + region = var.region + router = local.router + name = var.name + description = var.config.description + interconnect = var.interconnect + bandwidth = var.config.bandwidth + mtu = var.config.mtu + vlan_tag8021q = var.config.vlan_id + candidate_subnets = var.bgp == null ? null : var.bgp.candidate_ip_ranges + admin_enabled = var.config.admin_enabled + provider = google-beta +} + +resource "google_compute_router_interface" "interface" { + project = var.project_id + region = var.region + name = "interface-${var.name}" + router = local.router + ip_range = var.bgp == null ? null : var.bgp.session_range + interconnect_attachment = local.vlan_interconnect +} + +resource "google_compute_router_peer" "peer" { + project = var.project_id + region = var.region + name = "bgp-session-${var.name}" + router = local.router + peer_ip_address = var.peer.ip_address + peer_asn = var.peer.asn + advertised_route_priority = var.bgp == null ? null : var.bgp.advertised_route_priority + interface = local.vlan_interconnect +} diff --git a/modules/net-interconnect-attachment-direct/outputs.tf b/modules/net-interconnect-attachment-direct/outputs.tf new file mode 100644 index 000000000..392f4d122 --- /dev/null +++ b/modules/net-interconnect-attachment-direct/outputs.tf @@ -0,0 +1,31 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +output "bgpsession" { + description = "bgp session" + value = google_compute_router_peer.peer +} + +output "interconnect_attachment" { + description = "interconnect attachment" + value = google_compute_interconnect_attachment.interconnect_vlan_attachment +} + +output "router" { + description = "Router resource (only if auto-created)." + value = google_compute_router.router +} + + diff --git a/modules/net-interconnect-attachment-direct/variables.tf b/modules/net-interconnect-attachment-direct/variables.tf new file mode 100644 index 000000000..69d837c20 --- /dev/null +++ b/modules/net-interconnect-attachment-direct/variables.tf @@ -0,0 +1,115 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "bgp" { + description = "Bgp session parameters" + type = object({ + session_range = string + candidate_ip_ranges = list(string) + advertised_route_priority = number + + }) + default = null +} + +variable "config" { + description = "VLAN attachment parameters: description, vlan_id, bandwidth, admin_enabled, interconnect" + type = object({ + description = string + vlan_id = number + bandwidth = string + admin_enabled = bool + mtu = number + }) + default = { + description = null + vlan_id = null + bandwidth = "BPS_10G" + admin_enabled = true + mtu = 1440 + } +} + +variable "interconnect" { + description = "URL of the underlying Interconnect object that this attachment's traffic will traverse through." + type = string +} + +variable "name" { + description = "The name of the vlan attachment" + type = string + default = "vlan-attachment" +} + +variable "peer" { + description = "Peer Ip address and asn. Only IPv4 supported" + type = object({ + ip_address = string + asn = number + }) +} + +variable "project_id" { + description = "The project containing the resources" + type = string +} + +variable "region" { + description = "Region where the router resides" + type = string + default = "europe-west1-b" +} + +variable "router_config" { + description = "Router asn and custom advertisement configuration, ip_ranges is a map of address ranges and descriptions.. " + type = object({ + description = string + asn = number + advertise_config = object({ + groups = list(string) + ip_ranges = map(string) + mode = string + }) + }) + + default = { + description = null + asn = 64514 + advertise_config = null + } +} + +variable "router_create" { + description = "Create router." + type = bool + default = true +} + +variable "router_name" { + description = "Router name used for auto created router, or to specify an existing router to use if `router_create` is set to `true`. Leave blank to use vlan attachment name for auto created router." + type = string + default = "router-vlan-attachment" +} + +variable "router_network" { + description = "A reference to the network to which this router belongs" + type = string + default = null +} + + + + diff --git a/modules/net-interconnect-attachment-direct/versions.tf b/modules/net-interconnect-attachment-direct/versions.tf new file mode 100644 index 000000000..897f817c2 --- /dev/null +++ b/modules/net-interconnect-attachment-direct/versions.tf @@ -0,0 +1,18 @@ +/** + * Copyright 2021 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. + */ +terraform { + required_version = ">= 0.12.6" +} \ No newline at end of file