Merge pull request #1981 from apichick/cross-region-ilb-l7
Added Cross-region internal application load balancer module
This commit is contained in:
commit
e5de2ed31f
|
@ -30,7 +30,7 @@ The current list of modules supports most of the core foundational and networkin
|
||||||
Currently available modules:
|
Currently available modules:
|
||||||
|
|
||||||
- **foundational** - [billing account](./modules/billing-account), [Cloud Identity group](./modules/cloud-identity-group/), [folder](./modules/folder), [service accounts](./modules/iam-service-account), [logging bucket](./modules/logging-bucket), [organization](./modules/organization), [project](./modules/project), [projects-data-source](./modules/projects-data-source)
|
- **foundational** - [billing account](./modules/billing-account), [Cloud Identity group](./modules/cloud-identity-group/), [folder](./modules/folder), [service accounts](./modules/iam-service-account), [logging bucket](./modules/logging-bucket), [organization](./modules/organization), [project](./modules/project), [projects-data-source](./modules/projects-data-source)
|
||||||
- **networking** - [DNS](./modules/dns), [DNS Response Policy](./modules/dns-response-policy/), [Cloud Endpoints](./modules/endpoints), [address reservation](./modules/net-address), [NAT](./modules/net-cloudnat), [VLAN Attachment](./modules/net-vlan-attachment/), [External Application LB](./modules/net-lb-app-ext/), [External Passthrough Network LB](./modules/net-lb-ext), [External Regional Application Load Balancer](./modules/net-lb-app-ext-regional/), [Firewall policy](./modules/net-firewall-policy), [Internal Application LB](./modules/net-lb-app-int), [Internal Passthrough Network LB](./modules/net-lb-int), [Internal Proxy Network LB](./modules/net-lb-proxy-int), [IPSec over Interconnect](./modules/net-ipsec-over-interconnect), [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC peering](./modules/net-vpc-peering), [VPN dynamic](./modules/net-vpn-dynamic), [HA VPN](./modules/net-vpn-ha), [VPN static](./modules/net-vpn-static), [Service Directory](./modules/service-directory), [Secure Web Proxy](./modules/net-swp)
|
- **networking** - [DNS](./modules/dns), [DNS Response Policy](./modules/dns-response-policy/), [Cloud Endpoints](./modules/endpoints), [address reservation](./modules/net-address), [NAT](./modules/net-cloudnat), [VLAN Attachment](./modules/net-vlan-attachment/), [External Application LB](./modules/net-lb-app-ext/), [External Passthrough Network LB](./modules/net-lb-ext), [External Regional Application Load Balancer](./modules/net-lb-app-ext-regional/), [Firewall policy](./modules/net-firewall-policy), [Internal Application LB](./modules/net-lb-app-int), [Cross-region Internal Application LB](./modules/net-lb-app-int-cross-region), [Internal Passthrough Network LB](./modules/net-lb-int), [Internal Proxy Network LB](./modules/net-lb-proxy-int), [IPSec over Interconnect](./modules/net-ipsec-over-interconnect), [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC peering](./modules/net-vpc-peering), [VPN dynamic](./modules/net-vpn-dynamic), [HA VPN](./modules/net-vpn-ha), [VPN static](./modules/net-vpn-static), [Service Directory](./modules/service-directory), [Secure Web Proxy](./modules/net-swp)
|
||||||
- **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [COS container](./modules/cloud-config-container/cos-generic-metadata/) (coredns, mysql, onprem, squid), [GKE cluster](./modules/gke-cluster-standard), [GKE hub](./modules/gke-hub), [GKE nodepool](./modules/gke-nodepool), [GCVE private cloud](./modules/gcve-private-cloud)
|
- **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [COS container](./modules/cloud-config-container/cos-generic-metadata/) (coredns, mysql, onprem, squid), [GKE cluster](./modules/gke-cluster-standard), [GKE hub](./modules/gke-hub), [GKE nodepool](./modules/gke-nodepool), [GCVE private cloud](./modules/gcve-private-cloud)
|
||||||
- **data** - <!-- [AlloyDB instance](./modules/alloydb-instance), --> [BigQuery dataset](./modules/bigquery-dataset), [Bigtable instance](./modules/bigtable-instance), [Dataplex](./modules/dataplex), [Dataplex DataScan](./modules/dataplex-datascan/), [Cloud SQL instance](./modules/cloudsql-instance), [Data Catalog Policy Tag](./modules/data-catalog-policy-tag), [Datafusion](./modules/datafusion), [Dataproc](./modules/dataproc), [GCS](./modules/gcs), [Pub/Sub](./modules/pubsub)
|
- **data** - <!-- [AlloyDB instance](./modules/alloydb-instance), --> [BigQuery dataset](./modules/bigquery-dataset), [Bigtable instance](./modules/bigtable-instance), [Dataplex](./modules/dataplex), [Dataplex DataScan](./modules/dataplex-datascan/), [Cloud SQL instance](./modules/cloudsql-instance), [Data Catalog Policy Tag](./modules/data-catalog-policy-tag), [Datafusion](./modules/datafusion), [Dataproc](./modules/dataproc), [GCS](./modules/gcs), [Pub/Sub](./modules/pubsub)
|
||||||
- **development** - [API Gateway](./modules/api-gateway), [Apigee](./modules/apigee), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository), [Workstation cluster](./modules/workstation-cluster)
|
- **development** - [API Gateway](./modules/api-gateway), [Apigee](./modules/apigee), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository), [Workstation cluster](./modules/workstation-cluster)
|
||||||
|
|
|
@ -50,6 +50,7 @@ These modules are used in the examples included in this repository. If you are u
|
||||||
- [External Passthrough Network Load Balancer](./net-lb-ext)
|
- [External Passthrough Network Load Balancer](./net-lb-ext)
|
||||||
- [External Regional Application Load Balancer](./net-lb-app-ext-regional/)
|
- [External Regional Application Load Balancer](./net-lb-app-ext-regional/)
|
||||||
- [Internal Application Load Balancer](./net-lb-app-int)
|
- [Internal Application Load Balancer](./net-lb-app-int)
|
||||||
|
- [Cross-region Internal Application Load Balancer](./net-lb-app-int-cross-region)
|
||||||
- [Internal Passthrough Network Load Balancer](./net-lb-int)
|
- [Internal Passthrough Network Load Balancer](./net-lb-int)
|
||||||
- [Internal Proxy Network Load Balancer](./net-lb-proxy-int)
|
- [Internal Proxy Network Load Balancer](./net-lb-proxy-int)
|
||||||
- [NAT](./net-cloudnat)
|
- [NAT](./net-cloudnat)
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,194 @@
|
||||||
|
/**
|
||||||
|
* 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 Backend service resources.
|
||||||
|
|
||||||
|
locals {
|
||||||
|
group_ids = merge(
|
||||||
|
{
|
||||||
|
for k, v in google_compute_instance_group.default : k => v.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
for k, v in google_compute_network_endpoint_group.default : k => v.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
for k, v in google_compute_region_network_endpoint_group.default : k => v.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
for k, v in google_compute_region_network_endpoint_group.psc : k => v.id
|
||||||
|
}
|
||||||
|
)
|
||||||
|
hc_ids = {
|
||||||
|
for k, v in google_compute_health_check.default : k => v.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_backend_service" "default" {
|
||||||
|
provider = google-beta
|
||||||
|
for_each = var.backend_service_configs
|
||||||
|
project = (
|
||||||
|
each.value.project_id == null
|
||||||
|
? var.project_id
|
||||||
|
: each.value.project_id
|
||||||
|
)
|
||||||
|
name = "${var.name}-${each.key}"
|
||||||
|
description = var.description
|
||||||
|
affinity_cookie_ttl_sec = each.value.affinity_cookie_ttl_sec
|
||||||
|
connection_draining_timeout_sec = each.value.connection_draining_timeout_sec
|
||||||
|
health_checks = length(each.value.health_checks) == 0 ? null : [
|
||||||
|
for k in each.value.health_checks : lookup(local.hc_ids, k, k)
|
||||||
|
] # not for internet / serverless NEGs
|
||||||
|
locality_lb_policy = each.value.locality_lb_policy
|
||||||
|
load_balancing_scheme = "INTERNAL_MANAGED"
|
||||||
|
port_name = each.value.port_name # defaults to http, not for NEGs
|
||||||
|
protocol = (
|
||||||
|
each.value.protocol == null ? var.protocol : each.value.protocol
|
||||||
|
)
|
||||||
|
session_affinity = each.value.session_affinity
|
||||||
|
timeout_sec = each.value.timeout_sec
|
||||||
|
|
||||||
|
dynamic "backend" {
|
||||||
|
for_each = { for b in coalesce(each.value.backends, []) : b.group => b }
|
||||||
|
content {
|
||||||
|
group = lookup(local.group_ids, backend.key, backend.key)
|
||||||
|
balancing_mode = backend.value.balancing_mode
|
||||||
|
capacity_scaler = backend.value.capacity_scaler
|
||||||
|
description = backend.value.description
|
||||||
|
max_connections = try(
|
||||||
|
backend.value.max_connections.per_group, null
|
||||||
|
)
|
||||||
|
max_connections_per_endpoint = try(
|
||||||
|
backend.value.max_connections.per_endpoint, null
|
||||||
|
)
|
||||||
|
max_connections_per_instance = try(
|
||||||
|
backend.value.max_connections.per_instance, null
|
||||||
|
)
|
||||||
|
max_rate = try(
|
||||||
|
backend.value.max_rate.per_group, null
|
||||||
|
)
|
||||||
|
max_rate_per_endpoint = try(
|
||||||
|
backend.value.max_rate.per_endpoint, null
|
||||||
|
)
|
||||||
|
max_rate_per_instance = try(
|
||||||
|
backend.value.max_rate.per_instance, null
|
||||||
|
)
|
||||||
|
max_utilization = backend.value.max_utilization
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "circuit_breakers" {
|
||||||
|
for_each = (
|
||||||
|
each.value.circuit_breakers == null ? [] : [each.value.circuit_breakers]
|
||||||
|
)
|
||||||
|
iterator = cb
|
||||||
|
content {
|
||||||
|
max_connections = cb.value.max_connections
|
||||||
|
max_pending_requests = cb.value.max_pending_requests
|
||||||
|
max_requests = cb.value.max_requests
|
||||||
|
max_requests_per_connection = cb.value.max_requests_per_connection
|
||||||
|
max_retries = cb.value.max_retries
|
||||||
|
dynamic "connect_timeout" {
|
||||||
|
for_each = (
|
||||||
|
cb.value.connect_timeout == null ? [] : [cb.value.connect_timeout]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
seconds = connect_timeout.value.seconds
|
||||||
|
nanos = connect_timeout.value.nanos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "consistent_hash" {
|
||||||
|
for_each = (
|
||||||
|
each.value.consistent_hash == null ? [] : [each.value.consistent_hash]
|
||||||
|
)
|
||||||
|
iterator = ch
|
||||||
|
content {
|
||||||
|
http_header_name = ch.value.http_header_name
|
||||||
|
minimum_ring_size = ch.value.minimum_ring_size
|
||||||
|
dynamic "http_cookie" {
|
||||||
|
for_each = ch.value.http_cookie == null ? [] : [ch.value.http_cookie]
|
||||||
|
content {
|
||||||
|
name = http_cookie.value.name
|
||||||
|
path = http_cookie.value.path
|
||||||
|
dynamic "ttl" {
|
||||||
|
for_each = (
|
||||||
|
http_cookie.value.ttl == null ? [] : [http_cookie.value.ttl]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
seconds = ttl.value.seconds
|
||||||
|
nanos = ttl.value.nanos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "iap" {
|
||||||
|
for_each = each.value.iap_config == null ? [] : [each.value.iap_config]
|
||||||
|
content {
|
||||||
|
oauth2_client_id = iap.value.oauth2_client_id
|
||||||
|
oauth2_client_secret = iap.value.oauth2_client_secret
|
||||||
|
oauth2_client_secret_sha256 = iap.value.oauth2_client_secret_sha256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "log_config" {
|
||||||
|
for_each = each.value.log_sample_rate == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
enable = true
|
||||||
|
sample_rate = each.value.log_sample_rate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "outlier_detection" {
|
||||||
|
for_each = (
|
||||||
|
each.value.outlier_detection == null ? [] : [each.value.outlier_detection]
|
||||||
|
)
|
||||||
|
iterator = od
|
||||||
|
content {
|
||||||
|
consecutive_errors = od.value.consecutive_errors
|
||||||
|
consecutive_gateway_failure = od.value.consecutive_gateway_failure
|
||||||
|
enforcing_consecutive_errors = od.value.enforcing_consecutive_errors
|
||||||
|
enforcing_consecutive_gateway_failure = od.value.enforcing_consecutive_gateway_failure
|
||||||
|
enforcing_success_rate = od.value.enforcing_success_rate
|
||||||
|
max_ejection_percent = od.value.max_ejection_percent
|
||||||
|
success_rate_minimum_hosts = od.value.success_rate_minimum_hosts
|
||||||
|
success_rate_request_volume = od.value.success_rate_request_volume
|
||||||
|
success_rate_stdev_factor = od.value.success_rate_stdev_factor
|
||||||
|
dynamic "base_ejection_time" {
|
||||||
|
for_each = (
|
||||||
|
od.value.base_ejection_time == null ? [] : [od.value.base_ejection_time]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
seconds = base_ejection_time.value.seconds
|
||||||
|
nanos = base_ejection_time.value.nanos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "interval" {
|
||||||
|
for_each = (
|
||||||
|
od.value.interval == null ? [] : [od.value.interval]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
seconds = interval.value.seconds
|
||||||
|
nanos = interval.value.nanos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
resource "google_compute_instance_group" "default" {
|
||||||
|
for_each = var.group_configs
|
||||||
|
project = (
|
||||||
|
each.value.project_id == null
|
||||||
|
? var.project_id
|
||||||
|
: each.value.project_id
|
||||||
|
)
|
||||||
|
zone = each.value.zone
|
||||||
|
name = "${var.name}-${each.key}"
|
||||||
|
description = var.description
|
||||||
|
instances = each.value.instances
|
||||||
|
|
||||||
|
dynamic "named_port" {
|
||||||
|
for_each = each.value.named_ports
|
||||||
|
content {
|
||||||
|
name = named_port.key
|
||||||
|
port = named_port.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* 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 Health check resource.
|
||||||
|
|
||||||
|
resource "google_compute_health_check" "default" {
|
||||||
|
provider = google-beta
|
||||||
|
for_each = var.health_check_configs
|
||||||
|
project = (
|
||||||
|
each.value.project_id == null
|
||||||
|
? var.project_id
|
||||||
|
: each.value.project_id
|
||||||
|
)
|
||||||
|
name = "${var.name}-${each.key}"
|
||||||
|
description = each.value.description
|
||||||
|
check_interval_sec = each.value.check_interval_sec
|
||||||
|
healthy_threshold = each.value.healthy_threshold
|
||||||
|
timeout_sec = each.value.timeout_sec
|
||||||
|
unhealthy_threshold = each.value.unhealthy_threshold
|
||||||
|
|
||||||
|
dynamic "grpc_health_check" {
|
||||||
|
for_each = try(each.value.grpc, null) != null ? [""] : []
|
||||||
|
content {
|
||||||
|
port = each.value.grpc.port
|
||||||
|
port_name = each.value.grpc.port_name
|
||||||
|
port_specification = each.value.grpc.port_specification
|
||||||
|
grpc_service_name = each.value.grpc.service_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "http_health_check" {
|
||||||
|
for_each = try(each.value.http, null) != null ? [""] : []
|
||||||
|
content {
|
||||||
|
host = each.value.http.host
|
||||||
|
port = each.value.http.port
|
||||||
|
port_name = each.value.http.port_name
|
||||||
|
port_specification = each.value.http.port_specification
|
||||||
|
proxy_header = each.value.http.proxy_header
|
||||||
|
request_path = each.value.http.request_path
|
||||||
|
response = each.value.http.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "http2_health_check" {
|
||||||
|
for_each = try(each.value.http2, null) != null ? [""] : []
|
||||||
|
content {
|
||||||
|
host = each.value.http2.host
|
||||||
|
port = each.value.http2.port
|
||||||
|
port_name = each.value.http2.port_name
|
||||||
|
port_specification = each.value.http2.port_specification
|
||||||
|
proxy_header = each.value.http2.proxy_header
|
||||||
|
request_path = each.value.http2.request_path
|
||||||
|
response = each.value.http2.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "https_health_check" {
|
||||||
|
for_each = try(each.value.https, null) != null ? [""] : []
|
||||||
|
content {
|
||||||
|
host = each.value.https.host
|
||||||
|
port = each.value.https.port
|
||||||
|
port_name = each.value.https.port_name
|
||||||
|
port_specification = each.value.https.port_specification
|
||||||
|
proxy_header = each.value.https.proxy_header
|
||||||
|
request_path = each.value.https.request_path
|
||||||
|
response = each.value.https.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "ssl_health_check" {
|
||||||
|
for_each = try(each.value.ssl, null) != null ? [""] : []
|
||||||
|
content {
|
||||||
|
port = each.value.ssl.port
|
||||||
|
port_name = each.value.ssl.port_name
|
||||||
|
port_specification = each.value.ssl.port_specification
|
||||||
|
proxy_header = each.value.ssl.proxy_header
|
||||||
|
request = each.value.ssl.request
|
||||||
|
response = each.value.ssl.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "tcp_health_check" {
|
||||||
|
for_each = try(each.value.tcp, null) != null ? [""] : []
|
||||||
|
content {
|
||||||
|
port = each.value.tcp.port
|
||||||
|
port_name = each.value.tcp.port_name
|
||||||
|
port_specification = each.value.tcp.port_specification
|
||||||
|
proxy_header = each.value.tcp.proxy_header
|
||||||
|
request = each.value.tcp.request
|
||||||
|
response = each.value.tcp.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "log_config" {
|
||||||
|
for_each = try(each.value.enable_logging, null) == true ? [""] : []
|
||||||
|
content {
|
||||||
|
enable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
locals {
|
||||||
|
# we need keys in the endpoint type to address issue #1055
|
||||||
|
_neg_endpoints = flatten([
|
||||||
|
for k, v in local.neg_zonal : [
|
||||||
|
for kk, vv in v.endpoints : merge(vv, {
|
||||||
|
key = "${k}-${kk}", neg = k, zone = v.zone
|
||||||
|
})
|
||||||
|
]
|
||||||
|
])
|
||||||
|
fwd_rule_ports = (
|
||||||
|
var.protocol == "HTTPS" ? [443] : coalesce(var.ports, [80])
|
||||||
|
)
|
||||||
|
fwd_rule_target = (
|
||||||
|
var.protocol == "HTTPS"
|
||||||
|
? google_compute_target_https_proxy.default.0.id
|
||||||
|
: google_compute_target_http_proxy.default.0.id
|
||||||
|
)
|
||||||
|
neg_endpoints = {
|
||||||
|
for v in local._neg_endpoints : (v.key) => v
|
||||||
|
}
|
||||||
|
neg_regional = {
|
||||||
|
for k, v in var.neg_configs :
|
||||||
|
k => merge(v.cloudrun, { project_id = v.project_id }) if v.cloudrun != null
|
||||||
|
}
|
||||||
|
neg_zonal = {
|
||||||
|
# we need to rebuild new objects as we cannot merge different types
|
||||||
|
for k, v in var.neg_configs : k => {
|
||||||
|
endpoints = v.gce != null ? v.gce.endpoints : v.hybrid.endpoints
|
||||||
|
network = v.gce != null ? v.gce.network : v.hybrid.network
|
||||||
|
project_id = v.project_id
|
||||||
|
subnetwork = v.gce != null ? v.gce.subnetwork : null
|
||||||
|
type = v.gce != null ? "GCE_VM_IP_PORT" : "NON_GCP_PRIVATE_IP_PORT"
|
||||||
|
zone = v.gce != null ? v.gce.zone : v.hybrid.zone
|
||||||
|
} if v.gce != null || v.hybrid != null
|
||||||
|
}
|
||||||
|
neg_regional_psc = {
|
||||||
|
for k, v in var.neg_configs :
|
||||||
|
k => v if v.psc != null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_global_forwarding_rule" "forwarding_rules" {
|
||||||
|
for_each = var.vpc_config.subnetworks
|
||||||
|
provider = google-beta
|
||||||
|
project = var.project_id
|
||||||
|
name = "${var.name}-${each.key}"
|
||||||
|
description = var.description
|
||||||
|
ip_address = try(var.addresses[each.value], null)
|
||||||
|
ip_protocol = "TCP"
|
||||||
|
load_balancing_scheme = "INTERNAL_MANAGED"
|
||||||
|
network = var.vpc_config.network
|
||||||
|
port_range = join(",", local.fwd_rule_ports)
|
||||||
|
subnetwork = var.vpc_config.subnetworks[each.key]
|
||||||
|
labels = var.labels
|
||||||
|
target = local.fwd_rule_target
|
||||||
|
# during the preview phase you cannot change ths attribute on an existing rule
|
||||||
|
dynamic "service_directory_registrations" {
|
||||||
|
for_each = var.service_directory_registration == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
namespace = var.service_directory_registration.namespace
|
||||||
|
service_directory_region = var.service_directory_registration.service_directory_region
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_target_http_proxy" "default" {
|
||||||
|
count = var.protocol == "HTTPS" ? 0 : 1
|
||||||
|
project = var.project_id
|
||||||
|
name = var.name
|
||||||
|
description = var.description
|
||||||
|
url_map = google_compute_url_map.default.id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_target_https_proxy" "default" {
|
||||||
|
count = var.protocol == "HTTPS" ? 1 : 0
|
||||||
|
project = var.project_id
|
||||||
|
name = var.name
|
||||||
|
description = var.description
|
||||||
|
certificate_manager_certificates = var.https_proxy_config.certificate_manager_certificates
|
||||||
|
quic_override = var.https_proxy_config.quic_override
|
||||||
|
ssl_policy = var.https_proxy_config.ssl_policy
|
||||||
|
url_map = google_compute_url_map.default.id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_network_endpoint_group" "default" {
|
||||||
|
for_each = local.neg_zonal
|
||||||
|
project = (
|
||||||
|
each.value.project_id == null
|
||||||
|
? var.project_id
|
||||||
|
: each.value.project_id
|
||||||
|
)
|
||||||
|
zone = each.value.zone
|
||||||
|
name = "${var.name}-${each.key}"
|
||||||
|
# re-enable once provider properly supports this
|
||||||
|
# default_port = each.value.default_port
|
||||||
|
description = var.description
|
||||||
|
network_endpoint_type = each.value.type
|
||||||
|
network = (
|
||||||
|
each.value.network != null ? each.value.network : var.vpc_config.network
|
||||||
|
)
|
||||||
|
subnetwork = (
|
||||||
|
each.value.type == "NON_GCP_PRIVATE_IP_PORT"
|
||||||
|
? null
|
||||||
|
: try(each.value.subnetwork, var.vpc_config.subnetworks[substr(each.value.zone, 0, length(each.value.zone) - 2)])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_network_endpoint" "default" {
|
||||||
|
for_each = local.neg_endpoints
|
||||||
|
project = (
|
||||||
|
google_compute_network_endpoint_group.default[each.value.neg].project
|
||||||
|
)
|
||||||
|
network_endpoint_group = (
|
||||||
|
google_compute_network_endpoint_group.default[each.value.neg].name
|
||||||
|
)
|
||||||
|
instance = try(each.value.instance, null)
|
||||||
|
ip_address = each.value.ip_address
|
||||||
|
port = each.value.port
|
||||||
|
zone = each.value.zone
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_region_network_endpoint_group" "default" {
|
||||||
|
for_each = local.neg_regional
|
||||||
|
project = (
|
||||||
|
each.value.project_id == null
|
||||||
|
? var.project_id
|
||||||
|
: each.value.project_id
|
||||||
|
)
|
||||||
|
region = each.value.region
|
||||||
|
name = "${var.name}-${each.key}"
|
||||||
|
description = var.description
|
||||||
|
network_endpoint_type = "SERVERLESS"
|
||||||
|
cloud_run {
|
||||||
|
service = try(each.value.target_service.name, null)
|
||||||
|
tag = try(each.value.target_service.tag, null)
|
||||||
|
url_mask = each.value.target_urlmask
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_region_network_endpoint_group" "psc" {
|
||||||
|
for_each = local.neg_regional_psc
|
||||||
|
project = var.project_id
|
||||||
|
region = each.value.psc.region
|
||||||
|
name = "${var.name}-${each.key}"
|
||||||
|
//description = coalesce(each.value.description, var.description)
|
||||||
|
network_endpoint_type = "PRIVATE_SERVICE_CONNECT"
|
||||||
|
psc_target_service = each.value.psc.target_service
|
||||||
|
network = each.value.psc.network
|
||||||
|
subnetwork = each.value.psc.subnetwork
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
output "addresses" {
|
||||||
|
description = "Forwarding rule address."
|
||||||
|
value = { for k, v in google_compute_global_forwarding_rule.forwarding_rules : k => v.ip_address }
|
||||||
|
}
|
||||||
|
|
||||||
|
output "backend_service_ids" {
|
||||||
|
description = "Backend service resources."
|
||||||
|
value = {
|
||||||
|
for k, v in google_compute_backend_service.default : k => v.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "backend_service_names" {
|
||||||
|
description = "Backend service resource names."
|
||||||
|
value = {
|
||||||
|
for k, v in google_compute_backend_service.default : k => v.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "forwarding_rules" {
|
||||||
|
description = "Forwarding rule resource."
|
||||||
|
value = google_compute_global_forwarding_rule.forwarding_rules
|
||||||
|
}
|
||||||
|
|
||||||
|
output "group_ids" {
|
||||||
|
description = "Autogenerated instance group ids."
|
||||||
|
value = {
|
||||||
|
for k, v in google_compute_instance_group.default : k => v.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "health_check_ids" {
|
||||||
|
description = "Autogenerated health check ids."
|
||||||
|
value = {
|
||||||
|
for k, v in google_compute_health_check.default : k => v.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "ids" {
|
||||||
|
description = "Fully qualified forwarding rule ids."
|
||||||
|
value = { for k, v in google_compute_global_forwarding_rule.forwarding_rules : k => v.id }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
output "neg_ids" {
|
||||||
|
description = "Autogenerated network endpoint group ids."
|
||||||
|
value = {
|
||||||
|
for k, v in google_compute_network_endpoint_group.default : k => v.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "psc_neg_ids" {
|
||||||
|
description = "Autogenerated PSC network endpoint group ids."
|
||||||
|
value = {
|
||||||
|
for k, v in google_compute_region_network_endpoint_group.psc : k => v.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "regional_neg_ids" {
|
||||||
|
description = "Autogenerated regional network endpoint group ids."
|
||||||
|
value = {
|
||||||
|
for k, v in google_compute_region_network_endpoint_group.default : k => v.id
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,575 @@
|
||||||
|
/**
|
||||||
|
* 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 URL map resources.
|
||||||
|
|
||||||
|
locals {
|
||||||
|
backend_ids = {
|
||||||
|
for k, v in google_compute_backend_service.default : k => v.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_url_map" "default" {
|
||||||
|
provider = google-beta
|
||||||
|
project = var.project_id
|
||||||
|
name = var.name
|
||||||
|
description = var.description
|
||||||
|
default_service = (
|
||||||
|
var.urlmap_config.default_service == null ? null : lookup(
|
||||||
|
local.backend_ids,
|
||||||
|
var.urlmap_config.default_service,
|
||||||
|
var.urlmap_config.default_service
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
dynamic "default_url_redirect" {
|
||||||
|
for_each = (
|
||||||
|
var.urlmap_config.default_url_redirect == null
|
||||||
|
? []
|
||||||
|
: [var.urlmap_config.default_url_redirect]
|
||||||
|
)
|
||||||
|
iterator = r
|
||||||
|
content {
|
||||||
|
host_redirect = r.value.host
|
||||||
|
https_redirect = r.value.https
|
||||||
|
path_redirect = r.value.path
|
||||||
|
prefix_redirect = r.value.prefix
|
||||||
|
redirect_response_code = r.value.response_code
|
||||||
|
strip_query = r.value.strip_query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "host_rule" {
|
||||||
|
for_each = coalesce(var.urlmap_config.host_rules, [])
|
||||||
|
iterator = r
|
||||||
|
content {
|
||||||
|
hosts = r.value.hosts
|
||||||
|
path_matcher = r.value.path_matcher
|
||||||
|
description = r.value.description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "path_matcher" {
|
||||||
|
for_each = coalesce(var.urlmap_config.path_matchers, {})
|
||||||
|
iterator = m
|
||||||
|
content {
|
||||||
|
default_service = m.value.default_service == null ? null : lookup(
|
||||||
|
local.backend_ids, m.value.default_service, m.value.default_service
|
||||||
|
)
|
||||||
|
description = m.value.description
|
||||||
|
name = m.key
|
||||||
|
dynamic "default_url_redirect" {
|
||||||
|
for_each = (
|
||||||
|
m.value.default_url_redirect == null
|
||||||
|
? []
|
||||||
|
: [m.value.default_url_redirect]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
host_redirect = default_url_redirect.value.host
|
||||||
|
https_redirect = default_url_redirect.value.https
|
||||||
|
path_redirect = default_url_redirect.value.path
|
||||||
|
prefix_redirect = default_url_redirect.value.prefix
|
||||||
|
redirect_response_code = default_url_redirect.value.response_code
|
||||||
|
strip_query = default_url_redirect.value.strip_query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "path_rule" {
|
||||||
|
for_each = toset(coalesce(m.value.path_rules, []))
|
||||||
|
content {
|
||||||
|
paths = path_rule.value.paths
|
||||||
|
service = path_rule.value.service == null ? null : lookup(
|
||||||
|
local.backend_ids,
|
||||||
|
path_rule.value.service,
|
||||||
|
path_rule.value.service
|
||||||
|
)
|
||||||
|
dynamic "route_action" {
|
||||||
|
for_each = (
|
||||||
|
path_rule.value.route_action == null
|
||||||
|
? []
|
||||||
|
: [path_rule.value.route_action]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
dynamic "cors_policy" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.cors_policy == null
|
||||||
|
? []
|
||||||
|
: [route_action.value.cors_policy]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
allow_credentials = cors_policy.value.allow_credentials
|
||||||
|
allow_headers = cors_policy.value.allow_headers
|
||||||
|
allow_methods = cors_policy.value.allow_methods
|
||||||
|
allow_origin_regexes = cors_policy.value.allow_origin_regexes
|
||||||
|
allow_origins = cors_policy.value.allow_origins
|
||||||
|
disabled = cors_policy.value.disabled
|
||||||
|
expose_headers = cors_policy.value.expose_headers
|
||||||
|
max_age = cors_policy.value.max_age
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "fault_injection_policy" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.fault_injection_policy == null
|
||||||
|
? []
|
||||||
|
: [route_action.value.fault_injection_policy]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
dynamic "abort" {
|
||||||
|
for_each = (
|
||||||
|
fault_injection_policy.value.abort == null
|
||||||
|
? []
|
||||||
|
: [fault_injection_policy.value.abort]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
http_status = abort.value.status
|
||||||
|
percentage = abort.value.percentage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "delay" {
|
||||||
|
for_each = (
|
||||||
|
fault_injection_policy.value.delay == null
|
||||||
|
? []
|
||||||
|
: [fault_injection_policy.value.delay]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
percentage = delay.value.percentage
|
||||||
|
fixed_delay {
|
||||||
|
nanos = delay.value.fixed.nanos
|
||||||
|
seconds = delay.value.fixed.seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "request_mirror_policy" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.request_mirror_backend == null
|
||||||
|
? []
|
||||||
|
: [""]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
backend_service = lookup(
|
||||||
|
local.backend_ids,
|
||||||
|
route_action.value.request_mirror_backend,
|
||||||
|
route_action.value.request_mirror_backend
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "retry_policy" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.retry_policy == null
|
||||||
|
? []
|
||||||
|
: [route_action.value.retry_policy]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
num_retries = retry_policy.value.num_retries
|
||||||
|
retry_conditions = retry_policy.value.retry_conditions
|
||||||
|
dynamic "per_try_timeout" {
|
||||||
|
for_each = (
|
||||||
|
retry_policy.value.per_try_timeout == null
|
||||||
|
? []
|
||||||
|
: [retry_policy.value.per_try_timeout]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
nanos = per_try_timeout.value.nanos
|
||||||
|
seconds = per_try_timeout.value.seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "timeout" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.timeout == null
|
||||||
|
? []
|
||||||
|
: [route_action.value.timeout]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
nanos = timeout.value.nanos
|
||||||
|
seconds = timeout.value.seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "url_rewrite" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.url_rewrite == null
|
||||||
|
? []
|
||||||
|
: [route_action.value.url_rewrite]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
host_rewrite = url_rewrite.value.host
|
||||||
|
path_prefix_rewrite = url_rewrite.value.path_prefix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "weighted_backend_services" {
|
||||||
|
for_each = coalesce(
|
||||||
|
route_action.value.weighted_backend_services, {}
|
||||||
|
)
|
||||||
|
iterator = service
|
||||||
|
content {
|
||||||
|
backend_service = lookup(
|
||||||
|
local.backend_ids, service.key, service.key
|
||||||
|
)
|
||||||
|
weight = service.value.weight
|
||||||
|
dynamic "header_action" {
|
||||||
|
for_each = (
|
||||||
|
service.value.header_action == null
|
||||||
|
? []
|
||||||
|
: [service.value.header_action]
|
||||||
|
)
|
||||||
|
iterator = h
|
||||||
|
content {
|
||||||
|
request_headers_to_remove = h.value.request_remove
|
||||||
|
response_headers_to_remove = h.value.response_remove
|
||||||
|
dynamic "request_headers_to_add" {
|
||||||
|
for_each = coalesce(h.value.request_add, {})
|
||||||
|
content {
|
||||||
|
header_name = request_headers_to_add.key
|
||||||
|
header_value = request_headers_to_add.value.value
|
||||||
|
replace = request_headers_to_add.value.replace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "response_headers_to_add" {
|
||||||
|
for_each = coalesce(h.value.response_add, {})
|
||||||
|
content {
|
||||||
|
header_name = response_headers_to_add.key
|
||||||
|
header_value = response_headers_to_add.value.value
|
||||||
|
replace = response_headers_to_add.value.replace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "url_redirect" {
|
||||||
|
for_each = (
|
||||||
|
path_rule.value.url_redirect == null
|
||||||
|
? []
|
||||||
|
: [path_rule.value.url_redirect]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
host_redirect = url_redirect.value.host
|
||||||
|
https_redirect = url_redirect.value.https
|
||||||
|
path_redirect = url_redirect.value.path
|
||||||
|
prefix_redirect = url_redirect.value.prefix
|
||||||
|
redirect_response_code = url_redirect.value.response_code
|
||||||
|
strip_query = url_redirect.value.strip_query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "route_rules" {
|
||||||
|
for_each = toset(coalesce(m.value.route_rules, []))
|
||||||
|
content {
|
||||||
|
priority = route_rules.value.priority
|
||||||
|
service = route_rules.value.service == null ? null : lookup(
|
||||||
|
local.backend_ids,
|
||||||
|
route_rules.value.service,
|
||||||
|
route_rules.value.service
|
||||||
|
)
|
||||||
|
dynamic "header_action" {
|
||||||
|
for_each = (
|
||||||
|
route_rules.value.header_action == null
|
||||||
|
? []
|
||||||
|
: [route_rules.value.header_action]
|
||||||
|
)
|
||||||
|
iterator = h
|
||||||
|
content {
|
||||||
|
request_headers_to_remove = h.value.request_remove
|
||||||
|
response_headers_to_remove = h.value.response_remove
|
||||||
|
dynamic "request_headers_to_add" {
|
||||||
|
for_each = coalesce(h.value.request_add, {})
|
||||||
|
content {
|
||||||
|
header_name = request_headers_to_add.key
|
||||||
|
header_value = request_headers_to_add.value.value
|
||||||
|
replace = request_headers_to_add.value.replace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "response_headers_to_add" {
|
||||||
|
for_each = coalesce(h.value.response_add, {})
|
||||||
|
content {
|
||||||
|
header_name = response_headers_to_add.key
|
||||||
|
header_value = response_headers_to_add.value.value
|
||||||
|
replace = response_headers_to_add.value.replace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "match_rules" {
|
||||||
|
for_each = toset(coalesce(route_rules.value.match_rules, []))
|
||||||
|
content {
|
||||||
|
ignore_case = match_rules.value.ignore_case
|
||||||
|
full_path_match = (
|
||||||
|
try(match_rules.value.path.type, null) == "full"
|
||||||
|
? match_rules.value.path.value
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
prefix_match = (
|
||||||
|
try(match_rules.value.path.type, null) == "prefix"
|
||||||
|
? match_rules.value.path.value
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
regex_match = (
|
||||||
|
try(match_rules.value.path.type, null) == "regex"
|
||||||
|
? match_rules.value.path.value
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
dynamic "header_matches" {
|
||||||
|
for_each = toset(coalesce(match_rules.value.headers, []))
|
||||||
|
iterator = h
|
||||||
|
content {
|
||||||
|
header_name = h.value.name
|
||||||
|
exact_match = h.value.type == "exact" ? h.value.value : null
|
||||||
|
invert_match = h.value.invert_match
|
||||||
|
prefix_match = h.value.type == "prefix" ? h.value.value : null
|
||||||
|
present_match = h.value.type == "present" ? h.value.value : null
|
||||||
|
regex_match = h.value.type == "regex" ? h.value.value : null
|
||||||
|
suffix_match = h.value.type == "suffix" ? h.value.value : null
|
||||||
|
dynamic "range_match" {
|
||||||
|
for_each = (
|
||||||
|
h.value.type != "range" || h.value.range_value == null
|
||||||
|
? []
|
||||||
|
: [""]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
range_end = h.value.range_value.end
|
||||||
|
range_start = h.value.range_value.start
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "metadata_filters" {
|
||||||
|
for_each = toset(coalesce(match_rules.value.metadata_filters, []))
|
||||||
|
iterator = m
|
||||||
|
content {
|
||||||
|
filter_match_criteria = (
|
||||||
|
m.value.match_all ? "MATCH_ALL" : "MATCH_ANY"
|
||||||
|
)
|
||||||
|
dynamic "filter_labels" {
|
||||||
|
for_each = m.value.labels
|
||||||
|
content {
|
||||||
|
name = filter_labels.key
|
||||||
|
value = filter_labels.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "query_parameter_matches" {
|
||||||
|
for_each = toset(coalesce(match_rules.value.query_params, []))
|
||||||
|
iterator = q
|
||||||
|
content {
|
||||||
|
name = q.value.name
|
||||||
|
exact_match = (
|
||||||
|
q.value.type == "exact" ? q.value.value : null
|
||||||
|
)
|
||||||
|
present_match = (
|
||||||
|
q.value.type == "present" ? q.value.value : null
|
||||||
|
)
|
||||||
|
regex_match = (
|
||||||
|
q.value.type == "regex" ? q.value.value : null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "route_action" {
|
||||||
|
for_each = (
|
||||||
|
route_rules.value.route_action == null
|
||||||
|
? []
|
||||||
|
: [route_rules.value.route_action]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
dynamic "cors_policy" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.cors_policy == null
|
||||||
|
? []
|
||||||
|
: [route_action.value.cors_policy]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
allow_credentials = cors_policy.value.allow_credentials
|
||||||
|
allow_headers = cors_policy.value.allow_headers
|
||||||
|
allow_methods = cors_policy.value.allow_methods
|
||||||
|
allow_origin_regexes = cors_policy.value.allow_origin_regexes
|
||||||
|
allow_origins = cors_policy.value.allow_origins
|
||||||
|
disabled = cors_policy.value.disabled
|
||||||
|
expose_headers = cors_policy.value.expose_headers
|
||||||
|
max_age = cors_policy.value.max_age
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "fault_injection_policy" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.fault_injection_policy == null
|
||||||
|
? []
|
||||||
|
: [route_action.value.fault_injection_policy]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
dynamic "abort" {
|
||||||
|
for_each = (
|
||||||
|
fault_injection_policy.value.abort == null
|
||||||
|
? []
|
||||||
|
: [fault_injection_policy.value.abort]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
http_status = abort.value.status
|
||||||
|
percentage = abort.value.percentage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "delay" {
|
||||||
|
for_each = (
|
||||||
|
fault_injection_policy.value.delay == null
|
||||||
|
? []
|
||||||
|
: [fault_injection_policy.value.delay]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
percentage = delay.value.percentage
|
||||||
|
fixed_delay {
|
||||||
|
nanos = delay.value.fixed.nanos
|
||||||
|
seconds = delay.value.fixed.seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "request_mirror_policy" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.request_mirror_backend == null
|
||||||
|
? []
|
||||||
|
: [""]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
backend_service = lookup(
|
||||||
|
local.backend_ids,
|
||||||
|
route_action.value.request_mirror_backend,
|
||||||
|
route_action.value.request_mirror_backend
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "retry_policy" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.retry_policy == null
|
||||||
|
? []
|
||||||
|
: [route_action.value.retry_policy]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
num_retries = retry_policy.value.num_retries
|
||||||
|
retry_conditions = retry_policy.value.retry_conditions
|
||||||
|
dynamic "per_try_timeout" {
|
||||||
|
for_each = (
|
||||||
|
retry_policy.value.per_try_timeout == null
|
||||||
|
? []
|
||||||
|
: [retry_policy.value.per_try_timeout]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
nanos = per_try_timeout.value.nanos
|
||||||
|
seconds = per_try_timeout.value.seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "timeout" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.timeout == null
|
||||||
|
? []
|
||||||
|
: [route_action.value.timeout]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
nanos = timeout.value.nanos
|
||||||
|
seconds = timeout.value.seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "url_rewrite" {
|
||||||
|
for_each = (
|
||||||
|
route_action.value.url_rewrite == null
|
||||||
|
? []
|
||||||
|
: [route_action.value.url_rewrite]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
host_rewrite = url_rewrite.value.host
|
||||||
|
path_prefix_rewrite = url_rewrite.value.path_prefix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "weighted_backend_services" {
|
||||||
|
for_each = coalesce(
|
||||||
|
route_action.value.weighted_backend_services, {}
|
||||||
|
)
|
||||||
|
iterator = service
|
||||||
|
content {
|
||||||
|
backend_service = lookup(
|
||||||
|
local.backend_ids, service.key, service.key
|
||||||
|
)
|
||||||
|
weight = service.value.weight
|
||||||
|
dynamic "header_action" {
|
||||||
|
for_each = (
|
||||||
|
service.value.header_action == null
|
||||||
|
? []
|
||||||
|
: [service.value.header_action]
|
||||||
|
)
|
||||||
|
iterator = h
|
||||||
|
content {
|
||||||
|
request_headers_to_remove = h.value.request_remove
|
||||||
|
response_headers_to_remove = h.value.response_remove
|
||||||
|
dynamic "request_headers_to_add" {
|
||||||
|
for_each = coalesce(h.value.request_add, {})
|
||||||
|
content {
|
||||||
|
header_name = request_headers_to_add.key
|
||||||
|
header_value = request_headers_to_add.value.value
|
||||||
|
replace = request_headers_to_add.value.replace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "response_headers_to_add" {
|
||||||
|
for_each = coalesce(h.value.response_add, {})
|
||||||
|
content {
|
||||||
|
header_name = response_headers_to_add.key
|
||||||
|
header_value = response_headers_to_add.value.value
|
||||||
|
replace = response_headers_to_add.value.replace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamic "url_redirect" {
|
||||||
|
for_each = (
|
||||||
|
route_rules.value.url_redirect == null
|
||||||
|
? []
|
||||||
|
: [route_rules.value.url_redirect]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
host_redirect = url_redirect.value.host
|
||||||
|
https_redirect = url_redirect.value.https
|
||||||
|
path_redirect = url_redirect.value.path
|
||||||
|
prefix_redirect = url_redirect.value.prefix
|
||||||
|
redirect_response_code = url_redirect.value.response_code
|
||||||
|
strip_query = url_redirect.value.strip_query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "test" {
|
||||||
|
for_each = toset(coalesce(var.urlmap_config.test, []))
|
||||||
|
content {
|
||||||
|
host = test.value.host
|
||||||
|
path = test.value.path
|
||||||
|
service = test.value.service
|
||||||
|
description = test.value.description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
/**
|
||||||
|
* 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 Backend services variables.
|
||||||
|
|
||||||
|
variable "backend_service_configs" {
|
||||||
|
description = "Backend service level configuration."
|
||||||
|
type = map(object({
|
||||||
|
affinity_cookie_ttl_sec = optional(number)
|
||||||
|
connection_draining_timeout_sec = optional(number)
|
||||||
|
health_checks = optional(list(string), ["default"])
|
||||||
|
locality_lb_policy = optional(string)
|
||||||
|
log_sample_rate = optional(number)
|
||||||
|
port_name = optional(string)
|
||||||
|
project_id = optional(string)
|
||||||
|
protocol = optional(string)
|
||||||
|
session_affinity = optional(string)
|
||||||
|
timeout_sec = optional(number)
|
||||||
|
backends = list(object({
|
||||||
|
group = string
|
||||||
|
balancing_mode = optional(string, "UTILIZATION")
|
||||||
|
capacity_scaler = optional(number, 1)
|
||||||
|
description = optional(string, "Terraform managed.")
|
||||||
|
failover = optional(bool, false)
|
||||||
|
max_rate = optional(object({
|
||||||
|
per_endpoint = optional(number)
|
||||||
|
per_group = optional(number)
|
||||||
|
per_instance = optional(number)
|
||||||
|
}))
|
||||||
|
max_utilization = optional(number)
|
||||||
|
}))
|
||||||
|
circuit_breakers = optional(object({
|
||||||
|
max_connections = optional(number)
|
||||||
|
max_pending_requests = optional(number)
|
||||||
|
max_requests = optional(number)
|
||||||
|
max_requests_per_connection = optional(number)
|
||||||
|
max_retries = optional(number)
|
||||||
|
connect_timeout = optional(object({
|
||||||
|
seconds = number
|
||||||
|
nanos = optional(number)
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
consistent_hash = optional(object({
|
||||||
|
http_header_name = optional(string)
|
||||||
|
minimum_ring_size = optional(number)
|
||||||
|
http_cookie = optional(object({
|
||||||
|
name = optional(string)
|
||||||
|
path = optional(string)
|
||||||
|
ttl = optional(object({
|
||||||
|
seconds = number
|
||||||
|
nanos = optional(number)
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
iap_config = optional(object({
|
||||||
|
oauth2_client_id = string
|
||||||
|
oauth2_client_secret = string
|
||||||
|
oauth2_client_secret_sha256 = optional(string)
|
||||||
|
}))
|
||||||
|
outlier_detection = optional(object({
|
||||||
|
consecutive_errors = optional(number)
|
||||||
|
consecutive_gateway_failure = optional(number)
|
||||||
|
enforcing_consecutive_errors = optional(number)
|
||||||
|
enforcing_consecutive_gateway_failure = optional(number)
|
||||||
|
enforcing_success_rate = optional(number)
|
||||||
|
max_ejection_percent = optional(number)
|
||||||
|
success_rate_minimum_hosts = optional(number)
|
||||||
|
success_rate_request_volume = optional(number)
|
||||||
|
success_rate_stdev_factor = optional(number)
|
||||||
|
base_ejection_time = optional(object({
|
||||||
|
seconds = number
|
||||||
|
nanos = optional(number)
|
||||||
|
}))
|
||||||
|
interval = optional(object({
|
||||||
|
seconds = number
|
||||||
|
nanos = optional(number)
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
default = {}
|
||||||
|
nullable = false
|
||||||
|
validation {
|
||||||
|
condition = alltrue([
|
||||||
|
for backend_service in values(var.backend_service_configs) : contains(
|
||||||
|
[
|
||||||
|
"-", "ROUND_ROBIN", "LEAST_REQUEST", "RING_HASH",
|
||||||
|
"RANDOM", "ORIGINAL_DESTINATION", "MAGLEV"
|
||||||
|
],
|
||||||
|
coalesce(backend_service.locality_lb_policy, "-")
|
||||||
|
)
|
||||||
|
])
|
||||||
|
error_message = "Invalid locality lb policy value."
|
||||||
|
}
|
||||||
|
validation {
|
||||||
|
condition = alltrue([
|
||||||
|
for backend_service in values(var.backend_service_configs) : contains(
|
||||||
|
[
|
||||||
|
"NONE", "CLIENT_IP", "CLIENT_IP_NO_DESTINATION",
|
||||||
|
"CLIENT_IP_PORT_PROTO", "CLIENT_IP_PROTO"
|
||||||
|
],
|
||||||
|
coalesce(backend_service.session_affinity, "NONE")
|
||||||
|
)
|
||||||
|
])
|
||||||
|
error_message = "Invalid session affinity value."
|
||||||
|
}
|
||||||
|
validation {
|
||||||
|
condition = alltrue(flatten([
|
||||||
|
for backend_service in values(var.backend_service_configs) : [
|
||||||
|
for backend in backend_service.backends : contains(
|
||||||
|
["RATE", "UTILIZATION"], coalesce(backend.balancing_mode, "UTILIZATION")
|
||||||
|
)]
|
||||||
|
]))
|
||||||
|
error_message = "When specified, balancing mode needs to be 'RATE' or 'UTILIZATION'."
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
/**
|
||||||
|
* 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 Health check variable.
|
||||||
|
|
||||||
|
variable "health_check_configs" {
|
||||||
|
description = "Optional auto-created health check configurations, use the output self-link to set it in the auto healing policy. Refer to examples for usage."
|
||||||
|
type = map(object({
|
||||||
|
check_interval_sec = optional(number)
|
||||||
|
description = optional(string, "Terraform managed.")
|
||||||
|
enable_logging = optional(bool, false)
|
||||||
|
healthy_threshold = optional(number)
|
||||||
|
project_id = optional(string)
|
||||||
|
timeout_sec = optional(number)
|
||||||
|
unhealthy_threshold = optional(number)
|
||||||
|
grpc = optional(object({
|
||||||
|
port = optional(number)
|
||||||
|
port_name = optional(string)
|
||||||
|
port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT
|
||||||
|
service_name = optional(string)
|
||||||
|
}))
|
||||||
|
http = optional(object({
|
||||||
|
host = optional(string)
|
||||||
|
port = optional(number)
|
||||||
|
port_name = optional(string)
|
||||||
|
port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT
|
||||||
|
proxy_header = optional(string)
|
||||||
|
request_path = optional(string)
|
||||||
|
response = optional(string)
|
||||||
|
}))
|
||||||
|
http2 = optional(object({
|
||||||
|
host = optional(string)
|
||||||
|
port = optional(number)
|
||||||
|
port_name = optional(string)
|
||||||
|
port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT
|
||||||
|
proxy_header = optional(string)
|
||||||
|
request_path = optional(string)
|
||||||
|
response = optional(string)
|
||||||
|
}))
|
||||||
|
https = optional(object({
|
||||||
|
host = optional(string)
|
||||||
|
port = optional(number)
|
||||||
|
port_name = optional(string)
|
||||||
|
port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT
|
||||||
|
proxy_header = optional(string)
|
||||||
|
request_path = optional(string)
|
||||||
|
response = optional(string)
|
||||||
|
}))
|
||||||
|
tcp = optional(object({
|
||||||
|
port = optional(number)
|
||||||
|
port_name = optional(string)
|
||||||
|
port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT
|
||||||
|
proxy_header = optional(string)
|
||||||
|
request = optional(string)
|
||||||
|
response = optional(string)
|
||||||
|
}))
|
||||||
|
ssl = optional(object({
|
||||||
|
port = optional(number)
|
||||||
|
port_name = optional(string)
|
||||||
|
port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT
|
||||||
|
proxy_header = optional(string)
|
||||||
|
request = optional(string)
|
||||||
|
response = optional(string)
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
default = {
|
||||||
|
default = {
|
||||||
|
http = {
|
||||||
|
port_specification = "USE_SERVING_PORT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validation {
|
||||||
|
condition = alltrue([
|
||||||
|
for k, v in var.health_check_configs : (
|
||||||
|
(try(v.grpc, null) == null ? 0 : 1) +
|
||||||
|
(try(v.http, null) == null ? 0 : 1) +
|
||||||
|
(try(v.http2, null) == null ? 0 : 1) +
|
||||||
|
(try(v.https, null) == null ? 0 : 1) +
|
||||||
|
(try(v.tcp, null) == null ? 0 : 1) +
|
||||||
|
(try(v.ssl, null) == null ? 0 : 1) <= 1
|
||||||
|
)
|
||||||
|
])
|
||||||
|
error_message = "Only one health check type can be configured at a time."
|
||||||
|
}
|
||||||
|
validation {
|
||||||
|
condition = alltrue(flatten([
|
||||||
|
for k, v in var.health_check_configs : [
|
||||||
|
for kk, vv in v : contains([
|
||||||
|
"-", "USE_FIXED_PORT", "USE_NAMED_PORT", "USE_SERVING_PORT"
|
||||||
|
], coalesce(try(vv.port_specification, null), "-"))
|
||||||
|
]
|
||||||
|
]))
|
||||||
|
error_message = "Invalid 'port_specification' value. Supported values are 'USE_FIXED_PORT', 'USE_NAMED_PORT', 'USE_SERVING_PORT'."
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,234 @@
|
||||||
|
/**
|
||||||
|
* 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 URLmap variable.
|
||||||
|
|
||||||
|
variable "urlmap_config" {
|
||||||
|
description = "The URL map configuration."
|
||||||
|
type = object({
|
||||||
|
default_service = optional(string)
|
||||||
|
default_url_redirect = optional(object({
|
||||||
|
host = optional(string)
|
||||||
|
https = optional(bool)
|
||||||
|
path = optional(string)
|
||||||
|
prefix = optional(string)
|
||||||
|
response_code = optional(string)
|
||||||
|
strip_query = optional(bool)
|
||||||
|
}))
|
||||||
|
host_rules = optional(list(object({
|
||||||
|
hosts = list(string)
|
||||||
|
path_matcher = string
|
||||||
|
description = optional(string)
|
||||||
|
})))
|
||||||
|
path_matchers = optional(map(object({
|
||||||
|
description = optional(string)
|
||||||
|
default_service = optional(string)
|
||||||
|
default_url_redirect = optional(object({
|
||||||
|
host = optional(string)
|
||||||
|
https = optional(bool)
|
||||||
|
path = optional(string)
|
||||||
|
prefix = optional(string)
|
||||||
|
response_code = optional(string)
|
||||||
|
strip_query = optional(bool)
|
||||||
|
}))
|
||||||
|
path_rules = optional(list(object({
|
||||||
|
paths = list(string)
|
||||||
|
service = optional(string)
|
||||||
|
route_action = optional(object({
|
||||||
|
request_mirror_backend = optional(string)
|
||||||
|
cors_policy = optional(object({
|
||||||
|
allow_credentials = optional(bool)
|
||||||
|
allow_headers = optional(string)
|
||||||
|
allow_methods = optional(string)
|
||||||
|
allow_origin_regexes = list(string)
|
||||||
|
allow_origins = list(string)
|
||||||
|
disabled = optional(bool)
|
||||||
|
expose_headers = optional(string)
|
||||||
|
max_age = optional(string)
|
||||||
|
}))
|
||||||
|
fault_injection_policy = optional(object({
|
||||||
|
abort = optional(object({
|
||||||
|
percentage = number
|
||||||
|
status = number
|
||||||
|
}))
|
||||||
|
delay = optional(object({
|
||||||
|
fixed = object({
|
||||||
|
seconds = number
|
||||||
|
nanos = number
|
||||||
|
})
|
||||||
|
percentage = number
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
retry_policy = optional(object({
|
||||||
|
num_retries = number
|
||||||
|
retry_conditions = optional(list(string))
|
||||||
|
per_try_timeout = optional(object({
|
||||||
|
seconds = number
|
||||||
|
nanos = optional(number)
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
timeout = optional(object({
|
||||||
|
seconds = number
|
||||||
|
nanos = optional(number)
|
||||||
|
}))
|
||||||
|
url_rewrite = optional(object({
|
||||||
|
host = optional(string)
|
||||||
|
path_prefix = optional(string)
|
||||||
|
}))
|
||||||
|
weighted_backend_services = optional(map(object({
|
||||||
|
weight = number
|
||||||
|
header_action = optional(object({
|
||||||
|
request_add = optional(map(object({
|
||||||
|
value = string
|
||||||
|
replace = optional(bool, true)
|
||||||
|
})))
|
||||||
|
request_remove = optional(list(string))
|
||||||
|
response_add = optional(map(object({
|
||||||
|
value = string
|
||||||
|
replace = optional(bool, true)
|
||||||
|
})))
|
||||||
|
response_remove = optional(list(string))
|
||||||
|
}))
|
||||||
|
})))
|
||||||
|
}))
|
||||||
|
url_redirect = optional(object({
|
||||||
|
host = optional(string)
|
||||||
|
https = optional(bool)
|
||||||
|
path = optional(string)
|
||||||
|
prefix = optional(string)
|
||||||
|
response_code = optional(string)
|
||||||
|
strip_query = optional(bool)
|
||||||
|
}))
|
||||||
|
})))
|
||||||
|
route_rules = optional(list(object({
|
||||||
|
priority = number
|
||||||
|
service = optional(string)
|
||||||
|
header_action = optional(object({
|
||||||
|
request_add = optional(map(object({
|
||||||
|
value = string
|
||||||
|
replace = optional(bool, true)
|
||||||
|
})))
|
||||||
|
request_remove = optional(list(string))
|
||||||
|
response_add = optional(map(object({
|
||||||
|
value = string
|
||||||
|
replace = optional(bool, true)
|
||||||
|
})))
|
||||||
|
response_remove = optional(list(string))
|
||||||
|
}))
|
||||||
|
match_rules = optional(list(object({
|
||||||
|
ignore_case = optional(bool, false)
|
||||||
|
headers = optional(list(object({
|
||||||
|
name = string
|
||||||
|
invert_match = optional(bool, false)
|
||||||
|
type = optional(string, "present") # exact, prefix, suffix, regex, present, range
|
||||||
|
value = optional(string)
|
||||||
|
range_value = optional(object({
|
||||||
|
end = string
|
||||||
|
start = string
|
||||||
|
}))
|
||||||
|
})))
|
||||||
|
metadata_filters = optional(list(object({
|
||||||
|
labels = map(string)
|
||||||
|
match_all = bool # MATCH_ANY, MATCH_ALL
|
||||||
|
})))
|
||||||
|
path = optional(object({
|
||||||
|
value = string
|
||||||
|
type = optional(string, "prefix") # full, prefix, regex
|
||||||
|
}))
|
||||||
|
query_params = optional(list(object({
|
||||||
|
name = string
|
||||||
|
value = string
|
||||||
|
type = optional(string, "present") # exact, present, regex
|
||||||
|
})))
|
||||||
|
})))
|
||||||
|
route_action = optional(object({
|
||||||
|
request_mirror_backend = optional(string)
|
||||||
|
cors_policy = optional(object({
|
||||||
|
allow_credentials = optional(bool)
|
||||||
|
allow_headers = optional(string)
|
||||||
|
allow_methods = optional(string)
|
||||||
|
allow_origin_regexes = list(string)
|
||||||
|
allow_origins = list(string)
|
||||||
|
disabled = optional(bool)
|
||||||
|
expose_headers = optional(string)
|
||||||
|
max_age = optional(string)
|
||||||
|
}))
|
||||||
|
fault_injection_policy = optional(object({
|
||||||
|
abort = optional(object({
|
||||||
|
percentage = number
|
||||||
|
status = number
|
||||||
|
}))
|
||||||
|
delay = optional(object({
|
||||||
|
fixed = object({
|
||||||
|
seconds = number
|
||||||
|
nanos = number
|
||||||
|
})
|
||||||
|
percentage = number
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
retry_policy = optional(object({
|
||||||
|
num_retries = number
|
||||||
|
retry_conditions = optional(list(string))
|
||||||
|
per_try_timeout = optional(object({
|
||||||
|
seconds = number
|
||||||
|
nanos = optional(number)
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
timeout = optional(object({
|
||||||
|
seconds = number
|
||||||
|
nanos = optional(number)
|
||||||
|
}))
|
||||||
|
url_rewrite = optional(object({
|
||||||
|
host = optional(string)
|
||||||
|
path_prefix = optional(string)
|
||||||
|
}))
|
||||||
|
weighted_backend_services = optional(map(object({
|
||||||
|
weight = number
|
||||||
|
header_action = optional(object({
|
||||||
|
request_add = optional(map(object({
|
||||||
|
value = string
|
||||||
|
replace = optional(bool, true)
|
||||||
|
})))
|
||||||
|
request_remove = optional(list(string))
|
||||||
|
response_add = optional(map(object({
|
||||||
|
value = string
|
||||||
|
replace = optional(bool, true)
|
||||||
|
})))
|
||||||
|
response_remove = optional(list(string))
|
||||||
|
}))
|
||||||
|
})))
|
||||||
|
}))
|
||||||
|
url_redirect = optional(object({
|
||||||
|
host = optional(string)
|
||||||
|
https = optional(bool)
|
||||||
|
path = optional(string)
|
||||||
|
prefix = optional(string)
|
||||||
|
response_code = optional(string)
|
||||||
|
strip_query = optional(bool)
|
||||||
|
}))
|
||||||
|
})))
|
||||||
|
})))
|
||||||
|
test = optional(list(object({
|
||||||
|
host = string
|
||||||
|
path = string
|
||||||
|
service = string
|
||||||
|
description = optional(string)
|
||||||
|
})))
|
||||||
|
})
|
||||||
|
default = {
|
||||||
|
default_service = "default"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
variable "addresses" {
|
||||||
|
description = "Optional IP address used for the forwarding rule."
|
||||||
|
type = map(string)
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "description" {
|
||||||
|
description = "Optional description used for resources."
|
||||||
|
type = string
|
||||||
|
default = "Terraform managed."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "group_configs" {
|
||||||
|
description = "Optional unmanaged groups to create. Can be referenced in backends via key or outputs."
|
||||||
|
type = map(object({
|
||||||
|
zone = string
|
||||||
|
instances = optional(list(string))
|
||||||
|
named_ports = optional(map(number), {})
|
||||||
|
project_id = optional(string)
|
||||||
|
}))
|
||||||
|
default = {}
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "https_proxy_config" {
|
||||||
|
description = "HTTPS proxy connfiguration."
|
||||||
|
type = object({
|
||||||
|
certificate_manager_certificates = optional(list(string), [])
|
||||||
|
quic_override = optional(string)
|
||||||
|
ssl_policy = optional(string)
|
||||||
|
})
|
||||||
|
default = {}
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "labels" {
|
||||||
|
description = "Labels set on resources."
|
||||||
|
type = map(string)
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "name" {
|
||||||
|
description = "Load balancer name."
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "neg_configs" {
|
||||||
|
description = "Optional network endpoint groups to create. Can be referenced in backends via key or outputs."
|
||||||
|
type = map(object({
|
||||||
|
project_id = optional(string)
|
||||||
|
cloudrun = optional(object({
|
||||||
|
region = string
|
||||||
|
target_service = optional(object({
|
||||||
|
name = string
|
||||||
|
tag = optional(string)
|
||||||
|
}))
|
||||||
|
target_urlmask = optional(string)
|
||||||
|
}))
|
||||||
|
gce = optional(object({
|
||||||
|
zone = string
|
||||||
|
# default_port = optional(number)
|
||||||
|
network = optional(string)
|
||||||
|
subnetwork = optional(string)
|
||||||
|
endpoints = optional(map(object({
|
||||||
|
instance = string
|
||||||
|
ip_address = string
|
||||||
|
port = number
|
||||||
|
})))
|
||||||
|
|
||||||
|
}))
|
||||||
|
hybrid = optional(object({
|
||||||
|
zone = string
|
||||||
|
network = optional(string)
|
||||||
|
# re-enable once provider properly support this
|
||||||
|
# default_port = optional(number)
|
||||||
|
endpoints = optional(map(object({
|
||||||
|
ip_address = string
|
||||||
|
port = number
|
||||||
|
})))
|
||||||
|
}))
|
||||||
|
psc = optional(object({
|
||||||
|
region = string
|
||||||
|
target_service = string
|
||||||
|
network = optional(string)
|
||||||
|
subnetwork = optional(string)
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
default = {}
|
||||||
|
nullable = false
|
||||||
|
validation {
|
||||||
|
condition = alltrue([
|
||||||
|
for k, v in var.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.psc, null) == null ? 0 : 1) == 1
|
||||||
|
)
|
||||||
|
])
|
||||||
|
error_message = "Only one type of neg can be configured at a time."
|
||||||
|
}
|
||||||
|
validation {
|
||||||
|
condition = alltrue([
|
||||||
|
for k, v in var.neg_configs : (
|
||||||
|
v.cloudrun == null
|
||||||
|
? true
|
||||||
|
: v.cloudrun.target_urlmask != null || v.cloudrun.target_service != null
|
||||||
|
)
|
||||||
|
])
|
||||||
|
error_message = "Cloud Run negs need either target type or target urlmask defined."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "network_tier_premium" {
|
||||||
|
description = "Use premium network tier. Defaults to true."
|
||||||
|
type = bool
|
||||||
|
default = true
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ports" {
|
||||||
|
description = "Optional ports for HTTP load balancer, valid ports are 80 and 8080."
|
||||||
|
type = list(string)
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "project_id" {
|
||||||
|
description = "Project id."
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "protocol" {
|
||||||
|
description = "Protocol supported by this load balancer."
|
||||||
|
type = string
|
||||||
|
default = "HTTP"
|
||||||
|
nullable = false
|
||||||
|
validation {
|
||||||
|
condition = (
|
||||||
|
var.protocol == null || var.protocol == "HTTP" || var.protocol == "HTTPS"
|
||||||
|
)
|
||||||
|
error_message = "Protocol must be HTTP or HTTPS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "service_directory_registration" {
|
||||||
|
description = "Service directory namespace and service used to register this load balancer."
|
||||||
|
type = object({
|
||||||
|
namespace = string
|
||||||
|
service_directory_region = string
|
||||||
|
})
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vpc_config" {
|
||||||
|
description = "VPC-level configuration."
|
||||||
|
type = object({
|
||||||
|
network = string
|
||||||
|
subnetworks = map(string)
|
||||||
|
})
|
||||||
|
nullable = false
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
# https://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 = ">= 1.5.1"
|
||||||
|
required_providers {
|
||||||
|
google = {
|
||||||
|
source = "hashicorp/google"
|
||||||
|
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||||
|
}
|
||||||
|
google-beta = {
|
||||||
|
source = "hashicorp/google-beta"
|
||||||
|
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -69,6 +69,24 @@ variable "subnet" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "subnet1" {
|
||||||
|
default = {
|
||||||
|
name = "subnet_name"
|
||||||
|
region = "subnet_region"
|
||||||
|
cidr = "subnet_cidr"
|
||||||
|
self_link = "subnet_self_link"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "subnet2" {
|
||||||
|
default = {
|
||||||
|
name = "subnet_name"
|
||||||
|
region = "subnet_region"
|
||||||
|
cidr = "subnet_cidr"
|
||||||
|
self_link = "subnet_self_link"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
variable "vpc" {
|
variable "vpc" {
|
||||||
default = {
|
default = {
|
||||||
name = "vpc-name"
|
name = "vpc-name"
|
||||||
|
|
Loading…
Reference in New Issue