diff --git a/modules/net-lb-app-ext-regional/README.md b/modules/net-lb-app-ext-regional/README.md index f2c199b18..44ae6c05c 100644 --- a/modules/net-lb-app-ext-regional/README.md +++ b/modules/net-lb-app-ext-regional/README.md @@ -21,6 +21,7 @@ The variable space of this module closely mirrors that of [net-lb-app-ext](../n - [Managed Instance Groups](#managed-instance-groups) - [Zonal NEG creation](#zonal-neg-creation) - [Hybrid NEG creation](#hybrid-neg-creation) + - [Internet NEG creation](#internet-neg-creation) - [Private Service Connect NEG creation](#private-service-connect-neg-creation) - [Serverless NEG creation](#serverless-neg-creation) - [Cross Project Backend](#cross-project-backend) @@ -311,12 +312,14 @@ This example shows how to use the module with a manage instance group as backend ```hcl module "win-template" { - source = "./fabric/modules/compute-vm" - project_id = var.project_id - zone = "${var.region}-a" - name = "win-template" - instance_type = "n2d-standard-2" - create_template = {} + source = "./fabric/modules/compute-vm" + project_id = var.project_id + zone = "${var.region}-a" + name = "win-template" + instance_type = "n2d-standard-2" + create_template = { + regional = false + } boot_disk = { initialize_params = { image = "projects/windows-cloud/global/images/windows-server-2019-dc-v20221214" @@ -426,20 +429,17 @@ module "ralb-0" { region = var.region backend_service_configs = { default = { - backends = [ - { - backend = "neg-0" - balancing_mode = "RATE" - max_rate = { per_endpoint = 10 } - } - ] + backends = [{ + backend = "hybrid-neg" + }] } } neg_configs = { - neg-0 = { + hybrid-neg = { hybrid = { network = var.vpc.self_link zone = "${var.region}-b" + # default_port = 80 endpoints = { e-0 = { ip_address = "10.0.0.10" @@ -453,6 +453,53 @@ module "ralb-0" { # tftest modules=1 resources=7 e2e ``` +#### Internet NEG creation + +You can create internet NEGs with either FQDN or IP address endpoints: + +```hcl +module "ralb-0" { + source = "./fabric/modules/net-lb-app-ext-regional" + project_id = var.project_id + name = "ralb-test-0" + vpc = var.vpc.self_link + region = var.region + backend_service_configs = { + default = { + backends = [ + { backend = "internet-neg-fqdn" }, + { backend = "internet-neg-ip" } + ] + } + } + neg_configs = { + internet-neg-fqdn = { + internet = { + region = var.region + endpoints = { + e-0 = { + fqdn = "example.com" + port = 443 + } + } + } + } + internet-neg-ip = { + internet = { + region = var.region + endpoints = { + e-0 = { + ip_address = "192.0.2.5" + port = 443 + } + } + } + } + } +} +# tftest skip +``` + #### Private Service Connect NEG creation ```hcl @@ -725,9 +772,7 @@ module "ralb-0" { } # tftest modules=3 resources=18 fixtures=fixtures/compute-vm-group-bc.tf e2e ``` - ## Deploying changes to load balancer configurations - For deploying changes to load balancer configuration please refer to [net-lb-app-ext README.md](../net-lb-app-ext/README.md#deploying-changes-to-load-balancer-configurations) @@ -740,7 +785,7 @@ For deploying changes to load balancer configuration please refer to [net-lb-app | [groups.tf](./groups.tf) | None | google_compute_instance_group | | [health-check.tf](./health-check.tf) | Health check resource. | google_compute_region_health_check | | [main.tf](./main.tf) | Module-level locals and resources. | google_compute_forwarding_rule · google_compute_region_ssl_certificate · google_compute_region_target_http_proxy · google_compute_region_target_https_proxy | -| [negs.tf](./negs.tf) | NEG resources. | google_compute_network_endpoint · google_compute_network_endpoint_group · google_compute_region_network_endpoint_group | +| [negs.tf](./negs.tf) | NEG resources. | google_compute_network_endpoint · google_compute_network_endpoint_group · google_compute_region_network_endpoint · google_compute_region_network_endpoint_group | | [outputs.tf](./outputs.tf) | Module outputs. | | | [urlmap.tf](./urlmap.tf) | URL map resources. | google_compute_region_url_map | | [variables-backend-service.tf](./variables-backend-service.tf) | Backend services variables. | | @@ -754,9 +799,9 @@ For deploying changes to load balancer configuration please refer to [net-lb-app | name | description | type | required | default | |---|---|:---:|:---:|:---:| | [name](variables.tf#L59) | Load balancer name. | string | ✓ | | -| [project_id](variables.tf#L162) | Project id. | string | ✓ | | -| [region](variables.tf#L180) | Region where the load balancer is created. | string | ✓ | | -| [vpc](variables.tf#L199) | VPC-level configuration. | string | ✓ | | +| [project_id](variables.tf#L184) | Project id. | string | ✓ | | +| [region](variables.tf#L202) | Region where the load balancer is created. | string | ✓ | | +| [vpc](variables.tf#L221) | VPC-level configuration. | string | ✓ | | | [address](variables.tf#L17) | Optional IP address used for the forwarding rule. | string | | null | | [backend_service_configs](variables-backend-service.tf#L19) | Backend service level configuration. | map(object({…})) | | {} | | [description](variables.tf#L23) | Optional description used for resources. | string | | "Terraform managed." | @@ -764,11 +809,11 @@ For deploying changes to load balancer configuration please refer to [net-lb-app | [health_check_configs](variables-health-check.tf#L19) | Optional auto-created health check configurations, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | map(object({…})) | | {…} | | [https_proxy_config](variables.tf#L41) | HTTPS proxy connfiguration. | object({…}) | | {} | | [labels](variables.tf#L53) | Labels set on resources. | map(string) | | {} | -| [neg_configs](variables.tf#L64) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | -| [network_tier_standard](variables.tf#L145) | Use standard network tier. | bool | | true | -| [ports](variables.tf#L152) | Optional ports for HTTP load balancer. | list(string) | | null | -| [protocol](variables.tf#L167) | Protocol supported by this load balancer. | string | | "HTTP" | -| [ssl_certificates](variables.tf#L185) | SSL target proxy certificates (only if protocol is HTTPS) for existing, custom, and managed certificates. | object({…}) | | {} | +| [neg_configs](variables.tf#L64) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | +| [network_tier_standard](variables.tf#L167) | Use standard network tier. | bool | | true | +| [ports](variables.tf#L174) | Optional ports for HTTP load balancer. | list(string) | | null | +| [protocol](variables.tf#L189) | Protocol supported by this load balancer. | string | | "HTTP" | +| [ssl_certificates](variables.tf#L207) | SSL target proxy certificates (only if protocol is HTTPS) for existing, custom, and managed certificates. | object({…}) | | {} | | [urlmap_config](variables-urlmap.tf#L19) | The URL map configuration. | object({…}) | | {…} | ## Outputs diff --git a/modules/net-lb-app-ext-regional/backend-service.tf b/modules/net-lb-app-ext-regional/backend-service.tf index d1a78bba6..75dc946f6 100644 --- a/modules/net-lb-app-ext-regional/backend-service.tf +++ b/modules/net-lb-app-ext-regional/backend-service.tf @@ -24,6 +24,9 @@ locals { { for k, v in google_compute_network_endpoint_group.default : k => v.id }, + { + for k, v in google_compute_region_network_endpoint_group.internet : k => v.id + }, { for k, v in google_compute_region_network_endpoint_group.psc : k => v.id }, diff --git a/modules/net-lb-app-ext-regional/negs.tf b/modules/net-lb-app-ext-regional/negs.tf index 1b1bb662a..0123987e9 100644 --- a/modules/net-lb-app-ext-regional/negs.tf +++ b/modules/net-lb-app-ext-regional/negs.tf @@ -27,6 +27,20 @@ locals { neg_endpoints_zonal = { for v in local._neg_endpoints_zonal : (v.key) => v } + + neg_regional_internet = { + for k, v in var.neg_configs : + k => merge(v, { + # Calculate the endpoint type based on the first endpoint + # If any endpoint has fqdn, we'll use FQDN_PORT, otherwise IP_PORT + endpoint_type = length(v.internet.endpoints) > 0 ? ( + alltrue([ + for e_key, e in v.internet.endpoints : e.fqdn == null + ]) ? "INTERNET_IP_PORT" : "INTERNET_FQDN_PORT" + ) : "INTERNET_FQDN_PORT" # Default if no endpoints + }) if v.internet != null + } + neg_regional_psc = { for k, v in var.neg_configs : k => v if v.psc != null @@ -46,6 +60,24 @@ locals { zone = v.gce != null ? v.gce.zone : v.hybrid.zone } if v.gce != null || v.hybrid != null } + + # Create a map of Internet NEG endpoints for for_each + internet_neg_endpoints = { + for endpoint in flatten([ + for neg_key, neg in local.neg_regional_internet : [ + for endpoint_key, endpoint in neg.internet.endpoints : { + id = "${neg_key}-${endpoint_key}" + neg_key = neg_key + endpoint_key = endpoint_key + region = neg.internet.region + fqdn = try(endpoint.fqdn, null) + ip_address = try(endpoint.ip_address, null) + port = endpoint.port + endpoint_type = neg.endpoint_type + } + ] + ]) : endpoint.id => endpoint + } } resource "google_compute_network_endpoint_group" "default" { @@ -79,6 +111,28 @@ resource "google_compute_network_endpoint" "default" { zone = each.value.zone } +resource "google_compute_region_network_endpoint_group" "internet" { + for_each = local.neg_regional_internet + project = var.project_id + region = each.value.internet.region + name = "${var.name}-${each.key}" + description = coalesce(each.value.description, var.description) + network_endpoint_type = each.value.endpoint_type + network = each.value.internet.network +} + +resource "google_compute_region_network_endpoint" "internet" { + for_each = local.internet_neg_endpoints + region = each.value.region + region_network_endpoint_group = google_compute_region_network_endpoint_group.internet[each.value.neg_key].name + # Only set fqdn if endpoint type is FQDN_PORT + fqdn = each.value.endpoint_type == "INTERNET_FQDN_PORT" ? each.value.fqdn : null + # Only set ip_address if endpoint type is IP_PORT + ip_address = each.value.endpoint_type == "INTERNET_IP_PORT" ? each.value.ip_address : null + port = each.value.port + project = var.project_id +} + resource "google_compute_region_network_endpoint_group" "psc" { for_each = local.neg_regional_psc project = var.project_id diff --git a/modules/net-lb-app-ext-regional/outputs.tf b/modules/net-lb-app-ext-regional/outputs.tf index dc1824be2..e47e155ad 100644 --- a/modules/net-lb-app-ext-regional/outputs.tf +++ b/modules/net-lb-app-ext-regional/outputs.tf @@ -59,7 +59,18 @@ output "id" { output "neg_ids" { description = "Autogenerated network endpoint group ids." - value = { - for k, v in google_compute_network_endpoint_group.default : k => v.id - } + value = merge( + { + for k, v in google_compute_network_endpoint_group.default : k => v.id + }, + { + for k, v in google_compute_region_network_endpoint_group.internet : k => v.id + }, + { + for k, v in google_compute_region_network_endpoint_group.psc : k => v.id + }, + { + for k, v in google_compute_region_network_endpoint_group.serverless : k => v.id + } + ) } diff --git a/modules/net-lb-app-ext-regional/variables-backend-service.tf b/modules/net-lb-app-ext-regional/variables-backend-service.tf index 3cd2933fd..78146d431 100644 --- a/modules/net-lb-app-ext-regional/variables-backend-service.tf +++ b/modules/net-lb-app-ext-regional/variables-backend-service.tf @@ -125,9 +125,7 @@ variable "backend_service_configs" { for backend_service in values(var.backend_service_configs) : contains( [ "NONE", "CLIENT_IP", "CLIENT_IP_NO_DESTINATION", - "CLIENT_IP_PORT_PROTO", "CLIENT_IP_PROTO", - "GENERATED_COOKIE", "HEADER_FIELD", "HTTP_COOKIE", - "STRONG_COOKIE_AFFINITY" + "CLIENT_IP_PORT_PROTO", "CLIENT_IP_PROTO" ], coalesce(backend_service.session_affinity, "NONE") ) diff --git a/modules/net-lb-app-ext-regional/variables.tf b/modules/net-lb-app-ext-regional/variables.tf index b07e1e07f..65e793d7d 100644 --- a/modules/net-lb-app-ext-regional/variables.tf +++ b/modules/net-lb-app-ext-regional/variables.tf @@ -99,6 +99,15 @@ variable "neg_configs" { port = number }))) })) + internet = optional(object({ + region = string + network = string + endpoints = map(object({ + fqdn = optional(string) + ip_address = optional(string) + port = number + })) + })) psc = optional(object({ region = string target_service = string @@ -115,6 +124,7 @@ variable "neg_configs" { (try(v.cloudrun, null) == null ? 0 : 1) + (try(v.gce, null) == null ? 0 : 1) + (try(v.hybrid, null) == null ? 0 : 1) + + (try(v.internet, null) == null ? 0 : 1) + (try(v.psc, null) == null ? 0 : 1) == 1 ) ]) @@ -140,6 +150,18 @@ variable "neg_configs" { ]) error_message = "Cloud Function NEGs need either target function or target urlmask defined." } + validation { + condition = alltrue([ + for k, v in var.neg_configs : ( + v.internet == null + ? true + : alltrue([ + for ek, ev in v.internet.endpoints : (ev.fqdn != null || ev.ip_address != null) + ]) + ) + ]) + error_message = "Internet NEG endpoints must specify either fqdn or ip_address." + } } variable "network_tier_standard" {