update changelog

This commit is contained in:
Ludo 2022-12-01 23:55:52 +01:00
parent 477a1bb388
commit 2dc66b0493
14 changed files with 3732 additions and 0 deletions

View File

@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
### BLUEPRINTS
- [[#1024](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1024)] Fix Apigee PAYG environment node config ([g-greatdevaks](https://github.com/g-greatdevaks)) <!-- 2022-11-29 13:08:12+00:00 -->
- [[#1019](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1019)] Added endpoint attachments to Apigee module ([apichick](https://github.com/apichick)) <!-- 2022-11-28 16:53:27+00:00 -->
- [[#1000](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1000)] ADFS blueprint fixes ([apichick](https://github.com/apichick)) <!-- 2022-11-28 12:43:33+00:00 -->
- [[#1001](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1001)] Binauthz blueprint fixes related to project creation ([apichick](https://github.com/apichick)) <!-- 2022-11-28 11:45:11+00:00 -->
@ -114,6 +115,12 @@ All notable changes to this project will be documented in this file.
### MODULES
- [[#1026](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1026)] add lifecycle ignore_changes for apigee PAYG env ([g-greatdevaks](https://github.com/g-greatdevaks)) <!-- 2022-12-01 10:38:19+00:00 -->
- [[#1031](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1031)] Fix default_rules_config description in firewall module ([ludoo](https://github.com/ludoo)) <!-- 2022-12-01 09:04:13+00:00 -->
- [[#1028](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1028)] **incompatible change:** Align rest of vpn modules with #1027 ([juliocc](https://github.com/juliocc)) <!-- 2022-11-30 15:37:24+00:00 -->
- [[#1027](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1027)] **incompatible change:** Update VPN-HA module to tf1.3 ([juliocc](https://github.com/juliocc)) <!-- 2022-11-30 10:50:06+00:00 -->
- [[#1025](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1025)] fix apigee PAYG env node config dynamic block ([g-greatdevaks](https://github.com/g-greatdevaks)) <!-- 2022-11-30 04:53:43+00:00 -->
- [[#1024](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1024)] Fix Apigee PAYG environment node config ([g-greatdevaks](https://github.com/g-greatdevaks)) <!-- 2022-11-29 13:08:12+00:00 -->
- [[#1019](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1019)] Added endpoint attachments to Apigee module ([apichick](https://github.com/apichick)) <!-- 2022-11-28 16:53:27+00:00 -->
- [[#1018](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1018)] Apigee instance doc examples ([danistrebel](https://github.com/danistrebel)) <!-- 2022-11-28 11:10:12+00:00 -->
- [[#1016](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1016)] Fix memory/cpu typo in gke cluster module ([joeheaton](https://github.com/joeheaton)) <!-- 2022-11-27 17:29:26+00:00 -->
@ -191,6 +198,8 @@ All notable changes to this project will be documented in this file.
### TOOLS
- [[#1022](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1022)] Replace `set-output` with env variable and remove single quotes on labels ([kunzese](https://github.com/kunzese)) <!-- 2022-11-29 08:57:44+00:00 -->
- [[#1021](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1021)] Add OpenContainers annotations to published container images ([kunzese](https://github.com/kunzese)) <!-- 2022-11-29 08:11:53+00:00 -->
- [[#1017](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1017)] Fix auto-labeling ([ludoo](https://github.com/ludoo)) <!-- 2022-11-28 14:00:32+00:00 -->
- [[#1013](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1013)] Update labeler.yml ([ludoo](https://github.com/ludoo)) <!-- 2022-11-25 13:27:47+00:00 -->
- [[#1010](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1010)] Enforce nonempty descriptions ending in a dot ([juliocc](https://github.com/juliocc)) <!-- 2022-11-25 09:15:29+00:00 -->

View File

@ -0,0 +1,581 @@
# External Global (HTTP/S) Load Balancer Module
The module allows managing External Global HTTP/HTTPS Load Balancers (XGLB), integrating the global forwarding rule, the url-map, the backends (supporting buckets and groups), and optional health checks and SSL certificates (both managed and unmanaged). It's designed to be a simple match for the [`gcs`](../gcs) and the [`compute-vm`](../compute-vm) modules, which can be used to manage GCS buckets, instance templates and instance groups.
## Examples
### GCS Bucket Minimal Example
This is a minimal example, which creates a global HTTP load balancer, pointing the path `/` to an existing GCS bucket called `my_test_bucket`.
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
backend_services_config = {
my-bucket-backend = {
bucket_config = {
bucket_name = "my_test_bucket"
options = null
}
group_config = null
enable_cdn = false
cdn_config = null
}
}
}
# tftest modules=1 resources=4
```
### Group Backend Service Minimal Example
A very similar coniguration also applies to GCE instance groups:
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
backend_services_config = {
my-group-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_test_group"
options = null
}
],
health_checks = []
log_config = null
options = null
}
}
}
}
# tftest modules=1 resources=5
```
### Health Checks For Group Backend Services
Group backend services support health checks.
If no health checks are specified, a default HTTP health check is created and associated to each group backend service. The default health check configuration can be modified through the `health_checks_config_defaults` variable.
Alternatively, one or more health checks can be either contextually created or attached, if existing. If the id of the health checks specified is equal to one of the keys of the `health_checks_config` variable, the health check is contextually created; otherwise, the health check id is used as is, assuming an health check alredy exists.
For example, to contextually create a health check and attach it to the backend service:
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
backend_services_config = {
my-group-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_test_group"
options = null
}
],
health_checks = ["hc_1"]
log_config = null
options = null
}
}
}
health_checks_config = {
hc_1 = {
type = "http"
logging = true
options = {
timeout_sec = 40
}
check = {
port_specification = "USE_SERVING_PORT"
}
}
}
}
# tftest modules=1 resources=5
```
### Serverless Backends
Serverless backends can also be used, as shown in the example below.
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
# This is important as serverless backends require no HCs
health_checks_config_defaults = null
backend_services_config = {
my-serverless-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = google_compute_region_network_endpoint_group.serverless-neg.id
options = null
}
],
health_checks = []
log_config = null
options = null
}
}
}
}
resource "google_compute_region_network_endpoint_group" "serverless-neg" {
name = "my-serverless-neg"
project = var.project_id
region = "europe-west1"
network_endpoint_type = "SERVERLESS"
cloud_run {
service = "my-cloud-run-service"
}
}
# tftest modules=1 resources=5
```
### Mixing Backends
Backends can be multiple, group and bucket backends can be mixed and group backends support multiple groups.
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
backend_services_config = {
my-group-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_test_group"
options = null
}
],
health_checks = []
log_config = null
options = null
}
},
another-group-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_other_test_group"
options = null
}
],
health_checks = []
log_config = null
options = null
}
},
a-bucket-backend = {
bucket_config = {
bucket_name = "my_test_bucket"
options = null
}
group_config = null
enable_cdn = false
cdn_config = null
}
}
}
# tftest modules=1 resources=7
```
### Url-map
The url-map can be customized with lots of different configurations. This includes leveraging multiple backends in different parts of the configuration.
Given its complexity, it's left to the user passing the right data structure.
For simplicity, *if no configurations are given* the first backend service defined (in alphabetical order, with priority to bucket backend services, if any) is used as the *default_service*, thus answering to the root (*/*) path.
Backend services can be specified as needed in the url-map configuration, referencing the id used to declare them in the backend services map. If a corresponding backend service is found, their object id is automatically used; otherwise, it is assumed that the string passed is the id of an already existing backend and it is given to the provider as it was passed.
In this example, we're using one backend service as the default backend
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
url_map_config = {
default_service = "my-group-backend"
default_route_action = null
default_url_redirect = null
tests = null
header_action = null
host_rules = []
path_matchers = [
{
name = "my-example-page"
path_rules = [
{
paths = ["/my-example-page"]
service = "another-group-backend"
}
]
}
]
}
backend_services_config = {
my-group-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_test_group"
options = null
}
],
health_checks = []
log_config = null
options = null
}
},
my-example-page = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_other_test_group"
options = null
}
],
health_checks = []
log_config = null
options = null
}
}
}
}
# tftest modules=1 resources=6
```
### Reserve a static IP address
Optionally, a static IP address can be reserved:
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
reserve_ip_address = true
backend_services_config = {
my-group-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_test_group"
options = null
}
],
health_checks = []
log_config = null
options = null
}
}
}
}
# tftest modules=1 resources=6
```
### HTTPS And SSL Certificates
HTTPS is disabled by default but it can be optionally enabled.
The module supports both managed and unmanaged certificates, and they can be either created contextually with other resources or attached, if already existing.
If no `ssl_certificates_config` variable is specified, a managed certificate for the domain *example.com* is automatically created.
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
https = true
backend_services_config = {
my-group-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_test_group"
options = null
}
],
health_checks = []
log_config = null
options = null
}
}
}
}
# tftest modules=1 resources=6
```
Otherwise, SSL certificates can be explicitely defined. In this case, they'll need to be referenced from the `target_proxy_https_config.ssl_certificates` variable.
If the ids specified in the `target_proxy_https_config` variable are not found in the `ssl_certificates_config` map, they are used as is, assuming the ssl certificates already exist.
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
https = true
ssl_certificates_config = {
my-domain = {
domains = [
"my-domain.com"
],
unmanaged_config = null
}
}
target_proxy_https_config = {
ssl_certificates = [
"my-domain",
"an-existing-cert"
]
}
backend_services_config = {
my-group-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_test_group"
options = null
}
]
health_checks = []
log_config = null
options = null
}
}
}
}
# tftest modules=1 resources=6
```
Using unamanged certificates is also possible. Here is an example:
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
https = true
ssl_certificates_config = {
my-domain = {
domains = [
"my-domain.com"
],
unmanaged_config = {
tls_private_key = nonsensitive(tls_private_key.self_signed_key.private_key_pem)
tls_self_signed_cert = nonsensitive(tls_self_signed_cert.self_signed_cert.cert_pem)
}
}
}
target_proxy_https_config = {
ssl_certificates = [
"my-domain"
]
}
backend_services_config = {
my-group-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_test_group"
options = null
}
],
health_checks = []
log_config = null
options = null
}
}
}
}
resource "tls_private_key" "self_signed_key" {
algorithm = "RSA"
rsa_bits = 2048
}
resource "tls_self_signed_cert" "self_signed_cert" {
private_key_pem = tls_private_key.self_signed_key.private_key_pem
validity_period_hours = 12
early_renewal_hours = 3
dns_names = ["example.com"]
allowed_uses = [
"key_encipherment",
"digital_signature",
"server_auth"
]
subject {
common_name = "example.com"
organization = "My Test Org"
}
}
# tftest modules=1 resources=8
```
## Regional Load Balancing
You can also use regional load balancing by specifying a `region` parameter:
```hcl
module "glb" {
source = "./fabric/modules/net-glb"
name = "glb-test"
project_id = var.project_id
region = var.region
backend_services_config = {
my-group-backend = {
bucket_config = null
enable_cdn = false
cdn_config = null
group_config = {
backends = [
{
group = "my_test_group"
options = null
}
],
health_checks = []
log_config = null
options = null
}
}
}
}
# tftest modules=1 resources=5
```
## Components And Files Mapping
An External Global Load Balancer is made of multiple components, that change depending on the configurations. Sometimes, it may be tricky to understand what they are, and how they relate to each other. Following, we provide a very brief overview to become more familiar with them.
- The global load balancer [forwarding rule](global-forwarding-rule.tf) binds a frontend public Virtual IP (VIP) to an HTTP(S) [target proxy](target-proxy.tf).
- If the target proxy is HTTPS, it requires one or more managed or unmanaged [SSL certificates](ssl-certificates.tf).
Target proxies leverage [url-maps](url-map.tf): set of L7 rules, which create a mapping between specific hostnames, URIs (and more) to one or more [backends services](backend-services.tf).
- [Backend services](backend-services.tf) can either link to a bucket or one or multiple groups, which can be GCE instance groups or NEGs. It is assumed in this module that buckets and groups are previously created through other modules, and passed in as input variables.
- Backend services support one or more [health checks](health-checks.tf), used to verify that the backend is indeed healthy, so that traffic can be forwarded to it. Health checks currently supported in this module are HTTP, HTTPS, HTTP2, SSL, TCP.
<!-- TFDOC OPTS files:1 -->
<!-- BEGIN TFDOC -->
## Files
| name | description | resources |
|---|---|---|
| [backend-services.tf](./backend-services.tf) | Bucket and group backend services. | <code>google_compute_backend_bucket</code> · <code>google_compute_backend_service</code> |
| [global-forwarding-rule.tf](./global-forwarding-rule.tf) | Global address and forwarding rule. | <code>google_compute_global_address</code> · <code>google_compute_global_forwarding_rule</code> |
| [health-checks.tf](./health-checks.tf) | Health checks. | <code>google_compute_health_check</code> · <code>google_compute_region_health_check</code> |
| [outputs.tf](./outputs.tf) | Module outputs. | |
| [regional-backend-services.tf](./regional-backend-services.tf) | Bucket and group backend services for regional load balancers. | <code>google_compute_region_backend_service</code> |
| [regional-forwarding-rule.tf](./regional-forwarding-rule.tf) | Global address and forwarding rule. | <code>google_compute_address</code> · <code>google_compute_forwarding_rule</code> |
| [regional-url-map.tf](./regional-url-map.tf) | regional URL maps. | <code>google_compute_region_url_map</code> |
| [ssl-certificates.tf](./ssl-certificates.tf) | SSL certificates. | <code>google_compute_managed_ssl_certificate</code> · <code>google_compute_ssl_certificate</code> |
| [target-proxy.tf](./target-proxy.tf) | HTTP and HTTPS target proxies. | <code>google_compute_region_target_http_proxy</code> · <code>google_compute_region_target_https_proxy</code> · <code>google_compute_target_http_proxy</code> · <code>google_compute_target_https_proxy</code> |
| [url-map.tf](./url-map.tf) | URL maps. | <code>google_compute_url_map</code> |
| [variables.tf](./variables.tf) | Module variables. | |
| [versions.tf](./versions.tf) | Version pins. | |
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [name](variables.tf#L186) | Load balancer name. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L191) | Project id. | <code>string</code> | ✓ | |
| [backend_services_config](variables.tf#L17) | The backends services configuration. | <code title="map&#40;object&#40;&#123;&#10; enable_cdn &#61; bool&#10;&#10;&#10; cdn_config &#61; object&#40;&#123;&#10; cache_mode &#61; string&#10; client_ttl &#61; number&#10; default_ttl &#61; number&#10; max_ttl &#61; number&#10; negative_caching &#61; bool&#10; negative_caching_policy &#61; map&#40;number&#41;&#10; serve_while_stale &#61; bool&#10; signed_url_cache_max_age_sec &#61; string&#10; &#125;&#41;&#10;&#10;&#10; bucket_config &#61; object&#40;&#123;&#10; bucket_name &#61; string&#10; options &#61; object&#40;&#123;&#10; custom_response_headers &#61; list&#40;string&#41;&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#10;&#10; group_config &#61; object&#40;&#123;&#10; backends &#61; list&#40;object&#40;&#123;&#10; group &#61; string &#35; IG or NEG FQDN address&#10; options &#61; object&#40;&#123;&#10; balancing_mode &#61; string &#35; Can be UTILIZATION, RATE, CONNECTION&#10; capacity_scaler &#61; number &#35; Valid range is &#91;0.0,1.0&#93;&#10; max_connections &#61; number&#10; max_connections_per_instance &#61; number&#10; max_connections_per_endpoint &#61; number&#10; max_rate &#61; number&#10; max_rate_per_instance &#61; number&#10; max_rate_per_endpoint &#61; number&#10; max_utilization &#61; number&#10; &#125;&#41;&#10; &#125;&#41;&#41;&#10; health_checks &#61; list&#40;string&#41;&#10;&#10;&#10; log_config &#61; object&#40;&#123;&#10; enable &#61; bool&#10; sample_rate &#61; number &#35; must be in &#91;0, 1&#93;&#10; &#125;&#41;&#10;&#10;&#10; options &#61; object&#40;&#123;&#10; affinity_cookie_ttl_sec &#61; number&#10; custom_request_headers &#61; list&#40;string&#41;&#10; custom_response_headers &#61; list&#40;string&#41;&#10; connection_draining_timeout_sec &#61; number&#10; load_balancing_scheme &#61; string &#35; only EXTERNAL &#40;default&#41; makes sense here&#10; locality_lb_policy &#61; string&#10; port_name &#61; string&#10; protocol &#61; string&#10; security_policy &#61; string&#10; session_affinity &#61; string&#10; timeout_sec &#61; number&#10;&#10;&#10; circuits_breakers &#61; object&#40;&#123;&#10; max_requests_per_connection &#61; number &#35; Set to 1 to disable keep-alive&#10; max_connections &#61; number &#35; Defaults to 1024&#10; max_pending_requests &#61; number &#35; Defaults to 1024&#10; max_requests &#61; number &#35; Defaults to 1024&#10; max_retries &#61; number &#35; Defaults to 3&#10; &#125;&#41;&#10;&#10;&#10; consistent_hash &#61; object&#40;&#123;&#10; http_header_name &#61; string&#10; minimum_ring_size &#61; string&#10; http_cookie &#61; object&#40;&#123;&#10; name &#61; string&#10; path &#61; string&#10; ttl &#61; object&#40;&#123;&#10; seconds &#61; number&#10; nanos &#61; number&#10; &#125;&#41;&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#10;&#10; iap &#61; object&#40;&#123;&#10; oauth2_client_id &#61; string&#10; oauth2_client_secret &#61; string&#10; oauth2_client_secret_sha256 &#61; string&#10; &#125;&#41;&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [forwarding_rule_config](variables.tf#L112) | Regional forwarding rule configurations. | <code title="object&#40;&#123;&#10; ip_protocol &#61; string&#10; ip_version &#61; string&#10; load_balancing_scheme &#61; string&#10; port_range &#61; string&#10; network_tier &#61; string&#10; network &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; load_balancing_scheme &#61; &#34;EXTERNAL_MANAGED&#34;&#10; ip_protocol &#61; &#34;TCP&#34;&#10; ip_version &#61; &#34;IPV4&#34;&#10; network_tier &#61; &#34;STANDARD&#34;&#10; network &#61; &#34;default&#34;&#10; port_range &#61; null&#10;&#125;">&#123;&#8230;&#125;</code> |
| [global_forwarding_rule_config](variables.tf#L133) | Global forwarding rule configurations. | <code title="object&#40;&#123;&#10; ip_protocol &#61; string&#10; ip_version &#61; string&#10; load_balancing_scheme &#61; string&#10; port_range &#61; string&#10;&#10;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; load_balancing_scheme &#61; &#34;EXTERNAL&#34;&#10; ip_protocol &#61; &#34;TCP&#34;&#10; ip_version &#61; &#34;IPV4&#34;&#10; port_range &#61; null&#10;&#125;">&#123;&#8230;&#125;</code> |
| [health_checks_config](variables.tf#L151) | Custom health checks configuration. | <code title="map&#40;object&#40;&#123;&#10; type &#61; string &#35; http https tcp ssl http2&#10; check &#61; map&#40;any&#41; &#35; actual health check block attributes&#10; options &#61; map&#40;number&#41; &#35; interval, thresholds, timeout&#10; logging &#61; bool&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [health_checks_config_defaults](variables.tf#L162) | Auto-created health check default configuration. | <code title="object&#40;&#123;&#10; type &#61; string &#35; http https tcp ssl http2&#10; check &#61; map&#40;any&#41; &#35; actual health check block attributes&#10; options &#61; map&#40;number&#41; &#35; interval, thresholds, timeout&#10; logging &#61; bool&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; type &#61; &#34;http&#34;&#10; logging &#61; false&#10; options &#61; &#123;&#125;&#10; check &#61; &#123;&#10; port_specification &#61; &#34;USE_SERVING_PORT&#34;&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> |
| [https](variables.tf#L180) | Whether to enable HTTPS. | <code>bool</code> | | <code>false</code> |
| [region](variables.tf#L196) | Create a regional load balancer in this region. | <code>string</code> | | <code>null</code> |
| [reserve_ip_address](variables.tf#L202) | Whether to reserve a static global IP address. | <code>bool</code> | | <code>false</code> |
| [ssl_certificates_config](variables.tf#L208) | The SSL certificate configuration. | <code title="map&#40;object&#40;&#123;&#10; domains &#61; list&#40;string&#41;&#10; unmanaged_config &#61; object&#40;&#123;&#10; tls_private_key &#61; string&#10; tls_self_signed_cert &#61; string&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [ssl_certificates_config_defaults](variables.tf#L221) | The SSL certificate default configuration. | <code title="object&#40;&#123;&#10; domains &#61; list&#40;string&#41;&#10; unmanaged_config &#61; object&#40;&#123;&#10; tls_private_key &#61; string&#10; tls_self_signed_cert &#61; string&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; domains &#61; &#91;&#34;example.com&#34;&#93;,&#10; unmanaged_config &#61; null&#10;&#125;">&#123;&#8230;&#125;</code> |
| [target_proxy_https_config](variables.tf#L237) | The HTTPS target proxy configuration. | <code title="object&#40;&#123;&#10; ssl_certificates &#61; list&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [url_map_config](variables.tf#L245) | The url-map configuration. | <code title="object&#40;&#123;&#10; default_service &#61; string&#10; default_route_action &#61; any&#10; default_url_redirect &#61; map&#40;any&#41;&#10; header_action &#61; any&#10; host_rules &#61; list&#40;any&#41;&#10; path_matchers &#61; list&#40;any&#41;&#10; tests &#61; list&#40;map&#40;string&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
## Outputs
| name | description | sensitive |
|---|---|:---:|
| [backend_services](outputs.tf#L17) | Backend service resources. | |
| [forwarding_rule](outputs.tf#L25) | The regional forwarding rule. | |
| [global_forwarding_rule](outputs.tf#L30) | The global forwarding rule. | |
| [health_checks](outputs.tf#L35) | Health-check resources. | |
| [ip_address](outputs.tf#L40) | The reserved global IP address. | |
| [ip_address_self_link](outputs.tf#L45) | The URI of the reserved global IP address. | |
| [ssl_certificates](outputs.tf#L50) | The SSL certificate. | |
| [target_proxy](outputs.tf#L59) | The target proxy. | |
| [url_map](outputs.tf#L67) | The url-map. | |
<!-- END TFDOC -->

View File

@ -0,0 +1,211 @@
/**
* 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 Bucket and group backend services.
locals {
backend_services_bucket = {
for k, v in coalesce(var.backend_services_config, {}) :
k => v if v.bucket_config != null
}
backend_services_group = {
for k, v in coalesce(var.backend_services_config, {}) :
k => v if v.group_config != null
}
}
resource "google_compute_backend_bucket" "bucket" {
for_each = local.backend_services_bucket
name = "${var.name}-${each.key}"
description = "Terraform managed."
project = var.project_id
bucket_name = try(each.value.bucket_config.bucket_name, null)
custom_response_headers = try(each.value.bucket_config.options.custom_response_headers, null)
enable_cdn = try(each.value.enable_cdn, null)
dynamic "cdn_policy" {
for_each = try(each.value.cdn_policy, null) == null ? [] : [each.value.cdn_policy]
content {
cache_mode = try(cdn_policy.value.cache_mode, null)
client_ttl = try(cdn_policy.value.client_ttl, null)
default_ttl = try(cdn_policy.value.default_ttl, null)
max_ttl = try(cdn_policy.value.max_ttl, null)
negative_caching = try(cdn_policy.value.negative_caching, null)
serve_while_stale = try(cdn_policy.value.serve_while_stale, null)
signed_url_cache_max_age_sec = try(cdn_policy.value.signed_url_cache_max_age_sec, null)
dynamic "negative_caching_policy" {
for_each = try(cdn_policy.value.negative_caching_policy, null) == null ? [] : [cdn_policy.value.negative_caching_policy]
iterator = ncp
content {
code = ncp.value.code
ttl = ncp.value.ttl
}
}
}
}
}
resource "google_compute_backend_service" "group" {
for_each = var.region == null ? local.backend_services_group : {}
name = "${var.name}-${each.key}"
project = var.project_id
description = "Terraform managed."
affinity_cookie_ttl_sec = try(each.value.group_config.options.affinity_cookie_ttl_sec, null)
enable_cdn = try(each.value.enable_cdn, null)
custom_request_headers = try(each.value.group_config.options.custom_request_headers, null)
custom_response_headers = try(each.value.group_config.options.custom_response_headers, null)
connection_draining_timeout_sec = try(each.value.group_config.options.connection_draining_timeout_sec, null)
load_balancing_scheme = try(each.value.group_config.options.load_balancing_scheme, null)
locality_lb_policy = try(each.value.group_config.options.locality_lb_policy, null)
port_name = try(each.value.group_config.options.port_name, null)
protocol = try(each.value.group_config.options.protocol, null)
security_policy = try(each.value.group_config.options.security_policy, null)
session_affinity = try(each.value.group_config.options.session_affinity, null)
timeout_sec = try(each.value.group_config.options.timeout_sec, null)
# If no health checks are defined, use the default one.
# Otherwise, look in the health_checks_config map.
# Otherwise, use the health_check id as is (already existing).
health_checks = (
try(length(each.value.group_config.health_checks), 0) == 0
? try(
[google_compute_health_check.health_check["default"].id],
null
)
: [
for hc in each.value.group_config.health_checks :
try(google_compute_health_check.health_check[hc].id, hc)
]
)
dynamic "backend" {
for_each = try(each.value.group_config.backends, [])
content {
balancing_mode = try(backend.value.options.balancing_mode, null)
capacity_scaler = try(backend.value.options.capacity_scaler, null)
group = try(backend.value.group, null)
max_connections = try(backend.value.options.max_connections, null)
max_connections_per_instance = try(backend.value.options.max_connections_per_instance, null)
max_connections_per_endpoint = try(backend.value.options.max_connections_per_endpoint, null)
max_rate = try(backend.value.options.max_rate, null)
max_rate_per_instance = try(backend.value.options.max_rate_per_instance, null)
max_rate_per_endpoint = try(backend.value.options.max_rate_per_endpoint, null)
max_utilization = try(backend.value.options.max_utilization, null)
}
}
dynamic "circuit_breakers" {
for_each = (
try(each.value.group_config.options.circuit_breakers, null) == null
? []
: [each.value.group_config.options.circuit_breakers]
)
iterator = cb
content {
max_requests_per_connection = try(cb.value.max_requests_per_connection, null)
max_connections = try(cb.value.max_connections, null)
max_pending_requests = try(cb.value.max_pending_requests, null)
max_requests = try(cb.value.max_requests, null)
max_retries = try(cb.value.max_retries, null)
}
}
dynamic "consistent_hash" {
for_each = (
try(each.value.group_config.options.consistent_hash, null) == null
? []
: [each.value.group_config.options.consistent_hash]
)
content {
http_header_name = try(consistent_hash.value.http_header_name, null)
minimum_ring_size = try(consistent_hash.value.minimum_ring_size, null)
dynamic "http_cookie" {
for_each = try(consistent_hash.value.http_cookie, null) == null ? [] : [consistent_hash.value.http_cookie]
content {
name = try(http_cookie.value.name, null)
path = try(http_cookie.value.path, null)
dynamic "ttl" {
for_each = try(consistent_hash.value.ttl, null) == null ? [] : [consistent_hash.value.ttl]
content {
seconds = try(ttl.value.seconds, null) # Must be from 0 to 315,576,000,000 inclusive
nanos = try(ttl.value.nanos, null) # Must be from 0 to 999,999,999 inclusive
}
}
}
}
}
}
dynamic "cdn_policy" {
for_each = (
try(each.value.cdn_policy, null) == null
? []
: [each.value.cdn_policy]
)
iterator = cdn_policy
content {
signed_url_cache_max_age_sec = try(cdn_policy.value.signed_url_cache_max_age_sec, null)
default_ttl = try(cdn_policy.value.default_ttl, null)
max_ttl = try(cdn_policy.value.max_ttl, null)
client_ttl = try(cdn_policy.value.client_ttl, null)
negative_caching = try(cdn_policy.value.negative_caching, null)
cache_mode = try(cdn_policy.value.cache_mode, null)
serve_while_stale = try(cdn_policy.value.serve_while_stale, null)
dynamic "negative_caching_policy" {
for_each = (
try(cdn_policy.value.negative_caching_policy, null) == null
? []
: [cdn_policy.value.negative_caching_policy]
)
iterator = ncp
content {
code = try(ncp.value.code, null)
ttl = try(ncp.value.ttl, null)
}
}
}
}
dynamic "iap" {
for_each = (
try(each.value.group_config.options.iap, null) == null
? []
: [each.value.group_config.options.iap]
)
content {
oauth2_client_id = try(iap.value.oauth2_client_id, null)
oauth2_client_secret = try(iap.value.oauth2_client_secret, null) # sensitive
oauth2_client_secret_sha256 = try(iap.value.oauth2_client_secret_sha256, null) # sensitive
}
}
dynamic "log_config" {
for_each = (
try(each.value.group_config.log_config, null) == null
? []
: [each.value.group_config.log_config]
)
content {
enable = try(log_config.value.enable, null)
sample_rate = try(log_config.value.sample_rate, null)
}
}
}

View File

@ -0,0 +1,57 @@
/**
* 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 Global address and forwarding rule.
locals {
ip_address = var.region == null ? (
var.region == null && var.reserve_ip_address
? google_compute_global_address.static_ip.0.id
: null
) : null
port_range = coalesce(
var.global_forwarding_rule_config.port_range,
var.https ? "443" : "80"
)
target = var.region == null ? (
var.https
? google_compute_target_https_proxy.https.0.id
: google_compute_target_http_proxy.http.0.id
) : null
}
resource "google_compute_global_address" "static_ip" {
count = var.region == null && var.reserve_ip_address ? 1 : 0
provider = google-beta
name = var.name
project = var.project_id
description = "Terraform managed."
}
resource "google_compute_global_forwarding_rule" "forwarding_rule" {
count = var.region == null ? 1 : 0
provider = google-beta
name = var.name
project = var.project_id
description = "Terraform managed."
ip_protocol = var.global_forwarding_rule_config.ip_protocol
load_balancing_scheme = var.global_forwarding_rule_config.load_balancing_scheme
port_range = local.port_range
target = local.target
ip_address = local.ip_address
}

View File

@ -0,0 +1,253 @@
/**
* 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 checks.
locals {
# Get group backend services without health checks defined
_backends_without_hcs = [
for k, v in coalesce(var.backend_services_config, {}) :
v if(
v.group_config != null
&& (
try(v.group_config.health_checks, null) == null
|| length(try(v.group_config.health_checks, [])) == 0
)
)
]
health_checks_config_defaults = (
try(var.health_checks_config_defaults, null) == null
? null
: { default = var.health_checks_config_defaults }
)
# If at least one group backend service without HC is defined,
# create also a default HC (if default HC is not null)
health_checks_config = (
length(local._backends_without_hcs) > 0
? merge(
coalesce(local.health_checks_config_defaults, {}),
coalesce(var.health_checks_config, {})
)
: coalesce(var.health_checks_config, {})
)
}
resource "google_compute_health_check" "health_check" {
for_each = var.region == null ? local.health_checks_config : {}
provider = google-beta
name = "${var.name}-${each.key}"
project = var.project_id
description = "Terraform managed."
check_interval_sec = try(each.value.options.check_interval_sec, null)
healthy_threshold = try(each.value.options.healthy_threshold, null)
timeout_sec = try(each.value.options.timeout_sec, null)
unhealthy_threshold = try(each.value.options.unhealthy_threshold, null)
dynamic "http_health_check" {
for_each = (
try(each.value.type, null) == "http" || try(each.value.type, null) == null
? { 1 = 1 }
: {}
)
content {
host = try(each.value.check.host, null)
port = try(each.value.check.port, null)
port_name = try(each.value.check.port_name, null)
port_specification = try(each.value.check.port_specification, null)
proxy_header = try(each.value.check.proxy_header, null)
request_path = try(each.value.check.request_path, null)
response = try(each.value.check.response, null)
}
}
dynamic "https_health_check" {
for_each = (
try(each.value.type, null) == "https" || try(each.value.type, null) == null
? { 1 = 1 }
: {}
)
content {
host = try(each.value.check.host, null)
port = try(each.value.check.port, null)
port_name = try(each.value.check.port_name, null)
port_specification = try(each.value.check.port_specification, null)
proxy_header = try(each.value.check.proxy_header, null)
request_path = try(each.value.check.request_path, null)
response = try(each.value.check.response, null)
}
}
dynamic "tcp_health_check" {
for_each = (
try(each.value.type, null) == "tcp" || try(each.value.type, null) == null
? { 1 = 1 }
: {}
)
content {
port = try(each.value.check.port, null)
port_name = try(each.value.check.port_name, null)
port_specification = try(each.value.check.port_specification, null)
proxy_header = try(each.value.check.proxy_header, null)
request = try(each.value.check.request, null)
response = try(each.value.check.response, null)
}
}
dynamic "ssl_health_check" {
for_each = (
try(each.value.type, null) == "ssl" || try(each.value.type, null) == null
? { 1 = 1 }
: {}
)
content {
port = try(each.value.check.port, null)
port_name = try(each.value.check.port_name, null)
port_specification = try(each.value.check.port_specification, null)
proxy_header = try(each.value.check.proxy_header, null)
request = try(each.value.check.request, null)
response = try(each.value.check.response, null)
}
}
dynamic "http2_health_check" {
for_each = (
try(each.value.type, null) == "http2" || try(each.value.type, null) == null
? { 1 = 1 }
: {}
)
content {
host = try(each.value.check.host, null)
port = try(each.value.check.port, null)
port_name = try(each.value.check.port_name, null)
port_specification = try(each.value.check.port_specification, null)
proxy_header = try(each.value.check.proxy_header, null)
request_path = try(each.value.check.request_path, null)
response = try(each.value.check.response, null)
}
}
dynamic "log_config" {
for_each = try(each.value.logging, false) ? { 0 = 0 } : {}
content {
enable = true
}
}
}
resource "google_compute_region_health_check" "health_check" {
for_each = var.region != null ? local.health_checks_config : {}
provider = google-beta
name = "${var.name}-${each.key}"
project = var.project_id
region = var.region
description = "Terraform managed."
check_interval_sec = try(each.value.options.check_interval_sec, null)
healthy_threshold = try(each.value.options.healthy_threshold, null)
timeout_sec = try(each.value.options.timeout_sec, null)
unhealthy_threshold = try(each.value.options.unhealthy_threshold, null)
dynamic "http_health_check" {
for_each = (
try(each.value.type, null) == "http" || try(each.value.type, null) == null
? { 1 = 1 }
: {}
)
content {
host = try(each.value.check.host, null)
port = try(each.value.check.port, null)
port_name = try(each.value.check.port_name, null)
port_specification = try(each.value.check.port_specification, null)
proxy_header = try(each.value.check.proxy_header, null)
request_path = try(each.value.check.request_path, null)
response = try(each.value.check.response, null)
}
}
dynamic "https_health_check" {
for_each = (
try(each.value.type, null) == "https" || try(each.value.type, null) == null
? { 1 = 1 }
: {}
)
content {
host = try(each.value.check.host, null)
port = try(each.value.check.port, null)
port_name = try(each.value.check.port_name, null)
port_specification = try(each.value.check.port_specification, null)
proxy_header = try(each.value.check.proxy_header, null)
request_path = try(each.value.check.request_path, null)
response = try(each.value.check.response, null)
}
}
dynamic "tcp_health_check" {
for_each = (
try(each.value.type, null) == "tcp" || try(each.value.type, null) == null
? { 1 = 1 }
: {}
)
content {
port = try(each.value.check.port, null)
port_name = try(each.value.check.port_name, null)
port_specification = try(each.value.check.port_specification, null)
proxy_header = try(each.value.check.proxy_header, null)
request = try(each.value.check.request, null)
response = try(each.value.check.response, null)
}
}
dynamic "ssl_health_check" {
for_each = (
try(each.value.type, null) == "ssl" || try(each.value.type, null) == null
? { 1 = 1 }
: {}
)
content {
port = try(each.value.check.port, null)
port_name = try(each.value.check.port_name, null)
port_specification = try(each.value.check.port_specification, null)
proxy_header = try(each.value.check.proxy_header, null)
request = try(each.value.check.request, null)
response = try(each.value.check.response, null)
}
}
dynamic "http2_health_check" {
for_each = (
try(each.value.type, null) == "http2" || try(each.value.type, null) == null
? { 1 = 1 }
: {}
)
content {
host = try(each.value.check.host, null)
port = try(each.value.check.port, null)
port_name = try(each.value.check.port_name, null)
port_specification = try(each.value.check.port_specification, null)
proxy_header = try(each.value.check.proxy_header, null)
request_path = try(each.value.check.request_path, null)
response = try(each.value.check.response, null)
}
}
dynamic "log_config" {
for_each = try(each.value.logging, false) ? { 0 = 0 } : {}
content {
enable = true
}
}
}

View File

@ -0,0 +1,70 @@
/**
* 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.
*/
output "backend_services" {
description = "Backend service resources."
value = {
bucket = try(google_compute_backend_bucket.bucket, [])
group = try(google_compute_backend_service.group, [])
}
}
output "forwarding_rule" {
description = "The regional forwarding rule."
value = var.region == null ? google_compute_global_forwarding_rule.forwarding_rule.0 : google_compute_forwarding_rule.forwarding_rule.0
}
output "global_forwarding_rule" {
description = "The global forwarding rule."
value = var.region == null ? google_compute_global_forwarding_rule.forwarding_rule.0 : null
}
output "health_checks" {
description = "Health-check resources."
value = try(google_compute_health_check.health_check, [])
}
output "ip_address" {
description = "The reserved global IP address."
value = var.region == null ? try(google_compute_global_address.static_ip.0.address, null) : try(google_compute_address.static_ip.0.address, null)
}
output "ip_address_self_link" {
description = "The URI of the reserved global IP address."
value = var.region == null ? google_compute_global_forwarding_rule.forwarding_rule.0.ip_address : google_compute_forwarding_rule.forwarding_rule.0.ip_address
}
output "ssl_certificates" {
description = "The SSL certificate."
value = try(
google_compute_managed_ssl_certificate.managed,
google_compute_ssl_certificate.unmanaged,
null
)
}
output "target_proxy" {
description = "The target proxy."
value = try(
google_compute_target_http_proxy.http,
google_compute_target_https_proxy.https
)
}
output "url_map" {
description = "The url-map."
value = google_compute_url_map.url_map
}

View File

@ -0,0 +1,164 @@
/**
* 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 Bucket and group backend services for regional load balancers.
resource "google_compute_region_backend_service" "group" {
for_each = var.region != null ? local.backend_services_group : {}
name = "${var.name}-${each.key}"
project = var.project_id
region = var.region
description = "Terraform managed."
affinity_cookie_ttl_sec = try(each.value.group_config.options.affinity_cookie_ttl_sec, null)
enable_cdn = try(each.value.enable_cdn, null)
connection_draining_timeout_sec = try(each.value.group_config.options.connection_draining_timeout_sec, null)
load_balancing_scheme = try(each.value.group_config.options.load_balancing_scheme, null)
locality_lb_policy = try(each.value.group_config.options.locality_lb_policy, null)
port_name = try(each.value.group_config.options.port_name, null)
protocol = try(each.value.group_config.options.protocol, null)
session_affinity = try(each.value.group_config.options.session_affinity, null)
timeout_sec = try(each.value.group_config.options.timeout_sec, null)
# If no health checks are defined, use the default one.
# Otherwise, look in the health_checks_config map.
# Otherwise, use the health_check id as is (already existing).
health_checks = (
try(length(each.value.group_config.health_checks), 0) == 0
? try(
[google_compute_region_health_check.health_check["default"].id],
null
)
: [
for hc in each.value.group_config.health_checks :
try(google_compute_region_health_check.health_check[hc].id, hc)
]
)
dynamic "backend" {
for_each = try(each.value.group_config.backends, [])
content {
balancing_mode = try(backend.value.options.balancing_mode, null)
capacity_scaler = try(backend.value.options.capacity_scaler, null)
group = try(backend.value.group, null)
max_connections = try(backend.value.options.max_connections, null)
max_connections_per_instance = try(backend.value.options.max_connections_per_instance, null)
max_connections_per_endpoint = try(backend.value.options.max_connections_per_endpoint, null)
max_rate = try(backend.value.options.max_rate, null)
max_rate_per_instance = try(backend.value.options.max_rate_per_instance, null)
max_rate_per_endpoint = try(backend.value.options.max_rate_per_endpoint, null)
max_utilization = try(backend.value.options.max_utilization, null)
}
}
dynamic "circuit_breakers" {
for_each = (
try(each.value.group_config.options.circuit_breakers, null) == null
? []
: [each.value.group_config.options.circuit_breakers]
)
iterator = cb
content {
max_requests_per_connection = try(cb.value.max_requests_per_connection, null)
max_connections = try(cb.value.max_connections, null)
max_pending_requests = try(cb.value.max_pending_requests, null)
max_requests = try(cb.value.max_requests, null)
max_retries = try(cb.value.max_retries, null)
}
}
dynamic "consistent_hash" {
for_each = (
try(each.value.group_config.options.consistent_hash, null) == null
? []
: [each.value.group_config.options.consistent_hash]
)
content {
http_header_name = try(consistent_hash.value.http_header_name, null)
minimum_ring_size = try(consistent_hash.value.minimum_ring_size, null)
dynamic "http_cookie" {
for_each = try(consistent_hash.value.http_cookie, null) == null ? [] : [consistent_hash.value.http_cookie]
content {
name = try(http_cookie.value.name, null)
path = try(http_cookie.value.path, null)
dynamic "ttl" {
for_each = try(consistent_hash.value.ttl, null) == null ? [] : [consistent_hash.value.ttl]
content {
seconds = try(ttl.value.seconds, null) # Must be from 0 to 315,576,000,000 inclusive
nanos = try(ttl.value.nanos, null) # Must be from 0 to 999,999,999 inclusive
}
}
}
}
}
}
dynamic "cdn_policy" {
for_each = (
try(each.value.cdn_policy, null) == null
? []
: [each.value.cdn_policy]
)
iterator = cdn_policy
content {
signed_url_cache_max_age_sec = try(cdn_policy.value.signed_url_cache_max_age_sec, null)
default_ttl = try(cdn_policy.value.default_ttl, null)
max_ttl = try(cdn_policy.value.max_ttl, null)
client_ttl = try(cdn_policy.value.client_ttl, null)
negative_caching = try(cdn_policy.value.negative_caching, null)
cache_mode = try(cdn_policy.value.cache_mode, null)
serve_while_stale = try(cdn_policy.value.serve_while_stale, null)
dynamic "negative_caching_policy" {
for_each = (
try(cdn_policy.value.negative_caching_policy, null) == null
? []
: [cdn_policy.value.negative_caching_policy]
)
iterator = ncp
content {
code = try(ncp.value.code, null)
}
}
}
}
dynamic "iap" {
for_each = (
try(each.value.group_config.options.iap, null) == null
? []
: [each.value.group_config.options.iap]
)
content {
oauth2_client_id = try(iap.value.oauth2_client_id, null)
oauth2_client_secret = try(iap.value.oauth2_client_secret, null) # sensitive
oauth2_client_secret_sha256 = try(iap.value.oauth2_client_secret_sha256, null) # sensitive
}
}
dynamic "log_config" {
for_each = (
try(each.value.group_config.log_config, null) == null
? []
: [each.value.group_config.log_config]
)
content {
enable = try(log_config.value.enable, null)
sample_rate = try(log_config.value.sample_rate, null)
}
}
}

View File

@ -0,0 +1,62 @@
/**
* 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 Global address and forwarding rule.
locals {
regional_ip_address = var.region != null ? (
var.reserve_ip_address
? google_compute_address.static_ip.0.id
: null
) : null
regional_port_range = coalesce(
var.forwarding_rule_config.port_range,
var.https ? "443" : "80"
)
regional_target = var.region != null ? (
var.https
? google_compute_region_target_https_proxy.https.0.id
: google_compute_region_target_http_proxy.http.0.id
) : null
}
resource "google_compute_address" "static_ip" {
count = var.region != null && var.reserve_ip_address ? 1 : 0
provider = google-beta
name = var.name
project = var.project_id
region = var.region
description = "Terraform managed."
address_type = "EXTERNAL"
}
resource "google_compute_forwarding_rule" "forwarding_rule" {
count = var.region != null ? 1 : 0
provider = google-beta
name = var.name
project = var.project_id
region = var.region
description = "Terraform managed."
ip_protocol = var.forwarding_rule_config.ip_protocol
load_balancing_scheme = var.forwarding_rule_config.load_balancing_scheme
port_range = local.regional_port_range
target = local.regional_target
ip_address = local.regional_ip_address
network_tier = var.forwarding_rule_config.network_tier
network = var.forwarding_rule_config.network
}

View File

@ -0,0 +1,717 @@
/**
* 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 regional URL maps.
locals {
# Look for a backend services in the config whose id is
# the default_service given in the url-map.
# If not found, use the default_service id as given
# (assuming it's already existing).
# If the variable is null, will be set to null.
_regional_default_service = try(
google_compute_backend_bucket.bucket[var.url_map_config.default_service].id,
google_compute_region_backend_service.group[var.url_map_config.default_service].id,
var.url_map_config.default_service,
null
)
# If no backend services are specified,
# the first backend service defined is associated
regional_default_service = (
try(local._regional_default_service, null) == null
&& try(var.url_map_config.default_route_action.weighted_backend_services, null) == null
&& try(var.url_map_config.default_url_redirect, null) == null
? try(
google_compute_backend_bucket.bucket[keys(google_compute_backend_bucket.bucket)[0]].id,
google_compute_region_backend_service.group[keys(google_compute_region_backend_service.group)[0]].id,
null
)
: null
)
}
resource "google_compute_region_url_map" "url_map" {
count = var.region != null ? 1 : 0
name = var.name
description = "Terraform managed."
project = var.project_id
region = var.region
default_service = local.regional_default_service
dynamic "host_rule" {
for_each = (
try(var.url_map_config.host_rules, null) == null
? []
: var.url_map_config.host_rules
)
content {
description = try(host_rule.value.description, null)
hosts = try(host_rule.value.hosts, null)
path_matcher = try(host_rule.value.path_matcher, null)
}
}
dynamic "path_matcher" {
for_each = (
try(var.url_map_config.path_matchers, null) == null
? []
: var.url_map_config.path_matchers
)
content {
name = try(path_matcher.value.name, null)
description = try(path_matcher.value.description, null)
default_service = try(
google_compute_backend_bucket.bucket[var.url_map_config.default_service].id,
google_compute_region_backend_service.group[var.url_map_config.default_service].id,
path_matcher.value.default_service,
null
)
dynamic "path_rule" {
for_each = (
try(path_matcher.value.path_rules, null) == null
? []
: path_matcher.value.path_rules
)
content {
paths = try(path_rule.value.paths, null)
service = try(
google_compute_backend_bucket.bucket[path_rule.value.service].id,
google_compute_region_backend_service.group[path_rule.value.service].id,
path_rule.value.service,
null
)
dynamic "route_action" {
for_each = (
try(path_rule.value.route_action, null) == null
? []
: [path_rule.value.route_action]
)
content {
dynamic "cors_policy" {
for_each = (
try(route_action.value.cors_policy, null) == null
? []
: [route_action.value.cors_policy]
)
content {
allow_credentials = try(cors_policy.value.allow_credentials, null)
allow_headers = try(cors_policy.value.allow_headers, null)
allow_methods = try(cors_policy.value.allow_methods, null)
allow_origin_regexes = try(cors_policy.value.allow_origin_regexes, null)
allow_origins = try(cors_policy.value.allow_origins, null)
disabled = try(cors_policy.value.disabled, null)
expose_headers = try(cors_policy.value.expose_headers, null)
max_age = try(cors_policy.value.max_age, null)
}
}
dynamic "fault_injection_policy" {
for_each = (
try(route_action.value.fault_injection_policy, null) == null
? []
: [route_action.value.fault_injection_policy]
)
iterator = policy
content {
dynamic "abort" {
for_each = (
try(policy.value.abort, null) == null
? []
: [policy.value.abort]
)
content {
http_status = try(abort.value.http_status, null) # Must be between 200 and 599 inclusive
percentage = try(abort.value.percentage, null) # Must be between 0.0 and 100.0 inclusive
}
}
dynamic "delay" {
for_each = (
try(policy.value.delay, null) == null
? []
: [policy.value.delay]
)
content {
percentage = try(delay.value.percentage, null) # Must be between 0.0 and 100.0 inclusive
dynamic "fixed_delay" {
for_each = (
try(delay.value.fixed_delay, null) == null
? []
: [delay.value.fixed_delay]
)
content {
nanos = try(fixed_delay.value.nanos, null) # Must be from 0 to 999,999,999 inclusive
seconds = try(fixed_delay.value.seconds, null) # Must be from 0 to 315,576,000,000 inclusive
}
}
}
}
}
}
dynamic "request_mirror_policy" {
for_each = (
try(route_action.value.request_mirror_policy, null) == null
? []
: [route_action.value.request_mirror_policy]
)
iterator = policy
content {
backend_service = try(
google_compute_backend_bucket.bucket[policy.value.backend_service].id,
google_compute_region_backend_service.group[policy.value.backend_service].id,
policy.value.backend_service,
null
)
}
}
dynamic "retry_policy" {
for_each = (
try(route_action.value.retry_policy, null) == null
? []
: [route_action.value.retry_policy]
)
iterator = policy
content {
num_retries = try(policy.num_retries, null) # Must be > 0
# Valid values at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_url_map#retry_conditions
retry_conditions = try(policy.retry_conditions, null)
dynamic "per_try_timeout" {
for_each = (
try(policy.value.per_try_timeout, null) == null
? []
: [policy.value.per_try_timeout]
)
iterator = timeout
content {
nanos = try(timeout.value.nanos, null) # Must be from 0 to 999,999,999 inclusive
seconds = try(timeout.value.seconds, null) # Must be from 0 to 315,576,000,000 inclusive
}
}
}
}
dynamic "timeout" {
for_each = (
try(route_action.value.timeout, null) == null
? []
: [route_action.value.timeout]
)
content {
nanos = try(timeout.value.nanos, null) # Must be from 0 to 999,999,999 inclusive
seconds = try(timeout.value.seconds, null) # Must be from 0 to 315,576,000,000 inclusive
}
}
dynamic "url_rewrite" {
for_each = (
try(route_action.value.url_rewrite, null) == null
? []
: [route_action.value.url_rewrite]
)
content {
host_rewrite = try(url_rewrite.value.host_rewrite, null) # Must be between 1 and 255 characters
path_prefix_rewrite = try(url_rewrite.value.path_prefix_rewrite, null) # Must be between 1 and 1024 characters
}
}
dynamic "weighted_backend_services" {
for_each = (
try(route_action.value.weighted_backend_services, null) == null
? []
: route_action.value.weighted_backend_services
)
iterator = weighted
content {
weight = try(weighted.value.weigth, null)
backend_service = try(
google_compute_backend_bucket.bucket[weighted.value.backend_service].id,
google_compute_backend_service.group[weighted.value.backend_service].id,
policy.value.backend_service,
null
)
dynamic "header_action" {
for_each = (
try(path_matcher.value.header_action, null) == null
? []
: [path_matcher.value.header_action]
)
content {
request_headers_to_remove = try(header_action.value.request_headers_to_remove, null)
response_headers_to_remove = try(header_action.value.response_headers_to_remove, null)
dynamic "request_headers_to_add" {
for_each = (
try(header_action.value.request_headers_to_add, null) == null
? [] :
[header_action.value.request_headers_to_add]
)
content {
header_name = try(request_headers_to_add.value.header_name, null)
header_value = try(request_headers_to_add.value.header_value, null)
replace = try(request_headers_to_add.value.replace, null)
}
}
dynamic "response_headers_to_add" {
for_each = (
try(header_action.response_headers_to_add, null) == null
? []
: [header_action.response_headers_to_add]
)
content {
header_name = try(response_headers_to_add.value.header_name, null)
header_value = try(response_headers_to_add.value.header_value, null)
replace = try(response_headers_to_add.value.replace, null)
}
}
}
}
}
}
}
}
dynamic "url_redirect" {
for_each = (
try(path_rule.value.url_redirect, null) == null
? []
: path_rule.value.url_redirect
)
content {
host_redirect = try(url_redirect.value.host_redirect, null) # Must be between 1 and 255 characters
https_redirect = try(url_redirect.value.https_redirect, null)
path_redirect = try(url_redirect.value.path_redirect, null)
prefix_redirect = try(url_redirect.value.prefix_redirect, null) # Must be between 1 and 1024 characters
# Valid valus at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_url_map#redirect_response_code
redirect_response_code = try(url_redirect.value.redirect_response_code, null)
strip_query = try(url_redirect.value.strip_query, null)
}
}
}
}
dynamic "route_rules" {
for_each = (
try(path_matcher.value.route_rules, null) == null
? []
: path_matcher.value.route_rules
)
content {
priority = try(route_rules.value.priority, null)
service = try(
google_compute_backend_bucket.bucket[route_rules.value.service].id,
google_compute_backend_service.group[route_rules.value.service].id,
route_rules.value.service,
null
)
dynamic "header_action" {
for_each = (
try(path_matcher.value.header_action, null) == null
? []
: [path_matcher.value.header_action]
)
content {
request_headers_to_remove = try(header_action.value.request_headers_to_remove, null)
response_headers_to_remove = try(header_action.value.response_headers_to_remove, null)
dynamic "request_headers_to_add" {
for_each = (
try(header_action.value.request_headers_to_add, null) == null
? []
: [header_action.value.request_headers_to_add]
)
content {
header_name = try(request_headers_to_add.value.header_name, null)
header_value = try(request_headers_to_add.value.header_value, null)
replace = try(request_headers_to_add.value.replace, null)
}
}
dynamic "response_headers_to_add" {
for_each = (
try(header_action.response_headers_to_add, null) == null
? []
: [header_action.response_headers_to_add]
)
content {
header_name = try(response_headers_to_add.value.header_name, null)
header_value = try(response_headers_to_add.value.header_value, null)
replace = try(response_headers_to_add.value.replace, null)
}
}
}
}
dynamic "match_rules" {
for_each = (
try(path_matcher.value.match_rules, null) == null
? []
: path_matcher.value.match_rules
)
content {
full_path_match = try(match_rules.value.full_path_match, null) # Must be between 1 and 1024 characters
ignore_case = try(match_rules.value.ignore_case, null)
prefix_match = try(match_rules.value.prefix_match, null)
regex_match = try(match_rules.value.regex_match, null)
dynamic "header_matches" {
for_each = (
try(match_rules.value.header_matches, null) == null
? []
: [match_rules.value.header_matches]
)
content {
exact_match = try(header_matches.value.exact_match, null)
header_name = try(header_matches.value.header_name, null)
invert_match = try(header_matches.value.invert_match, null)
prefix_match = try(header_matches.value.prefix_match, null)
present_match = try(header_matches.value.present_match, null)
regex_match = try(header_matches.value.regex_match, null)
suffix_match = try(header_matches.value, null)
dynamic "range_match" {
for_each = try(header_matches.value.range_match, null) == null ? [] : [header_matches.value.range_match]
content {
range_end = try(range_match.value.range_end, null)
range_start = try(range_match.value.range_start, null)
}
}
}
}
dynamic "metadata_filters" {
for_each = (
try(match_rules.value.metadata_filters, null) == null
? []
: [match_rules.value.metadata_filters]
)
content {
# Valid values at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_url_map#filter_match_criteria
filter_match_criteria = try(metadata_filters.value.filter_match_criteria, null)
dynamic "filter_labels" {
for_each = (
try(metadata_filters.value.filter_labels, null) == null
? []
: metadata_filters.value.filter_labels
)
content {
name = try(filter_labels.value.name, null) # Must be between 1 and 1024 characters
value = try(filter_labels.value.value, null) # Must be between 1 and 1024 characters
}
}
}
}
dynamic "query_parameter_matches" {
for_each = (
try(match_rules.value.query_parameter_matches, null) == null
? []
: [match_rules.value.query_parameter_matches]
)
iterator = query
content {
exact_match = try(query.value.exact_match, null)
name = try(query.value.name, null)
present_match = try(query.value.present_match, null)
regex_match = try(query.value.regex_match, null)
}
}
}
}
dynamic "route_action" {
for_each = (
try(route_rules.value.route_action, null) == null
? []
: [route_rules.value.route_action]
)
content {
dynamic "cors_policy" {
for_each = (
try(route_action.value.cors_policy, null) == null
? []
: [route_action.value.cors_policy]
)
content {
allow_credentials = try(cors_policy.value.allow_credentials, null)
allow_headers = try(cors_policy.value.allow_headers, null)
allow_methods = try(cors_policy.value.allow_methods, null)
allow_origin_regexes = try(cors_policy.value.allow_origin_regexes, null)
allow_origins = try(cors_policy.value.allow_origins, null)
disabled = try(cors_policy.value.disabled, null)
expose_headers = try(cors_policy.value.expose_headers, null)
max_age = try(cors_policy.value.max_age, null)
}
}
dynamic "fault_injection_policy" {
for_each = (
try(route_action.value.fault_injection_policy, null) == null
? []
: [route_action.value.fault_injection_policy]
)
iterator = policy
content {
dynamic "abort" {
for_each = (
try(policy.value.abort, null) == null
? []
: [policy.value.abort]
)
content {
http_status = try(abort.value.http_status, null) # Must be between 200 and 599 inclusive
percentage = try(abort.value.percentage, null) # Must be between 0.0 and 100.0 inclusive
}
}
dynamic "delay" {
for_each = (
try(policy.value.delay, null) == null
? []
: [policy.value.delay]
)
content {
percentage = try(delay.value.percentage, null) # Must be between 0.0 and 100.0 inclusive
dynamic "fixed_delay" {
for_each = (
try(delay.value.fixed_delay, null) == null
? []
: [delay.value.fixed_delay]
)
content {
nanos = try(fixed_delay.value.nanos, null) # Must be from 0 to 999,999,999 inclusive
seconds = try(fixed_delay.value.seconds, null) # Must be from 0 to 315,576,000,000 inclusive
}
}
}
}
}
}
dynamic "request_mirror_policy" {
for_each = (
try(route_action.value.request_mirror_policy, null) == null
? []
: [route_action.value.request_mirror_policy]
)
iterator = policy
content {
backend_service = try(
google_compute_backend_bucket.bucket[policy.value.backend_service].id,
google_compute_backend_service.group[policy.value.backend_service].id,
policy.value.backend_service,
null
)
}
}
dynamic "retry_policy" {
for_each = (
try(route_action.value.retry_policy, null) == null
? []
: [route_action.value.retry_policy]
)
iterator = policy
content {
num_retries = try(policy.num_retries, null) # Must be > 0
# Valid values at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_url_map#retry_conditions
retry_conditions = try(policy.retry_conditions, null)
dynamic "per_try_timeout" {
for_each = (
try(policy.value.per_try_timeout, null) == null
? []
: [policy.value.per_try_timeout]
)
iterator = timeout
content {
nanos = try(timeout.value.nanos, null) # Must be from 0 to 999,999,999 inclusive
seconds = try(timeout.value.seconds, null) # Must be from 0 to 315,576,000,000 inclusive
}
}
}
}
dynamic "timeout" {
for_each = (
try(route_action.value.timeout, null) == null
? []
: [route_action.value.timeout]
)
content {
nanos = try(timeout.value.nanos, null) # Must be from 0 to 999,999,999 inclusive
seconds = try(timeout.value.seconds, null) # Must be from 0 to 315,576,000,000 inclusive
}
}
dynamic "url_rewrite" {
for_each = (
try(route_action.value.url_rewrite, null) == null
? []
: [route_action.value.url_rewrite]
)
content {
host_rewrite = try(url_rewrite.value.host_rewrite, null) # Must be between 1 and 255 characters
path_prefix_rewrite = try(url_rewrite.value.path_prefix_rewrite, null) # Must be between 1 and 1024 characters
}
}
dynamic "weighted_backend_services" {
for_each = (
try(route_action.value.weighted_backend_services, null) == null
? []
: [route_action.value.url_rewrite]
)
iterator = weighted
content {
weight = try(weighted.value.weigth, null)
backend_service = try(
google_compute_backend_bucket.bucket[weighted.value.backend_service].id,
google_compute_backend_service.group[weighted.value.backend_service].id,
weighted.value.backend_service,
null
)
dynamic "header_action" {
for_each = (
try(path_matcher.value.header_action, null) == null
? [] :
[path_matcher.value.header_action]
)
content {
request_headers_to_remove = try(header_action.value.request_headers_to_remove, null)
response_headers_to_remove = try(header_action.value.response_headers_to_remove, null)
dynamic "request_headers_to_add" {
for_each = (
try(header_action.value.request_headers_to_add, null) == null
? []
: [header_action.value.request_headers_to_add]
)
content {
header_name = try(request_headers_to_add.value.header_name, null)
header_value = try(request_headers_to_add.value.header_value, null)
replace = try(request_headers_to_add.value.replace, null)
}
}
dynamic "response_headers_to_add" {
for_each = (
try(header_action.response_headers_to_add, null) == null
? []
: [header_action.response_headers_to_add]
)
content {
header_name = try(response_headers_to_add.value.header_name, null)
header_value = try(response_headers_to_add.value.header_value, null)
replace = try(response_headers_to_add.value.replace, null)
}
}
}
}
}
}
}
}
dynamic "url_redirect" {
for_each = (
try(route_rules.value.url_redirect, null) == null
? []
: route_rules.value.url_redirect
)
content {
host_redirect = try(url_redirect.value.host_redirect, null) # Must be between 1 and 255 characters
https_redirect = try(url_redirect.value.https_redirect, null)
path_redirect = try(url_redirect.value.path_redirect, null)
prefix_redirect = try(url_redirect.value.prefix_redirect, null) # Must be between 1 and 1024 characters
# Valid valus at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_url_map#redirect_response_code
redirect_response_code = try(url_redirect.value.redirect_response_code, null)
strip_query = try(url_redirect.value.strip_query, null)
}
}
}
}
dynamic "default_url_redirect" {
for_each = (
try(path_matcher.value.default_url_redirect, null) == null
? []
: path_matcher.value.default_url_redirect
)
content {
host_redirect = try(default_url_redirect.value.host_redirect, null) # Must be between 1 and 255 characters
https_redirect = try(default_url_redirect.value.https_redirect, null)
path_redirect = try(default_url_redirect.value.path_redirect, null) # Must be between 1 and 1024 characters
prefix_redirect = try(default_url_redirect.value.prefix_redirect, null) # Must be between 1 and 1024 characters
# Valid values at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_url_map#redirect_response_code
redirect_response_code = try(default_url_redirect.value.redirect_response_code, null)
strip_query = try(default_url_redirect.value.strip_query, null)
}
}
}
}
# Up to 100 tests per url_map
dynamic "test" {
for_each = (
try(var.url_map_config.tests, null) == null
? []
: var.url_map_config.tests
)
content {
description = try(test.value.description, null)
host = try(test.value.host, null)
path = try(test.value.path, null)
service = try(
google_compute_backend_bucket.bucket[test.value.service].id,
google_compute_backend_service.group[test.value.service].id,
test.value.service,
null
)
}
}
dynamic "default_url_redirect" {
for_each = (
try(var.url_map_config.default_url_redirect, null) == null
? []
: [var.url_map_config.default_url_redirect]
)
content {
host_redirect = try(default_url_redirect.value.host_redirect, null) # Must be between 1 and 255 characters
https_redirect = try(default_url_redirect.value.https_redirect, null)
path_redirect = try(default_url_redirect.value.path_redirect, null) # Must be between 1 and 1024 characters
prefix_redirect = try(default_url_redirect.value.prefix_redirect, null) # Must be between 1 and 1024 characters
# Valid values at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_url_map#redirect_response_code
redirect_response_code = try(default_url_redirect.value.redirect_response_code, null)
strip_query = try(default_url_redirect.value.strip_query, null)
}
}
}

View File

@ -0,0 +1,62 @@
/**
* 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 SSL certificates.
locals {
# If the HTTPS target proxy has no SSL certs
# set, create also a default managed SSL cert
ssl_certificates_config = merge(
coalesce(var.ssl_certificates_config, {}),
try(length(var.target_proxy_https_config.ssl_certificates), 0) == 0
? { default = var.ssl_certificates_config_defaults }
: {}
)
ssl_certs_managed = (
var.https
? {
for k, v in coalesce(local.ssl_certificates_config, {}) :
k => v if v.unmanaged_config == null
}
: {}
)
ssl_certs_unmanaged = (
var.https
? {
for k, v in coalesce(local.ssl_certificates_config, {}) :
k => v if v.unmanaged_config != null
}
: {}
)
}
resource "google_compute_managed_ssl_certificate" "managed" {
for_each = local.ssl_certs_managed
project = var.project_id
name = "${var.name}-${each.key}"
managed {
domains = try(each.value.domains, null)
}
}
resource "google_compute_ssl_certificate" "unmanaged" {
for_each = local.ssl_certs_unmanaged
project = var.project_id
name = "${var.name}-${each.key}"
certificate = try(each.value.unmanaged_config.tls_self_signed_cert, null)
private_key = try(each.value.unmanaged_config.tls_private_key, null)
}

View File

@ -0,0 +1,76 @@
/**
* 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 HTTP and HTTPS target proxies.
locals {
# If no SSL certificates are defined, use the default one.
# Otherwise, look in the ssl_certificates_config map.
# Otherwise, use the SSL certificate id as is (already existing).
ssl_certificates = (
try(var.target_proxy_https_config.ssl_certificates, null) == null
|| length(coalesce(try(var.target_proxy_https_config.ssl_certificates, null), [])) == 0
? try(
[google_compute_managed_ssl_certificate.managed["default"].id],
[google_compute_ssl_certificate.unmanaged["default"].id],
null
)
: [
for cert in try(var.target_proxy_https_config.ssl_certificates, []) :
try(
google_compute_managed_ssl_certificate.managed[cert].id,
google_compute_ssl_certificate.unmanaged[cert].id,
cert
)
]
)
}
resource "google_compute_target_http_proxy" "http" {
count = var.https ? 0 : (var.region == null ? 1 : 0)
name = var.name
project = var.project_id
description = "Terraform managed."
url_map = google_compute_url_map.url_map.0.id
}
resource "google_compute_target_https_proxy" "https" {
count = var.https ? (var.region == null ? 1 : 0) : 0
name = var.name
project = var.project_id
description = "Terraform managed."
url_map = google_compute_url_map.url_map.0.id
ssl_certificates = local.ssl_certificates
}
resource "google_compute_region_target_http_proxy" "http" {
count = var.https ? 0 : (var.region != null ? 1 : 0)
name = var.name
project = var.project_id
region = var.region
description = "Terraform managed."
url_map = google_compute_region_url_map.url_map.0.id
}
resource "google_compute_region_target_https_proxy" "https" {
count = var.https ? (var.region != null ? 1 : 0) : 0
name = var.name
project = var.project_id
region = var.region
description = "Terraform managed."
url_map = google_compute_region_url_map.url_map.0.id
ssl_certificates = local.ssl_certificates
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,257 @@
/**
* 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 "backend_services_config" {
description = "The backends services configuration."
type = map(object({
enable_cdn = bool
cdn_config = object({
cache_mode = string
client_ttl = number
default_ttl = number
max_ttl = number
negative_caching = bool
negative_caching_policy = map(number)
serve_while_stale = bool
signed_url_cache_max_age_sec = string
})
bucket_config = object({
bucket_name = string
options = object({
custom_response_headers = list(string)
})
})
group_config = object({
backends = list(object({
group = string # IG or NEG FQDN address
options = object({
balancing_mode = string # Can be UTILIZATION, RATE, CONNECTION
capacity_scaler = number # Valid range is [0.0,1.0]
max_connections = number
max_connections_per_instance = number
max_connections_per_endpoint = number
max_rate = number
max_rate_per_instance = number
max_rate_per_endpoint = number
max_utilization = number
})
}))
# Optional health check ids for backend service groups.
# Will lookup for ids in health_chacks_config first,
# then will use the id as is. If no ids are defined
# at all (null, []) health_checks_config_defaults is used
health_checks = list(string)
log_config = object({
enable = bool
sample_rate = number # must be in [0, 1]
})
options = object({
affinity_cookie_ttl_sec = number
custom_request_headers = list(string)
custom_response_headers = list(string)
connection_draining_timeout_sec = number
load_balancing_scheme = string # only EXTERNAL (default) makes sense here
locality_lb_policy = string
port_name = string
protocol = string
security_policy = string
session_affinity = string
timeout_sec = number
circuits_breakers = object({
max_requests_per_connection = number # Set to 1 to disable keep-alive
max_connections = number # Defaults to 1024
max_pending_requests = number # Defaults to 1024
max_requests = number # Defaults to 1024
max_retries = number # Defaults to 3
})
consistent_hash = object({
http_header_name = string
minimum_ring_size = string
http_cookie = object({
name = string
path = string
ttl = object({
seconds = number
nanos = number
})
})
})
iap = object({
oauth2_client_id = string
oauth2_client_secret = string
oauth2_client_secret_sha256 = string
})
})
})
}))
default = {}
}
variable "forwarding_rule_config" {
description = "Regional forwarding rule configurations."
type = object({
ip_protocol = string
ip_version = string
load_balancing_scheme = string
port_range = string
network_tier = string
network = string
})
default = {
load_balancing_scheme = "EXTERNAL_MANAGED"
ip_protocol = "TCP"
ip_version = "IPV4"
network_tier = "STANDARD"
network = "default"
# If not specified, 80 for https = false, 443 otherwise
port_range = null
}
}
variable "global_forwarding_rule_config" {
description = "Global forwarding rule configurations."
type = object({
ip_protocol = string
ip_version = string
load_balancing_scheme = string
port_range = string
})
default = {
load_balancing_scheme = "EXTERNAL"
ip_protocol = "TCP"
ip_version = "IPV4"
# If not specified, 80 for https = false, 443 otherwise
port_range = null
}
}
variable "health_checks_config" {
description = "Custom health checks configuration."
type = map(object({
type = string # http https tcp ssl http2
check = map(any) # actual health check block attributes
options = map(number) # interval, thresholds, timeout
logging = bool
}))
default = {}
}
variable "health_checks_config_defaults" {
description = "Auto-created health check default configuration."
type = object({
type = string # http https tcp ssl http2
check = map(any) # actual health check block attributes
options = map(number) # interval, thresholds, timeout
logging = bool
})
default = {
type = "http"
logging = false
options = {}
check = {
port_specification = "USE_SERVING_PORT"
}
}
}
variable "https" {
description = "Whether to enable HTTPS."
type = bool
default = false
}
variable "name" {
description = "Load balancer name."
type = string
}
variable "project_id" {
description = "Project id."
type = string
}
variable "region" {
description = "Create a regional load balancer in this region."
type = string
default = null
}
variable "reserve_ip_address" {
description = "Whether to reserve a static global IP address."
type = bool
default = false
}
variable "ssl_certificates_config" {
description = "The SSL certificate configuration."
type = map(object({
domains = list(string)
# If unmanaged_config is null, the certificate will be managed
unmanaged_config = object({
tls_private_key = string
tls_self_signed_cert = string
})
}))
default = {}
}
variable "ssl_certificates_config_defaults" {
description = "The SSL certificate default configuration."
type = object({
domains = list(string)
# If unmanaged_config is null, the certificate will be managed
unmanaged_config = object({
tls_private_key = string
tls_self_signed_cert = string
})
})
default = {
domains = ["example.com"],
unmanaged_config = null
}
}
variable "target_proxy_https_config" {
description = "The HTTPS target proxy configuration."
type = object({
ssl_certificates = list(string)
})
default = null
}
variable "url_map_config" {
description = "The url-map configuration."
type = object({
default_service = string
default_route_action = any
default_url_redirect = map(any)
header_action = any
host_rules = list(any)
path_matchers = list(any)
tests = list(map(string))
})
default = null
}

View File

@ -0,0 +1,29 @@
# 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
#
# 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.3.1"
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.40.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.40.0" # tftest
}
}
}