From 46d5503799479519ac06d1cc0ca8b3bc87f7d4bc Mon Sep 17 00:00:00 2001 From: Imran Nayer Date: Mon, 6 Nov 2023 18:38:26 +0000 Subject: [PATCH 1/7] fix cert map --- README.md | 16 +- autogen/main.tf.tmpl | 10 +- autogen/outputs.tf.tmpl | 5 + autogen/variables.tf.tmpl | 52 ++--- examples/certificate-map/README.md | 30 +++ examples/certificate-map/certificate-map.tf | 45 ++++ examples/certificate-map/gceme.sh.tpl | 127 ++++++++++++ examples/certificate-map/gcp-logo.svg | 142 +++++++++++++ examples/certificate-map/main.tf | 188 +++++++++++++++++ examples/certificate-map/mig.tf | 57 ++++++ examples/certificate-map/outputs.tf | 31 +++ examples/certificate-map/variables.tf | 27 +++ examples/certificate-map/versions.tf | 36 ++++ .../user-managed-google-managed-ssl/README.md | 113 +++++++++++ .../gceme.sh.tpl | 1 + .../gcp-logo.svg | 142 +++++++++++++ .../user-managed-google-managed-ssl/main.tf | 192 ++++++++++++++++++ .../user-managed-google-managed-ssl/mig.tf | 57 ++++++ .../outputs.tf | 31 +++ .../user-managed-google-managed-ssl/tls.tf | 84 ++++++++ .../variables.tf | 27 +++ .../versions.tf | 36 ++++ main.tf | 10 +- modules/dynamic_backends/README.md | 16 +- modules/dynamic_backends/main.tf | 10 +- modules/dynamic_backends/variables.tf | 52 ++--- modules/serverless_negs/README.md | 16 +- modules/serverless_negs/main.tf | 10 +- modules/serverless_negs/variables.tf | 52 ++--- test/setup/main.tf | 2 + variables.tf | 52 ++--- 31 files changed, 1521 insertions(+), 148 deletions(-) create mode 100644 examples/certificate-map/README.md create mode 100644 examples/certificate-map/certificate-map.tf create mode 100644 examples/certificate-map/gceme.sh.tpl create mode 100644 examples/certificate-map/gcp-logo.svg create mode 100644 examples/certificate-map/main.tf create mode 100644 examples/certificate-map/mig.tf create mode 100644 examples/certificate-map/outputs.tf create mode 100644 examples/certificate-map/variables.tf create mode 100644 examples/certificate-map/versions.tf create mode 100644 examples/user-managed-google-managed-ssl/README.md create mode 120000 examples/user-managed-google-managed-ssl/gceme.sh.tpl create mode 100644 examples/user-managed-google-managed-ssl/gcp-logo.svg create mode 100644 examples/user-managed-google-managed-ssl/main.tf create mode 100644 examples/user-managed-google-managed-ssl/mig.tf create mode 100644 examples/user-managed-google-managed-ssl/outputs.tf create mode 100644 examples/user-managed-google-managed-ssl/tls.tf create mode 100644 examples/user-managed-google-managed-ssl/variables.tf create mode 100644 examples/user-managed-google-managed-ssl/versions.tf diff --git a/README.md b/README.md index 677bc296..90df9227 100644 --- a/README.md +++ b/README.md @@ -120,11 +120,12 @@ module "gce-lb-http" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | address | Existing IPv4 address to use (the actual IP address value) | `string` | `null` | no | -| backends | Map backend indices to list of backend maps. |
map(object({
port = optional(number)
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

timeout_sec = optional(number)
connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)

health_check = object({
host = optional(string)
request_path = optional(string)
request = optional(string)
response = optional(string)
port = optional(number)
port_name = optional(string)
proxy_header = optional(string)
port_specification = optional(string)
protocol = optional(string)
check_interval_sec = optional(number)
timeout_sec = optional(number)
healthy_threshold = optional(number)
unhealthy_threshold = optional(number)
logging = optional(bool)
})

log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

balancing_mode = optional(string)
capacity_scaler = optional(number)
description = optional(string)
max_connections = optional(number)
max_connections_per_instance = optional(number)
max_connections_per_endpoint = optional(number)
max_rate = optional(number)
max_rate_per_instance = optional(number)
max_rate_per_endpoint = optional(number)
max_utilization = optional(number)
}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
outlier_detection = optional(object({
base_ejection_time = optional(object({
seconds = number
nanos = optional(number)
}))
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)
interval = optional(object({
seconds = number
nanos = 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)
}))
}))
| n/a | yes | -| certificate | Content of the SSL certificate. Required if `ssl` is `true` and `ssl_certificates` is empty. | `string` | `null` | no | -| certificate\_map | Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy | `string` | `null` | no | +| backends | Map backend indices to list of backend maps. |
map(object({
port = optional(number)
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

timeout_sec = optional(number)
connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)

health_check = object({
host = optional(string)
request_path = optional(string)
request = optional(string)
response = optional(string)
port = optional(number)
port_name = optional(string)
proxy_header = optional(string)
port_specification = optional(string)
protocol = optional(string)
check_interval_sec = optional(number)
timeout_sec = optional(number)
healthy_threshold = optional(number)
unhealthy_threshold = optional(number)
logging = optional(bool)
})

log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

balancing_mode = optional(string)
capacity_scaler = optional(number)
description = optional(string)
max_connections = optional(number)
max_connections_per_instance = optional(number)
max_connections_per_endpoint = optional(number)
max_rate = optional(number)
max_rate_per_instance = optional(number)
max_rate_per_endpoint = optional(number)
max_utilization = optional(number)
}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
}))
| n/a | yes | +| certificate | Content of the SSL certificate. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true` | `string` | `null` | no | +| certificate\_map | Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy. Requires `ssl` to be set to `true` | `string` | `null` | no | | create\_address | Create a new global IPv4 address | `bool` | `true` | no | | create\_ipv6\_address | Allocate a new IPv6 address. Conflicts with "ipv6\_address" - if both specified, "create\_ipv6\_address" takes precedence. | `bool` | `false` | no | +| create\_ssl\_certificate | If `true`, Create certificate using `private_key/certificate` | `bool` | `false` | no | | create\_url\_map | Set to `false` if url\_map variable is provided. | `bool` | `true` | no | | edge\_security\_policy | The resource URL for the edge security policy to associate with the backend service | `string` | `null` | no | | enable\_ipv6 | Enable IPv6 address on the CDN load-balancer | `bool` | `false` | no | @@ -135,21 +136,20 @@ module "gce-lb-http" { | ipv6\_address | An existing IPv6 address to use (the actual IP address value) | `string` | `null` | no | | labels | The labels to attach to resources created by this module | `map(string)` | `{}` | no | | load\_balancing\_scheme | Load balancing scheme type (EXTERNAL for classic external load balancer, EXTERNAL\_MANAGED for Envoy-based load balancer, and INTERNAL\_SELF\_MANAGED for traffic director) | `string` | `"EXTERNAL"` | no | -| managed\_ssl\_certificate\_domains | Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true` and `use_ssl_certificates` set to `false`. | `list(string)` | `[]` | no | +| managed\_ssl\_certificate\_domains | Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true` | `list(string)` | `[]` | no | | name | Name for the forwarding rule and prefix for supporting resources | `string` | n/a | yes | | network | Network for INTERNAL\_SELF\_MANAGED load balancing scheme | `string` | `"default"` | no | -| private\_key | Content of the private SSL key. Required if `ssl` is `true` and `ssl_certificates` is empty. | `string` | `null` | no | +| private\_key | Content of the private SSL key. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true` | `string` | `null` | no | | project | The project to deploy to, if not set the default provider project is used. | `string` | n/a | yes | | quic | Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only. | `bool` | `null` | no | | random\_certificate\_suffix | Bool to enable/disable random certificate name generation. Set and keep this to true if you need to change the SSL cert. | `bool` | `false` | no | | security\_policy | The resource URL for the security policy to associate with the backend service | `string` | `null` | no | -| ssl | Set to `true` to enable SSL support, requires variable `ssl_certificates` - a list of self\_link certs | `bool` | `false` | no | -| ssl\_certificates | SSL cert self\_link list. Required if `ssl` is `true` and no `private_key` and `certificate` is provided. | `list(string)` | `[]` | no | +| ssl | Set to `true` to enable SSL support. If `true` then at least one of these are required: 1) `ssl_certificates` OR 2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR 3) `managed_ssl_certificate_domains`, OR 4) `certificate_map` | `bool` | `false` | no | +| ssl\_certificates | SSL cert self\_link list. Requires `ssl` to be set to `true` | `list(string)` | `[]` | no | | ssl\_policy | Selfink to SSL Policy | `string` | `null` | no | | target\_service\_accounts | List of target service accounts for health check firewall rule. Exactly one of target\_tags or target\_service\_accounts should be specified. | `list(string)` | `[]` | no | | target\_tags | List of target tags for health check firewall rule. Exactly one of target\_tags or target\_service\_accounts should be specified. | `list(string)` | `[]` | no | | url\_map | The url\_map resource to use. Default is to send all traffic to first backend. | `string` | `null` | no | -| use\_ssl\_certificates | If true, use the certificates provided by `ssl_certificates`, otherwise, create cert from `private_key` and `certificate` | `bool` | `false` | no | ## Outputs diff --git a/autogen/main.tf.tmpl b/autogen/main.tf.tmpl index 6ec826df..cd1a5740 100644 --- a/autogen/main.tf.tmpl +++ b/autogen/main.tf.tmpl @@ -47,7 +47,7 @@ resource "google_compute_global_forwarding_rule" "http" { resource "google_compute_global_forwarding_rule" "https" { provider = google-beta project = var.project - count = var.ssl || var.certificate_map != null ? 1 : 0 + count = var.ssl ? 1 : 0 name = "${var.name}-https" target = google_compute_target_https_proxy.default[0].self_link ip_address = local.address @@ -84,7 +84,7 @@ resource "google_compute_global_forwarding_rule" "http_ipv6" { resource "google_compute_global_forwarding_rule" "https_ipv6" { provider = google-beta project = var.project - count = var.enable_ipv6 && (var.ssl || var.certificate_map != null) ? 1 : 0 + count = var.enable_ipv6 && var.ssl ? 1 : 0 name = "${var.name}-ipv6-https" target = google_compute_target_https_proxy.default[0].self_link ip_address = local.ipv6_address @@ -115,7 +115,7 @@ resource "google_compute_target_http_proxy" "default" { # HTTPS proxy when ssl is true resource "google_compute_target_https_proxy" "default" { project = var.project - count = var.ssl || var.certificate_map != null ? 1 : 0 + count = var.ssl ? 1 : 0 name = "${var.name}-https-proxy" url_map = local.url_map @@ -127,7 +127,7 @@ resource "google_compute_target_https_proxy" "default" { resource "google_compute_ssl_certificate" "default" { project = var.project - count = var.ssl && length(var.managed_ssl_certificate_domains) == 0 && !var.use_ssl_certificates ? 1 : 0 + count = var.ssl && var.create_ssl_certificate ? 1 : 0 name_prefix = "${var.name}-certificate-" private_key = var.private_key certificate = var.certificate @@ -150,7 +150,7 @@ resource "random_id" "certificate" { resource "google_compute_managed_ssl_certificate" "default" { provider = google-beta project = var.project - count = var.ssl && length(var.managed_ssl_certificate_domains) > 0 && !var.use_ssl_certificates ? 1 : 0 + count = var.ssl && length(var.managed_ssl_certificate_domains) > 0 ? 1 : 0 name = var.random_certificate_suffix == true ? random_id.certificate[0].hex : "${var.name}-cert" lifecycle { diff --git a/autogen/outputs.tf.tmpl b/autogen/outputs.tf.tmpl index c17a0ef4..7e7a8afa 100644 --- a/autogen/outputs.tf.tmpl +++ b/autogen/outputs.tf.tmpl @@ -49,3 +49,8 @@ output "url_map" { description = "The default URL map used by this module." value = google_compute_url_map.default[*].self_link } + +output "ssl_certificate" { + description = "The managed SSL certificates" + value = google_compute_ssl_certificate.default.self_link +} \ No newline at end of file diff --git a/autogen/variables.tf.tmpl b/autogen/variables.tf.tmpl index c56ba9d9..fdc50d9c 100644 --- a/autogen/variables.tf.tmpl +++ b/autogen/variables.tf.tmpl @@ -215,51 +215,57 @@ variable "http_forward" { } variable "ssl" { - description = "Set to `true` to enable SSL support, requires variable `ssl_certificates` - a list of self_link certs" + description = "Set to `true` to enable SSL support. If `true` then at least one of these are required: 1) `ssl_certificates` OR 2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR 3) `managed_ssl_certificate_domains`, OR 4) `certificate_map`" type = bool default = false } -variable "ssl_policy" { - type = string - description = "Selfink to SSL Policy" - default = null +variable "create_ssl_certificate" { + description = "If `true`, Create certificate using `private_key/certificate`" + type = bool + default = false } -variable "quic" { - type = bool - description = "Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only." - default = null +variable "ssl_certificates" { + description = "SSL cert self_link list. Requires `ssl` to be set to `true`" + type = list(string) + default = [] } variable "private_key" { - description = "Content of the private SSL key. Required if `ssl` is `true` and `ssl_certificates` is empty." + description = "Content of the private SSL key. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true`" type = string default = null } variable "certificate" { - description = "Content of the SSL certificate. Required if `ssl` is `true` and `ssl_certificates` is empty." + description = "Content of the SSL certificate. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true`" type = string default = null } variable "managed_ssl_certificate_domains" { - description = "Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true` and `use_ssl_certificates` set to `false`." + description = "Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true`" type = list(string) default = [] } -variable "use_ssl_certificates" { - description = "If true, use the certificates provided by `ssl_certificates`, otherwise, create cert from `private_key` and `certificate`" - type = bool - default = false +variable "certificate_map" { + description = "Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy. Requires `ssl` to be set to `true`" + type = string + default = null } -variable "ssl_certificates" { - description = "SSL cert self_link list. Required if `ssl` is `true` and no `private_key` and `certificate` is provided." - type = list(string) - default = [] +variable "ssl_policy" { + type = string + description = "Selfink to SSL Policy" + default = null +} + +variable "quic" { + type = bool + description = "Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only." + default = null } variable "edge_security_policy" { @@ -298,12 +304,6 @@ variable "load_balancing_scheme" { default = "EXTERNAL" } -variable "certificate_map" { - description = "Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy" - type = string - default = null -} - variable "network" { description = "Network for INTERNAL_SELF_MANAGED load balancing scheme" type = string diff --git a/examples/certificate-map/README.md b/examples/certificate-map/README.md new file mode 100644 index 00000000..ffb2653f --- /dev/null +++ b/examples/certificate-map/README.md @@ -0,0 +1,30 @@ +# Certificate Map Example + +This example shows how to use certificate maps with the HTTPS Load Balancer module. + +## Run Terraform + +``` +terraform init +terraform apply +``` + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| group1\_region | n/a | `string` | `"us-west1"` | no | +| network\_name | n/a | `string` | `"tf-lb-https-cert-map"` | no | +| project\_id | n/a | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| asset-url | n/a | +| group1\_region | n/a | +| load-balancer-ip | n/a | +| project\_id | n/a | + + diff --git a/examples/certificate-map/certificate-map.tf b/examples/certificate-map/certificate-map.tf new file mode 100644 index 00000000..78fd5218 --- /dev/null +++ b/examples/certificate-map/certificate-map.tf @@ -0,0 +1,45 @@ +/** + * 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. + */ + +locals { + cert_map_name = "projects/${var.project_id}/locations/global/certificateMaps/certmgr-map" +} + +resource "google_certificate_manager_certificate" "all" { + name = "certmgr-cert" + description = "The default cert for all domains" + project = var.project_id + managed { + domains = [ + "test.example.com", + ] + } +} + +resource "google_certificate_manager_certificate_map" "certificate_map" { + name = "certmgr-map" + description = "My certificate map" + project = var.project_id +} + +resource "google_certificate_manager_certificate_map_entry" "map_entry_web1" { + project = var.project_id + name = "certmgr-map-entry-web1" + description = "My test certificate map entry" + map = google_certificate_manager_certificate_map.certificate_map.name + certificates = [google_certificate_manager_certificate.all.id] + hostname = "test.example.com" +} diff --git a/examples/certificate-map/gceme.sh.tpl b/examples/certificate-map/gceme.sh.tpl new file mode 100644 index 00000000..97b22459 --- /dev/null +++ b/examples/certificate-map/gceme.sh.tpl @@ -0,0 +1,127 @@ +#!/bin/bash -xe + +# introducing sleep so network interfaces and routes can get ready before fetching software +sleep 10 + +RPM_INSTALL_ARGS="install -y httpd php php-common" + +if [ -f "/etc/redhat-release" ]; then + yum update -y || dnf update -y + yum $RPM_INSTALL_ARGS || dnf $RPM_INSTALL_ARGS +else + apt-get update + apt-get install -y apache2 libapache2-mod-php +fi + +cat > /var/www/html/index.php <<'EOF' + array( + "method" => "GET", + "header" => "Metadata-Flavor: Google" + ) + ); + $context = stream_context_create($opts); + $content = file_get_contents("http://metadata/computeMetadata/v1/$value", false, $context); + return $content; +} +if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == "http") { + $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + header('HTTP/1.1 301 Moved Permanently'); + header('Location: ' . $redirect); + exit(); +} +?> + + + + + + + + + +Frontend Web Server + + +
+
+
 
+
+ + + +
+
+
Backend that serviced this request
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name
ID
Hostname
Zone
Machine Type
Project
Internal IP
External IP
+
+
+ +
+
+
Proxy that handled this request
+
+
+ + + + + + + +
Address
+
+ +
+
+
 
+
+
+ +EOF + +mv /var/www/html/index.html /var/www/html/index.html.old || echo "Old index doesn't exist" + +[[ -n "${PROXY_PATH}" ]] && mkdir -p /var/www/html/${PROXY_PATH} && cp /var/www/html/index.php /var/www/html/${PROXY_PATH}/index.php + +chkconfig httpd on || systemctl enable httpd || systemctl enable apache2 +service httpd restart || systemctl restart httpd || systemctl restart apache2 diff --git a/examples/certificate-map/gcp-logo.svg b/examples/certificate-map/gcp-logo.svg new file mode 100644 index 00000000..45c38c4e --- /dev/null +++ b/examples/certificate-map/gcp-logo.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/certificate-map/main.tf b/examples/certificate-map/main.tf new file mode 100644 index 00000000..f62eefcc --- /dev/null +++ b/examples/certificate-map/main.tf @@ -0,0 +1,188 @@ +/** + * 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. + */ + +provider "google" { + project = var.project_id +} + +provider "google-beta" { + project = var.project_id +} + +resource "google_compute_network" "default" { + name = var.network_name + auto_create_subnetworks = "false" +} + +resource "google_compute_subnetwork" "group1" { + name = var.network_name + ip_cidr_range = "10.125.0.0/20" + network = google_compute_network.default.self_link + region = var.group1_region + private_ip_google_access = true +} + +# Router and Cloud NAT are required for installing packages from repos (apache, php etc) +resource "google_compute_router" "group1" { + name = "${var.network_name}-gw-group1" + network = google_compute_network.default.self_link + region = var.group1_region +} + +module "cloud-nat-group1" { + source = "terraform-google-modules/cloud-nat/google" + version = "~> 2.2" + router = google_compute_router.group1.name + project_id = var.project_id + region = var.group1_region + name = "${var.network_name}-cloud-nat-group1" +} + +resource "random_id" "assets-bucket" { + prefix = "terraform-static-content-" + byte_length = 2 +} + +locals { + health_check = { + request_path = "/" + port = 80 + } +} + +module "gce-lb-https" { + source = "../../" + name = var.network_name + project = var.project_id + firewall_networks = [google_compute_network.default.self_link] + url_map = google_compute_url_map.https-multi-cert.self_link + create_url_map = false + ssl = true + certificate_map = local.cert_map_name + + backends = { + default = { + protocol = "HTTP" + port = 80 + port_name = "http" + timeout_sec = 10 + enable_cdn = false + + health_check = local.health_check + log_config = { + enable = true + sample_rate = 1.0 + } + groups = [ + { + group = module.mig1.instance_group + }, + ] + + iap_config = { + enable = false + } + } + + mig1 = { + protocol = "HTTP" + port = 80 + port_name = "http" + timeout_sec = 10 + enable_cdn = false + + health_check = local.health_check + log_config = { + enable = true + sample_rate = 1.0 + } + groups = [ + { + group = module.mig1.instance_group + }, + ] + + iap_config = { + enable = false + } + } + } + + depends_on = [google_certificate_manager_certificate_map.certificate_map] +} + +resource "google_compute_url_map" "https-multi-cert" { + // note that this is the name of the load balancer + name = var.network_name + default_service = module.gce-lb-https.backend_services["default"].self_link + + host_rule { + hosts = ["*"] + path_matcher = "allpaths" + } + + path_matcher { + name = "allpaths" + default_service = module.gce-lb-https.backend_services["default"].self_link + + path_rule { + paths = [ + "/group1", + "/group1/*" + ] + service = module.gce-lb-https.backend_services["mig1"].self_link + } + + path_rule { + paths = [ + "/assets", + "/assets/*" + ] + service = google_compute_backend_bucket.assets.self_link + } + } +} + +resource "google_compute_backend_bucket" "assets" { + name = random_id.assets-bucket.hex + description = "Contains static resources for example app" + bucket_name = google_storage_bucket.assets.name + enable_cdn = true +} + +resource "google_storage_bucket" "assets" { + name = random_id.assets-bucket.hex + location = "US" + + // delete bucket and contents on destroy. + force_destroy = true +} + +// The image object in Cloud Storage. +// Note that the path in the bucket matches the paths in the url map path rule above. +resource "google_storage_bucket_object" "image" { + name = "assets/gcp-logo.svg" + content = file("gcp-logo.svg") + content_type = "image/svg+xml" + bucket = google_storage_bucket.assets.name +} + +// Make object public readable. +resource "google_storage_object_acl" "image-acl" { + bucket = google_storage_bucket.assets.name + object = google_storage_bucket_object.image.name + predefined_acl = "publicRead" +} diff --git a/examples/certificate-map/mig.tf b/examples/certificate-map/mig.tf new file mode 100644 index 00000000..7e6a6ba0 --- /dev/null +++ b/examples/certificate-map/mig.tf @@ -0,0 +1,57 @@ +/** + * 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. + */ + +data "template_file" "group1-startup-script" { + template = file(format("%s/gceme.sh.tpl", path.module)) + + vars = { + PROXY_PATH = "/group1" + } +} + +module "mig1_template" { + source = "terraform-google-modules/vm/google//modules/instance_template" + version = "~> 7.9" + network = google_compute_network.default.self_link + subnetwork = google_compute_subnetwork.group1.self_link + service_account = { + email = "" + scopes = ["cloud-platform"] + } + name_prefix = "${var.network_name}-group1" + startup_script = data.template_file.group1-startup-script.rendered + source_image_family = "ubuntu-2004-lts" + source_image_project = "ubuntu-os-cloud" + tags = [ + "${var.network_name}-group1", + module.cloud-nat-group1.router_name + ] +} + +module "mig1" { + source = "terraform-google-modules/vm/google//modules/mig" + version = "7.9.0" + instance_template = module.mig1_template.self_link + region = var.group1_region + hostname = "${var.network_name}-group1" + target_size = 2 + named_ports = [{ + name = "http", + port = 80 + }] + network = google_compute_network.default.self_link + subnetwork = google_compute_subnetwork.group1.self_link +} diff --git a/examples/certificate-map/outputs.tf b/examples/certificate-map/outputs.tf new file mode 100644 index 00000000..5ad198e7 --- /dev/null +++ b/examples/certificate-map/outputs.tf @@ -0,0 +1,31 @@ +/** + * 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 "group1_region" { + value = var.group1_region +} + +output "project_id" { + value = var.project_id +} + +output "load-balancer-ip" { + value = module.gce-lb-https.external_ip +} + +output "asset-url" { + value = "https://${module.gce-lb-https.external_ip}/assets/gcp-logo.svg" +} diff --git a/examples/certificate-map/variables.tf b/examples/certificate-map/variables.tf new file mode 100644 index 00000000..a4223722 --- /dev/null +++ b/examples/certificate-map/variables.tf @@ -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 + * + * 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 "group1_region" { + default = "us-west1" +} + +variable "network_name" { + default = "tf-lb-https-cert-map" +} + +variable "project_id" { + type = string +} diff --git a/examples/certificate-map/versions.tf b/examples/certificate-map/versions.tf new file mode 100644 index 00000000..ab774560 --- /dev/null +++ b/examples/certificate-map/versions.tf @@ -0,0 +1,36 @@ +/** + * 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. + */ + +terraform { + required_version = ">= 0.13" + required_providers { + google = { + source = "hashicorp/google" + } + google-beta = { + source = "hashicorp/google-beta" + } + random = { + source = "hashicorp/random" + } + template = { + source = "hashicorp/template" + } + tls = { + source = "hashicorp/tls" + } + } +} diff --git a/examples/user-managed-google-managed-ssl/README.md b/examples/user-managed-google-managed-ssl/README.md new file mode 100644 index 00000000..456eecc6 --- /dev/null +++ b/examples/user-managed-google-managed-ssl/README.md @@ -0,0 +1,113 @@ +# Multiple Certificate Example + +[![button](http://gstatic.com/cloudssh/images/open-btn.png)](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/terraform-google-lb-http&working_dir=examples/multiple-certs&page=shell&tutorial=README.md) + +This example shows how to use multiple certificates with the HTTPS Load Balancer module. + +## Change to the example directory + +``` +[[ `basename $PWD` != multiple-certs ]] && cd examples/multiple-certs +``` + +## Install Terraform + +1. Install Terraform if it is not already installed (visit [terraform.io](https://terraform.io) for other distributions): + +``` +../terraform-install.sh +``` + +## Set up the environment + +1. Set the project, replace `YOUR_PROJECT` with your project ID: + +``` +PROJECT=YOUR_PROJECT +``` + +``` +gcloud config set project ${PROJECT} +``` + +2. Configure the environment for Terraform: + +``` +[[ $CLOUD_SHELL ]] || gcloud auth application-default login +export GOOGLE_PROJECT=$(gcloud config get-value project) +``` + +## Run Terraform + +``` +terraform init +terraform apply +``` + +## Testing + +1. Wait for the load balancer to be provisioned: + +``` +./test.sh +``` + +2. Open URL of load balancer in browser: + +``` +echo http://$(terraform output load-balancer-ip)| sed 's/"//g' +``` + +> You should see the GCP logo and instance details from the group closest to your geographical region. + +3. Open URL to route mapped to us-west1 instance group: + +``` +echo http://$(terraform output load-balancer-ip)/group1/| sed 's/"//g' +``` + +> You should see the GCP logo and instance details from the group in us-west1. + +4. Open URL to route mapped to us-central1 instance group: + +``` +echo http://$(terraform output load-balancer-ip)/group2/| sed 's/"//g' +``` + +> You should see the GCP logo and instance details from the group in us-central1. + +5. Open URL to route mapped to us-east1 instance group: + +``` +echo http://$(terraform output load-balancer-ip)/group3/| sed 's/"//g' +``` + +> You should see the GCP logo and instance details from the group in us-east1. + +## Cleanup + +1. Remove all resources created by terraform: + +``` +terraform destroy +``` + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| group1\_region | n/a | `string` | `"us-west1"` | no | +| network\_name | n/a | `string` | `"tf-lb-user-goog-ssl"` | no | +| project\_id | n/a | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| asset-url | n/a | +| group1\_region | n/a | +| load-balancer-ip | n/a | +| project\_id | n/a | + + diff --git a/examples/user-managed-google-managed-ssl/gceme.sh.tpl b/examples/user-managed-google-managed-ssl/gceme.sh.tpl new file mode 120000 index 00000000..7934e83e --- /dev/null +++ b/examples/user-managed-google-managed-ssl/gceme.sh.tpl @@ -0,0 +1 @@ +../multi-backend-multi-mig-bucket-https-lb/gceme.sh.tpl \ No newline at end of file diff --git a/examples/user-managed-google-managed-ssl/gcp-logo.svg b/examples/user-managed-google-managed-ssl/gcp-logo.svg new file mode 100644 index 00000000..45c38c4e --- /dev/null +++ b/examples/user-managed-google-managed-ssl/gcp-logo.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/user-managed-google-managed-ssl/main.tf b/examples/user-managed-google-managed-ssl/main.tf new file mode 100644 index 00000000..a6b5036c --- /dev/null +++ b/examples/user-managed-google-managed-ssl/main.tf @@ -0,0 +1,192 @@ +/** + * 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. + */ + +provider "google" { + project = var.project_id +} + +provider "google-beta" { + project = var.project_id +} + +resource "google_compute_network" "default" { + name = var.network_name + auto_create_subnetworks = "false" +} + +resource "google_compute_subnetwork" "group1" { + name = var.network_name + ip_cidr_range = "10.125.0.0/20" + network = google_compute_network.default.self_link + region = var.group1_region + private_ip_google_access = true +} + +# Router and Cloud NAT are required for installing packages from repos (apache, php etc) +resource "google_compute_router" "group1" { + name = "${var.network_name}-gw-group1" + network = google_compute_network.default.self_link + region = var.group1_region +} + +module "cloud-nat-group1" { + source = "terraform-google-modules/cloud-nat/google" + version = "~> 2.2" + router = google_compute_router.group1.name + project_id = var.project_id + region = var.group1_region + name = "${var.network_name}-cloud-nat-group1" +} + +resource "random_id" "assets-bucket" { + prefix = "terraform-static-content-" + byte_length = 2 +} + +locals { + health_check = { + request_path = "/" + port = 80 + } +} + +module "gce-lb-https" { + source = "../../" + name = var.network_name + project = var.project_id + firewall_networks = [google_compute_network.default.self_link] + url_map = google_compute_url_map.https-multi-cert.self_link + create_url_map = false + ssl = true + create_ssl_certificate = true + private_key = tls_private_key.single_key.private_key_pem + certificate = tls_self_signed_cert.single_cert.cert_pem + managed_ssl_certificate_domains = ["test.example.com"] + ssl_certificates = google_compute_ssl_certificate.example.*.self_link + + backends = { + default = { + protocol = "HTTP" + port = 80 + port_name = "http" + timeout_sec = 10 + enable_cdn = false + + health_check = local.health_check + log_config = { + enable = true + sample_rate = 1.0 + } + groups = [ + { + group = module.mig1.instance_group + }, + ] + + iap_config = { + enable = false + } + } + + mig1 = { + protocol = "HTTP" + port = 80 + port_name = "http" + timeout_sec = 10 + enable_cdn = false + + health_check = local.health_check + log_config = { + enable = true + sample_rate = 1.0 + } + groups = [ + { + group = module.mig1.instance_group + }, + ] + + iap_config = { + enable = false + } + } + } + + # depends_on = [google_certificate_manager_certificate_map.certificate_map] +} + +resource "google_compute_url_map" "https-multi-cert" { + // note that this is the name of the load balancer + name = var.network_name + default_service = module.gce-lb-https.backend_services["default"].self_link + + host_rule { + hosts = ["*"] + path_matcher = "allpaths" + } + + path_matcher { + name = "allpaths" + default_service = module.gce-lb-https.backend_services["default"].self_link + + path_rule { + paths = [ + "/group1", + "/group1/*" + ] + service = module.gce-lb-https.backend_services["mig1"].self_link + } + + path_rule { + paths = [ + "/assets", + "/assets/*" + ] + service = google_compute_backend_bucket.assets.self_link + } + } +} + +resource "google_compute_backend_bucket" "assets" { + name = random_id.assets-bucket.hex + description = "Contains static resources for example app" + bucket_name = google_storage_bucket.assets.name + enable_cdn = true +} + +resource "google_storage_bucket" "assets" { + name = random_id.assets-bucket.hex + location = "US" + + // delete bucket and contents on destroy. + force_destroy = true +} + +// The image object in Cloud Storage. +// Note that the path in the bucket matches the paths in the url map path rule above. +resource "google_storage_bucket_object" "image" { + name = "assets/gcp-logo.svg" + content = file("gcp-logo.svg") + content_type = "image/svg+xml" + bucket = google_storage_bucket.assets.name +} + +// Make object public readable. +resource "google_storage_object_acl" "image-acl" { + bucket = google_storage_bucket.assets.name + object = google_storage_bucket_object.image.name + predefined_acl = "publicRead" +} diff --git a/examples/user-managed-google-managed-ssl/mig.tf b/examples/user-managed-google-managed-ssl/mig.tf new file mode 100644 index 00000000..7e6a6ba0 --- /dev/null +++ b/examples/user-managed-google-managed-ssl/mig.tf @@ -0,0 +1,57 @@ +/** + * 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. + */ + +data "template_file" "group1-startup-script" { + template = file(format("%s/gceme.sh.tpl", path.module)) + + vars = { + PROXY_PATH = "/group1" + } +} + +module "mig1_template" { + source = "terraform-google-modules/vm/google//modules/instance_template" + version = "~> 7.9" + network = google_compute_network.default.self_link + subnetwork = google_compute_subnetwork.group1.self_link + service_account = { + email = "" + scopes = ["cloud-platform"] + } + name_prefix = "${var.network_name}-group1" + startup_script = data.template_file.group1-startup-script.rendered + source_image_family = "ubuntu-2004-lts" + source_image_project = "ubuntu-os-cloud" + tags = [ + "${var.network_name}-group1", + module.cloud-nat-group1.router_name + ] +} + +module "mig1" { + source = "terraform-google-modules/vm/google//modules/mig" + version = "7.9.0" + instance_template = module.mig1_template.self_link + region = var.group1_region + hostname = "${var.network_name}-group1" + target_size = 2 + named_ports = [{ + name = "http", + port = 80 + }] + network = google_compute_network.default.self_link + subnetwork = google_compute_subnetwork.group1.self_link +} diff --git a/examples/user-managed-google-managed-ssl/outputs.tf b/examples/user-managed-google-managed-ssl/outputs.tf new file mode 100644 index 00000000..5ad198e7 --- /dev/null +++ b/examples/user-managed-google-managed-ssl/outputs.tf @@ -0,0 +1,31 @@ +/** + * 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 "group1_region" { + value = var.group1_region +} + +output "project_id" { + value = var.project_id +} + +output "load-balancer-ip" { + value = module.gce-lb-https.external_ip +} + +output "asset-url" { + value = "https://${module.gce-lb-https.external_ip}/assets/gcp-logo.svg" +} diff --git a/examples/user-managed-google-managed-ssl/tls.tf b/examples/user-managed-google-managed-ssl/tls.tf new file mode 100644 index 00000000..373e4e4f --- /dev/null +++ b/examples/user-managed-google-managed-ssl/tls.tf @@ -0,0 +1,84 @@ +/** + * Copyright 2017 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 "tls_private_key" "example" { + count = 3 + algorithm = "RSA" + rsa_bits = 2048 +} + +resource "tls_self_signed_cert" "example" { + count = 3 + private_key_pem = tls_private_key.example[count.index].private_key_pem + + # Certificate expires after 12 hours. + validity_period_hours = 12 + + # Generate a new certificate if Terraform is run within three + # hours of the certificate's expiration time. + early_renewal_hours = 3 + + # Reasonable set of uses for a server SSL certificate. + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + ] + + dns_names = ["example-${count.index + 1}.com"] + + subject { + common_name = "example-${count.index + 1}.com" + organization = "ACME Examples, Inc" + } +} + +resource "google_compute_ssl_certificate" "example" { + count = 3 + name = "${var.network_name}-cert-${count.index + 1}" + private_key = tls_private_key.example[count.index].private_key_pem + certificate = tls_self_signed_cert.example[count.index].cert_pem +} + +resource "tls_private_key" "single_key" { + algorithm = "RSA" + rsa_bits = 2048 +} + +resource "tls_self_signed_cert" "single_cert" { + private_key_pem = tls_private_key.single_key.private_key_pem + + # Certificate expires after 12 hours. + validity_period_hours = 12 + + # Generate a new certificate if Terraform is run within three + # hours of the certificate's expiration time. + early_renewal_hours = 3 + + # Reasonable set of uses for a server SSL certificate. + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + ] + + dns_names = ["example-single.com"] + + subject { + common_name = "example-single.com" + organization = "ACME Examples, Inc" + } +} diff --git a/examples/user-managed-google-managed-ssl/variables.tf b/examples/user-managed-google-managed-ssl/variables.tf new file mode 100644 index 00000000..704756ce --- /dev/null +++ b/examples/user-managed-google-managed-ssl/variables.tf @@ -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 + * + * 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 "group1_region" { + default = "us-west1" +} + +variable "network_name" { + default = "tf-lb-user-goog-ssl" +} + +variable "project_id" { + type = string +} diff --git a/examples/user-managed-google-managed-ssl/versions.tf b/examples/user-managed-google-managed-ssl/versions.tf new file mode 100644 index 00000000..80aa2254 --- /dev/null +++ b/examples/user-managed-google-managed-ssl/versions.tf @@ -0,0 +1,36 @@ +/** + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +terraform { + required_version = ">= 0.13" + required_providers { + google = { + source = "hashicorp/google" + } + google-beta = { + source = "hashicorp/google-beta" + } + random = { + source = "hashicorp/random" + } + template = { + source = "hashicorp/template" + } + tls = { + source = "hashicorp/tls" + } + } +} diff --git a/main.tf b/main.tf index 48fe72ac..660a63ef 100644 --- a/main.tf +++ b/main.tf @@ -45,7 +45,7 @@ resource "google_compute_global_forwarding_rule" "http" { resource "google_compute_global_forwarding_rule" "https" { provider = google-beta project = var.project - count = var.ssl || var.certificate_map != null ? 1 : 0 + count = var.ssl ? 1 : 0 name = "${var.name}-https" target = google_compute_target_https_proxy.default[0].self_link ip_address = local.address @@ -82,7 +82,7 @@ resource "google_compute_global_forwarding_rule" "http_ipv6" { resource "google_compute_global_forwarding_rule" "https_ipv6" { provider = google-beta project = var.project - count = var.enable_ipv6 && (var.ssl || var.certificate_map != null) ? 1 : 0 + count = var.enable_ipv6 && var.ssl ? 1 : 0 name = "${var.name}-ipv6-https" target = google_compute_target_https_proxy.default[0].self_link ip_address = local.ipv6_address @@ -113,7 +113,7 @@ resource "google_compute_target_http_proxy" "default" { # HTTPS proxy when ssl is true resource "google_compute_target_https_proxy" "default" { project = var.project - count = var.ssl || var.certificate_map != null ? 1 : 0 + count = var.ssl ? 1 : 0 name = "${var.name}-https-proxy" url_map = local.url_map @@ -125,7 +125,7 @@ resource "google_compute_target_https_proxy" "default" { resource "google_compute_ssl_certificate" "default" { project = var.project - count = var.ssl && length(var.managed_ssl_certificate_domains) == 0 && !var.use_ssl_certificates ? 1 : 0 + count = var.ssl && var.create_ssl_certificate ? 1 : 0 name_prefix = "${var.name}-certificate-" private_key = var.private_key certificate = var.certificate @@ -148,7 +148,7 @@ resource "random_id" "certificate" { resource "google_compute_managed_ssl_certificate" "default" { provider = google-beta project = var.project - count = var.ssl && length(var.managed_ssl_certificate_domains) > 0 && !var.use_ssl_certificates ? 1 : 0 + count = var.ssl && length(var.managed_ssl_certificate_domains) > 0 ? 1 : 0 name = var.random_certificate_suffix == true ? random_id.certificate[0].hex : "${var.name}-cert" lifecycle { diff --git a/modules/dynamic_backends/README.md b/modules/dynamic_backends/README.md index 658b767b..a10c39db 100644 --- a/modules/dynamic_backends/README.md +++ b/modules/dynamic_backends/README.md @@ -113,11 +113,12 @@ module "gce-lb-http" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | address | Existing IPv4 address to use (the actual IP address value) | `string` | `null` | no | -| backends | Map backend indices to list of backend maps. |
map(object({
port = optional(number)
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

timeout_sec = optional(number)
connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)

health_check = object({
host = optional(string)
request_path = optional(string)
request = optional(string)
response = optional(string)
port = optional(number)
port_name = optional(string)
proxy_header = optional(string)
port_specification = optional(string)
protocol = optional(string)
check_interval_sec = optional(number)
timeout_sec = optional(number)
healthy_threshold = optional(number)
unhealthy_threshold = optional(number)
logging = optional(bool)
})

log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

balancing_mode = optional(string)
capacity_scaler = optional(number)
description = optional(string)
max_connections = optional(number)
max_connections_per_instance = optional(number)
max_connections_per_endpoint = optional(number)
max_rate = optional(number)
max_rate_per_instance = optional(number)
max_rate_per_endpoint = optional(number)
max_utilization = optional(number)
}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
outlier_detection = optional(object({
base_ejection_time = optional(object({
seconds = number
nanos = optional(number)
}))
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)
interval = optional(object({
seconds = number
nanos = 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)
}))
}))
| n/a | yes | -| certificate | Content of the SSL certificate. Required if `ssl` is `true` and `ssl_certificates` is empty. | `string` | `null` | no | -| certificate\_map | Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy | `string` | `null` | no | +| backends | Map backend indices to list of backend maps. |
map(object({
port = optional(number)
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

timeout_sec = optional(number)
connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)

health_check = object({
host = optional(string)
request_path = optional(string)
request = optional(string)
response = optional(string)
port = optional(number)
port_name = optional(string)
proxy_header = optional(string)
port_specification = optional(string)
protocol = optional(string)
check_interval_sec = optional(number)
timeout_sec = optional(number)
healthy_threshold = optional(number)
unhealthy_threshold = optional(number)
logging = optional(bool)
})

log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

balancing_mode = optional(string)
capacity_scaler = optional(number)
description = optional(string)
max_connections = optional(number)
max_connections_per_instance = optional(number)
max_connections_per_endpoint = optional(number)
max_rate = optional(number)
max_rate_per_instance = optional(number)
max_rate_per_endpoint = optional(number)
max_utilization = optional(number)
}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
}))
| n/a | yes | +| certificate | Content of the SSL certificate. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true` | `string` | `null` | no | +| certificate\_map | Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy. Requires `ssl` to be set to `true` | `string` | `null` | no | | create\_address | Create a new global IPv4 address | `bool` | `true` | no | | create\_ipv6\_address | Allocate a new IPv6 address. Conflicts with "ipv6\_address" - if both specified, "create\_ipv6\_address" takes precedence. | `bool` | `false` | no | +| create\_ssl\_certificate | If `true`, Create certificate using `private_key/certificate` | `bool` | `false` | no | | create\_url\_map | Set to `false` if url\_map variable is provided. | `bool` | `true` | no | | edge\_security\_policy | The resource URL for the edge security policy to associate with the backend service | `string` | `null` | no | | enable\_ipv6 | Enable IPv6 address on the CDN load-balancer | `bool` | `false` | no | @@ -128,21 +129,20 @@ module "gce-lb-http" { | ipv6\_address | An existing IPv6 address to use (the actual IP address value) | `string` | `null` | no | | labels | The labels to attach to resources created by this module | `map(string)` | `{}` | no | | load\_balancing\_scheme | Load balancing scheme type (EXTERNAL for classic external load balancer, EXTERNAL\_MANAGED for Envoy-based load balancer, and INTERNAL\_SELF\_MANAGED for traffic director) | `string` | `"EXTERNAL"` | no | -| managed\_ssl\_certificate\_domains | Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true` and `use_ssl_certificates` set to `false`. | `list(string)` | `[]` | no | +| managed\_ssl\_certificate\_domains | Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true` | `list(string)` | `[]` | no | | name | Name for the forwarding rule and prefix for supporting resources | `string` | n/a | yes | | network | Network for INTERNAL\_SELF\_MANAGED load balancing scheme | `string` | `"default"` | no | -| private\_key | Content of the private SSL key. Required if `ssl` is `true` and `ssl_certificates` is empty. | `string` | `null` | no | +| private\_key | Content of the private SSL key. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true` | `string` | `null` | no | | project | The project to deploy to, if not set the default provider project is used. | `string` | n/a | yes | | quic | Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only. | `bool` | `null` | no | | random\_certificate\_suffix | Bool to enable/disable random certificate name generation. Set and keep this to true if you need to change the SSL cert. | `bool` | `false` | no | | security\_policy | The resource URL for the security policy to associate with the backend service | `string` | `null` | no | -| ssl | Set to `true` to enable SSL support, requires variable `ssl_certificates` - a list of self\_link certs | `bool` | `false` | no | -| ssl\_certificates | SSL cert self\_link list. Required if `ssl` is `true` and no `private_key` and `certificate` is provided. | `list(string)` | `[]` | no | +| ssl | Set to `true` to enable SSL support. If `true` then at least one of these are required: 1) `ssl_certificates` OR 2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR 3) `managed_ssl_certificate_domains`, OR 4) `certificate_map` | `bool` | `false` | no | +| ssl\_certificates | SSL cert self\_link list. Requires `ssl` to be set to `true` | `list(string)` | `[]` | no | | ssl\_policy | Selfink to SSL Policy | `string` | `null` | no | | target\_service\_accounts | List of target service accounts for health check firewall rule. Exactly one of target\_tags or target\_service\_accounts should be specified. | `list(string)` | `[]` | no | | target\_tags | List of target tags for health check firewall rule. Exactly one of target\_tags or target\_service\_accounts should be specified. | `list(string)` | `[]` | no | | url\_map | The url\_map resource to use. Default is to send all traffic to first backend. | `string` | `null` | no | -| use\_ssl\_certificates | If true, use the certificates provided by `ssl_certificates`, otherwise, create cert from `private_key` and `certificate` | `bool` | `false` | no | ## Outputs diff --git a/modules/dynamic_backends/main.tf b/modules/dynamic_backends/main.tf index d6ff812f..84615e32 100644 --- a/modules/dynamic_backends/main.tf +++ b/modules/dynamic_backends/main.tf @@ -45,7 +45,7 @@ resource "google_compute_global_forwarding_rule" "http" { resource "google_compute_global_forwarding_rule" "https" { provider = google-beta project = var.project - count = var.ssl || var.certificate_map != null ? 1 : 0 + count = var.ssl ? 1 : 0 name = "${var.name}-https" target = google_compute_target_https_proxy.default[0].self_link ip_address = local.address @@ -82,7 +82,7 @@ resource "google_compute_global_forwarding_rule" "http_ipv6" { resource "google_compute_global_forwarding_rule" "https_ipv6" { provider = google-beta project = var.project - count = var.enable_ipv6 && (var.ssl || var.certificate_map != null) ? 1 : 0 + count = var.enable_ipv6 && var.ssl ? 1 : 0 name = "${var.name}-ipv6-https" target = google_compute_target_https_proxy.default[0].self_link ip_address = local.ipv6_address @@ -113,7 +113,7 @@ resource "google_compute_target_http_proxy" "default" { # HTTPS proxy when ssl is true resource "google_compute_target_https_proxy" "default" { project = var.project - count = var.ssl || var.certificate_map != null ? 1 : 0 + count = var.ssl ? 1 : 0 name = "${var.name}-https-proxy" url_map = local.url_map @@ -125,7 +125,7 @@ resource "google_compute_target_https_proxy" "default" { resource "google_compute_ssl_certificate" "default" { project = var.project - count = var.ssl && length(var.managed_ssl_certificate_domains) == 0 && !var.use_ssl_certificates ? 1 : 0 + count = var.ssl && var.create_ssl_certificate ? 1 : 0 name_prefix = "${var.name}-certificate-" private_key = var.private_key certificate = var.certificate @@ -148,7 +148,7 @@ resource "random_id" "certificate" { resource "google_compute_managed_ssl_certificate" "default" { provider = google-beta project = var.project - count = var.ssl && length(var.managed_ssl_certificate_domains) > 0 && !var.use_ssl_certificates ? 1 : 0 + count = var.ssl && length(var.managed_ssl_certificate_domains) > 0 ? 1 : 0 name = var.random_certificate_suffix == true ? random_id.certificate[0].hex : "${var.name}-cert" lifecycle { diff --git a/modules/dynamic_backends/variables.tf b/modules/dynamic_backends/variables.tf index 5f27bff0..56018f1b 100644 --- a/modules/dynamic_backends/variables.tf +++ b/modules/dynamic_backends/variables.tf @@ -202,51 +202,57 @@ variable "http_forward" { } variable "ssl" { - description = "Set to `true` to enable SSL support, requires variable `ssl_certificates` - a list of self_link certs" + description = "Set to `true` to enable SSL support. If `true` then at least one of these are required: 1) `ssl_certificates` OR 2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR 3) `managed_ssl_certificate_domains`, OR 4) `certificate_map`" type = bool default = false } -variable "ssl_policy" { - type = string - description = "Selfink to SSL Policy" - default = null +variable "create_ssl_certificate" { + description = "If `true`, Create certificate using `private_key/certificate`" + type = bool + default = false } -variable "quic" { - type = bool - description = "Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only." - default = null +variable "ssl_certificates" { + description = "SSL cert self_link list. Requires `ssl` to be set to `true`" + type = list(string) + default = [] } variable "private_key" { - description = "Content of the private SSL key. Required if `ssl` is `true` and `ssl_certificates` is empty." + description = "Content of the private SSL key. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true`" type = string default = null } variable "certificate" { - description = "Content of the SSL certificate. Required if `ssl` is `true` and `ssl_certificates` is empty." + description = "Content of the SSL certificate. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true`" type = string default = null } variable "managed_ssl_certificate_domains" { - description = "Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true` and `use_ssl_certificates` set to `false`." + description = "Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true`" type = list(string) default = [] } -variable "use_ssl_certificates" { - description = "If true, use the certificates provided by `ssl_certificates`, otherwise, create cert from `private_key` and `certificate`" - type = bool - default = false +variable "certificate_map" { + description = "Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy. Requires `ssl` to be set to `true`" + type = string + default = null } -variable "ssl_certificates" { - description = "SSL cert self_link list. Required if `ssl` is `true` and no `private_key` and `certificate` is provided." - type = list(string) - default = [] +variable "ssl_policy" { + type = string + description = "Selfink to SSL Policy" + default = null +} + +variable "quic" { + type = bool + description = "Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only." + default = null } variable "edge_security_policy" { @@ -285,12 +291,6 @@ variable "load_balancing_scheme" { default = "EXTERNAL" } -variable "certificate_map" { - description = "Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy" - type = string - default = null -} - variable "network" { description = "Network for INTERNAL_SELF_MANAGED load balancing scheme" type = string diff --git a/modules/serverless_negs/README.md b/modules/serverless_negs/README.md index 9e1588b7..062aaac6 100644 --- a/modules/serverless_negs/README.md +++ b/modules/serverless_negs/README.md @@ -79,11 +79,12 @@ module "lb-http" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | address | Existing IPv4 address to use (the actual IP address value) | `string` | `null` | no | -| backends | Map backend indices to list of backend maps. |
map(object({
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)


log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
outlier_detection = optional(object({
base_ejection_time = optional(object({
seconds = number
nanos = optional(number)
}))
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)
interval = optional(object({
seconds = number
nanos = 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)
}))
}))
| n/a | yes | -| certificate | Content of the SSL certificate. Required if `ssl` is `true` and `ssl_certificates` is empty. | `string` | `null` | no | -| certificate\_map | Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy | `string` | `null` | no | +| backends | Map backend indices to list of backend maps. |
map(object({
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)


log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
}))
| n/a | yes | +| certificate | Content of the SSL certificate. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true` | `string` | `null` | no | +| certificate\_map | Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy. Requires `ssl` to be set to `true` | `string` | `null` | no | | create\_address | Create a new global IPv4 address | `bool` | `true` | no | | create\_ipv6\_address | Allocate a new IPv6 address. Conflicts with "ipv6\_address" - if both specified, "create\_ipv6\_address" takes precedence. | `bool` | `false` | no | +| create\_ssl\_certificate | If `true`, Create certificate using `private_key/certificate` | `bool` | `false` | no | | create\_url\_map | Set to `false` if url\_map variable is provided. | `bool` | `true` | no | | edge\_security\_policy | The resource URL for the edge security policy to associate with the backend service | `string` | `null` | no | | enable\_ipv6 | Enable IPv6 address on the CDN load-balancer | `bool` | `false` | no | @@ -92,19 +93,18 @@ module "lb-http" { | ipv6\_address | An existing IPv6 address to use (the actual IP address value) | `string` | `null` | no | | labels | The labels to attach to resources created by this module | `map(string)` | `{}` | no | | load\_balancing\_scheme | Load balancing scheme type (EXTERNAL for classic external load balancer, EXTERNAL\_MANAGED for Envoy-based load balancer, and INTERNAL\_SELF\_MANAGED for traffic director) | `string` | `"EXTERNAL"` | no | -| managed\_ssl\_certificate\_domains | Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true` and `use_ssl_certificates` set to `false`. | `list(string)` | `[]` | no | +| managed\_ssl\_certificate\_domains | Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true` | `list(string)` | `[]` | no | | name | Name for the forwarding rule and prefix for supporting resources | `string` | n/a | yes | | network | Network for INTERNAL\_SELF\_MANAGED load balancing scheme | `string` | `"default"` | no | -| private\_key | Content of the private SSL key. Required if `ssl` is `true` and `ssl_certificates` is empty. | `string` | `null` | no | +| private\_key | Content of the private SSL key. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true` | `string` | `null` | no | | project | The project to deploy to, if not set the default provider project is used. | `string` | n/a | yes | | quic | Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only. | `bool` | `null` | no | | random\_certificate\_suffix | Bool to enable/disable random certificate name generation. Set and keep this to true if you need to change the SSL cert. | `bool` | `false` | no | | security\_policy | The resource URL for the security policy to associate with the backend service | `string` | `null` | no | -| ssl | Set to `true` to enable SSL support, requires variable `ssl_certificates` - a list of self\_link certs | `bool` | `false` | no | -| ssl\_certificates | SSL cert self\_link list. Required if `ssl` is `true` and no `private_key` and `certificate` is provided. | `list(string)` | `[]` | no | +| ssl | Set to `true` to enable SSL support. If `true` then at least one of these are required: 1) `ssl_certificates` OR 2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR 3) `managed_ssl_certificate_domains`, OR 4) `certificate_map` | `bool` | `false` | no | +| ssl\_certificates | SSL cert self\_link list. Requires `ssl` to be set to `true` | `list(string)` | `[]` | no | | ssl\_policy | Selfink to SSL Policy | `string` | `null` | no | | url\_map | The url\_map resource to use. Default is to send all traffic to first backend. | `string` | `null` | no | -| use\_ssl\_certificates | If true, use the certificates provided by `ssl_certificates`, otherwise, create cert from `private_key` and `certificate` | `bool` | `false` | no | ## Outputs diff --git a/modules/serverless_negs/main.tf b/modules/serverless_negs/main.tf index 90ed40cc..f7036808 100644 --- a/modules/serverless_negs/main.tf +++ b/modules/serverless_negs/main.tf @@ -44,7 +44,7 @@ resource "google_compute_global_forwarding_rule" "http" { resource "google_compute_global_forwarding_rule" "https" { provider = google-beta project = var.project - count = var.ssl || var.certificate_map != null ? 1 : 0 + count = var.ssl ? 1 : 0 name = "${var.name}-https" target = google_compute_target_https_proxy.default[0].self_link ip_address = local.address @@ -81,7 +81,7 @@ resource "google_compute_global_forwarding_rule" "http_ipv6" { resource "google_compute_global_forwarding_rule" "https_ipv6" { provider = google-beta project = var.project - count = var.enable_ipv6 && (var.ssl || var.certificate_map != null) ? 1 : 0 + count = var.enable_ipv6 && var.ssl ? 1 : 0 name = "${var.name}-ipv6-https" target = google_compute_target_https_proxy.default[0].self_link ip_address = local.ipv6_address @@ -112,7 +112,7 @@ resource "google_compute_target_http_proxy" "default" { # HTTPS proxy when ssl is true resource "google_compute_target_https_proxy" "default" { project = var.project - count = var.ssl || var.certificate_map != null ? 1 : 0 + count = var.ssl ? 1 : 0 name = "${var.name}-https-proxy" url_map = local.url_map @@ -124,7 +124,7 @@ resource "google_compute_target_https_proxy" "default" { resource "google_compute_ssl_certificate" "default" { project = var.project - count = var.ssl && length(var.managed_ssl_certificate_domains) == 0 && !var.use_ssl_certificates ? 1 : 0 + count = var.ssl && var.create_ssl_certificate ? 1 : 0 name_prefix = "${var.name}-certificate-" private_key = var.private_key certificate = var.certificate @@ -147,7 +147,7 @@ resource "random_id" "certificate" { resource "google_compute_managed_ssl_certificate" "default" { provider = google-beta project = var.project - count = var.ssl && length(var.managed_ssl_certificate_domains) > 0 && !var.use_ssl_certificates ? 1 : 0 + count = var.ssl && length(var.managed_ssl_certificate_domains) > 0 ? 1 : 0 name = var.random_certificate_suffix == true ? random_id.certificate[0].hex : "${var.name}-cert" lifecycle { diff --git a/modules/serverless_negs/variables.tf b/modules/serverless_negs/variables.tf index 1629d1a2..59a56b3e 100644 --- a/modules/serverless_negs/variables.tf +++ b/modules/serverless_negs/variables.tf @@ -151,51 +151,57 @@ variable "http_forward" { } variable "ssl" { - description = "Set to `true` to enable SSL support, requires variable `ssl_certificates` - a list of self_link certs" + description = "Set to `true` to enable SSL support. If `true` then at least one of these are required: 1) `ssl_certificates` OR 2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR 3) `managed_ssl_certificate_domains`, OR 4) `certificate_map`" type = bool default = false } -variable "ssl_policy" { - type = string - description = "Selfink to SSL Policy" - default = null +variable "create_ssl_certificate" { + description = "If `true`, Create certificate using `private_key/certificate`" + type = bool + default = false } -variable "quic" { - type = bool - description = "Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only." - default = null +variable "ssl_certificates" { + description = "SSL cert self_link list. Requires `ssl` to be set to `true`" + type = list(string) + default = [] } variable "private_key" { - description = "Content of the private SSL key. Required if `ssl` is `true` and `ssl_certificates` is empty." + description = "Content of the private SSL key. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true`" type = string default = null } variable "certificate" { - description = "Content of the SSL certificate. Required if `ssl` is `true` and `ssl_certificates` is empty." + description = "Content of the SSL certificate. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true`" type = string default = null } variable "managed_ssl_certificate_domains" { - description = "Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true` and `use_ssl_certificates` set to `false`." + description = "Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true`" type = list(string) default = [] } -variable "use_ssl_certificates" { - description = "If true, use the certificates provided by `ssl_certificates`, otherwise, create cert from `private_key` and `certificate`" - type = bool - default = false +variable "certificate_map" { + description = "Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy. Requires `ssl` to be set to `true`" + type = string + default = null } -variable "ssl_certificates" { - description = "SSL cert self_link list. Required if `ssl` is `true` and no `private_key` and `certificate` is provided." - type = list(string) - default = [] +variable "ssl_policy" { + type = string + description = "Selfink to SSL Policy" + default = null +} + +variable "quic" { + type = bool + description = "Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only." + default = null } variable "edge_security_policy" { @@ -234,12 +240,6 @@ variable "load_balancing_scheme" { default = "EXTERNAL" } -variable "certificate_map" { - description = "Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy" - type = string - default = null -} - variable "network" { description = "Network for INTERNAL_SELF_MANAGED load balancing scheme" type = string diff --git a/test/setup/main.tf b/test/setup/main.tf index c94f1ce7..e011f519 100644 --- a/test/setup/main.tf +++ b/test/setup/main.tf @@ -34,6 +34,7 @@ module "project-ci-lb-http" { "compute.googleapis.com", "run.googleapis.com", "iam.googleapis.com", + "certificatemanager.googleapis.com", ] } @@ -57,5 +58,6 @@ module "project-ci-lb-http-1" { "compute.googleapis.com", "run.googleapis.com", "iam.googleapis.com", + "certificatemanager.googleapis.com", ] } diff --git a/variables.tf b/variables.tf index 5f27bff0..56018f1b 100644 --- a/variables.tf +++ b/variables.tf @@ -202,51 +202,57 @@ variable "http_forward" { } variable "ssl" { - description = "Set to `true` to enable SSL support, requires variable `ssl_certificates` - a list of self_link certs" + description = "Set to `true` to enable SSL support. If `true` then at least one of these are required: 1) `ssl_certificates` OR 2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR 3) `managed_ssl_certificate_domains`, OR 4) `certificate_map`" type = bool default = false } -variable "ssl_policy" { - type = string - description = "Selfink to SSL Policy" - default = null +variable "create_ssl_certificate" { + description = "If `true`, Create certificate using `private_key/certificate`" + type = bool + default = false } -variable "quic" { - type = bool - description = "Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only." - default = null +variable "ssl_certificates" { + description = "SSL cert self_link list. Requires `ssl` to be set to `true`" + type = list(string) + default = [] } variable "private_key" { - description = "Content of the private SSL key. Required if `ssl` is `true` and `ssl_certificates` is empty." + description = "Content of the private SSL key. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true`" type = string default = null } variable "certificate" { - description = "Content of the SSL certificate. Required if `ssl` is `true` and `ssl_certificates` is empty." + description = "Content of the SSL certificate. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true`" type = string default = null } variable "managed_ssl_certificate_domains" { - description = "Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true` and `use_ssl_certificates` set to `false`." + description = "Create Google-managed SSL certificates for specified domains. Requires `ssl` to be set to `true`" type = list(string) default = [] } -variable "use_ssl_certificates" { - description = "If true, use the certificates provided by `ssl_certificates`, otherwise, create cert from `private_key` and `certificate`" - type = bool - default = false +variable "certificate_map" { + description = "Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy. Requires `ssl` to be set to `true`" + type = string + default = null } -variable "ssl_certificates" { - description = "SSL cert self_link list. Required if `ssl` is `true` and no `private_key` and `certificate` is provided." - type = list(string) - default = [] +variable "ssl_policy" { + type = string + description = "Selfink to SSL Policy" + default = null +} + +variable "quic" { + type = bool + description = "Specifies the QUIC override policy for this resource. Set true to enable HTTP/3 and Google QUIC support, false to disable both. Defaults to null which enables support for HTTP/3 only." + default = null } variable "edge_security_policy" { @@ -285,12 +291,6 @@ variable "load_balancing_scheme" { default = "EXTERNAL" } -variable "certificate_map" { - description = "Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy" - type = string - default = null -} - variable "network" { description = "Network for INTERNAL_SELF_MANAGED load balancing scheme" type = string From 3dfc6f308fdb29a7279c2c99d41cfaee085fb48a Mon Sep 17 00:00:00 2001 From: Imran Nayer Date: Mon, 6 Nov 2023 19:49:49 +0000 Subject: [PATCH 2/7] fix certificate-map --- README.md | 3 ++- autogen/outputs.tf.tmpl | 8 ++++---- build/int.cloudbuild.yaml | 26 ++++++++++++++++++++++++++ examples/dynamic-backend/main.tf | 3 +-- examples/https-redirect/main.tf | 17 ++++++++--------- examples/multiple-certs/main.tf | 11 +++++------ modules/dynamic_backends/README.md | 3 ++- modules/dynamic_backends/outputs.tf | 5 +++++ modules/serverless_negs/README.md | 3 ++- modules/serverless_negs/outputs.tf | 5 +++++ outputs.tf | 5 +++++ 11 files changed, 65 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 90df9227..529b025e 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ module "gce-lb-http" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | address | Existing IPv4 address to use (the actual IP address value) | `string` | `null` | no | -| backends | Map backend indices to list of backend maps. |
map(object({
port = optional(number)
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

timeout_sec = optional(number)
connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)

health_check = object({
host = optional(string)
request_path = optional(string)
request = optional(string)
response = optional(string)
port = optional(number)
port_name = optional(string)
proxy_header = optional(string)
port_specification = optional(string)
protocol = optional(string)
check_interval_sec = optional(number)
timeout_sec = optional(number)
healthy_threshold = optional(number)
unhealthy_threshold = optional(number)
logging = optional(bool)
})

log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

balancing_mode = optional(string)
capacity_scaler = optional(number)
description = optional(string)
max_connections = optional(number)
max_connections_per_instance = optional(number)
max_connections_per_endpoint = optional(number)
max_rate = optional(number)
max_rate_per_instance = optional(number)
max_rate_per_endpoint = optional(number)
max_utilization = optional(number)
}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
}))
| n/a | yes | +| backends | Map backend indices to list of backend maps. |
map(object({
port = optional(number)
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

timeout_sec = optional(number)
connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)

health_check = object({
host = optional(string)
request_path = optional(string)
request = optional(string)
response = optional(string)
port = optional(number)
port_name = optional(string)
proxy_header = optional(string)
port_specification = optional(string)
protocol = optional(string)
check_interval_sec = optional(number)
timeout_sec = optional(number)
healthy_threshold = optional(number)
unhealthy_threshold = optional(number)
logging = optional(bool)
})

log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

balancing_mode = optional(string)
capacity_scaler = optional(number)
description = optional(string)
max_connections = optional(number)
max_connections_per_instance = optional(number)
max_connections_per_endpoint = optional(number)
max_rate = optional(number)
max_rate_per_instance = optional(number)
max_rate_per_endpoint = optional(number)
max_utilization = optional(number)
}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
outlier_detection = optional(object({
base_ejection_time = optional(object({
seconds = number
nanos = optional(number)
}))
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)
interval = optional(object({
seconds = number
nanos = 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)
}))
}))
| n/a | yes | | certificate | Content of the SSL certificate. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true` | `string` | `null` | no | | certificate\_map | Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy. Requires `ssl` to be set to `true` | `string` | `null` | no | | create\_address | Create a new global IPv4 address | `bool` | `true` | no | @@ -161,6 +161,7 @@ module "gce-lb-http" { | http\_proxy | The HTTP proxy used by this module. | | https\_proxy | The HTTPS proxy used by this module. | | ipv6\_enabled | Whether IPv6 configuration is enabled on this load-balancer | +| ssl\_certificate\_created | The SSL certificate create from key/pem | | url\_map | The default URL map used by this module. | diff --git a/autogen/outputs.tf.tmpl b/autogen/outputs.tf.tmpl index 7e7a8afa..8cbc4e2d 100644 --- a/autogen/outputs.tf.tmpl +++ b/autogen/outputs.tf.tmpl @@ -50,7 +50,7 @@ output "url_map" { value = google_compute_url_map.default[*].self_link } -output "ssl_certificate" { - description = "The managed SSL certificates" - value = google_compute_ssl_certificate.default.self_link -} \ No newline at end of file +output "ssl_certificate_created" { + description = "The SSL certificate create from key/pem" + value = google_compute_ssl_certificate.default.*.self_link +} diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index fd28d8d8..4054a752 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -62,6 +62,32 @@ steps: - id: traffic-director-example-teardown name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', 'cft test run TestAll/examples/traffic-director --stage teardown --verbose'] +# certificate-map example +- id: certificate-map-example-init + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TTestAll/examples/certificate-map --stage init --verbose'] +- id: certificate-map-example-apply + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TTestAll/examples/certificate-map --stage apply --verbose'] +- id: certificate-map-example-verify + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TTestAll/examples/certificate-map --stage verify --verbose'] +- id: certificate-map-example-teardown + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TTestAll/examples/certificate-map --stage teardown --verbose'] +# managed-manual-certificates example +- id: user-managed-google-managed-ssl-example-init + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestAll/examples/user-managed-google-managed-ssl --stage init --verbose'] +- id: user-managed-google-managed-ssl-example-apply + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestAll/examples/user-managed-google-managed-ssl --stage apply --verbose'] +- id: user-managed-google-managed-ssl-example-verify + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestAll/examples/user-managed-google-managed-ssl --stage verify --verbose'] +- id: user-managed-google-managed-ssl-example-teardown + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestAll/examples/user-managed-google-managed-ssl --stage teardown --verbose'] tags: - 'ci' - 'integration' diff --git a/examples/dynamic-backend/main.tf b/examples/dynamic-backend/main.tf index 101cceed..2d1bfea7 100644 --- a/examples/dynamic-backend/main.tf +++ b/examples/dynamic-backend/main.tf @@ -41,8 +41,7 @@ module "load_balancer" { load_balancing_scheme = "EXTERNAL_MANAGED" - ssl = true - use_ssl_certificates = true + ssl = true ssl_certificates = [ google_compute_managed_ssl_certificate.frontend.self_link ] diff --git a/examples/https-redirect/main.tf b/examples/https-redirect/main.tf index 5929e3f0..073db8ae 100644 --- a/examples/https-redirect/main.tf +++ b/examples/https-redirect/main.tf @@ -92,15 +92,14 @@ module "mig" { # [START cloudloadbalancing_ext_http_gce_http_redirect] module "gce-lb-http" { - source = "../../" - name = "ci-https-redirect" - project = var.project - target_tags = [var.network_name] - firewall_networks = [google_compute_network.default.name] - ssl = true - ssl_certificates = [google_compute_ssl_certificate.example.self_link] - use_ssl_certificates = true - https_redirect = true + source = "../../" + name = "ci-https-redirect" + project = var.project + target_tags = [var.network_name] + firewall_networks = [google_compute_network.default.name] + ssl = true + ssl_certificates = [google_compute_ssl_certificate.example.self_link] + https_redirect = true backends = { default = { diff --git a/examples/multiple-certs/main.tf b/examples/multiple-certs/main.tf index 1735aab0..9d9d9f04 100644 --- a/examples/multiple-certs/main.tf +++ b/examples/multiple-certs/main.tf @@ -129,12 +129,11 @@ module "gce-lb-https" { "${var.network_name}-group3", module.cloud-nat-group3.router_name ] - firewall_networks = [google_compute_network.default.self_link] - url_map = google_compute_url_map.https-multi-cert.self_link - create_url_map = false - ssl = true - ssl_certificates = google_compute_ssl_certificate.example.*.self_link - use_ssl_certificates = true + firewall_networks = [google_compute_network.default.self_link] + url_map = google_compute_url_map.https-multi-cert.self_link + create_url_map = false + ssl = true + ssl_certificates = google_compute_ssl_certificate.example.*.self_link backends = { default = { diff --git a/modules/dynamic_backends/README.md b/modules/dynamic_backends/README.md index a10c39db..6f6f4219 100644 --- a/modules/dynamic_backends/README.md +++ b/modules/dynamic_backends/README.md @@ -113,7 +113,7 @@ module "gce-lb-http" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | address | Existing IPv4 address to use (the actual IP address value) | `string` | `null` | no | -| backends | Map backend indices to list of backend maps. |
map(object({
port = optional(number)
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

timeout_sec = optional(number)
connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)

health_check = object({
host = optional(string)
request_path = optional(string)
request = optional(string)
response = optional(string)
port = optional(number)
port_name = optional(string)
proxy_header = optional(string)
port_specification = optional(string)
protocol = optional(string)
check_interval_sec = optional(number)
timeout_sec = optional(number)
healthy_threshold = optional(number)
unhealthy_threshold = optional(number)
logging = optional(bool)
})

log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

balancing_mode = optional(string)
capacity_scaler = optional(number)
description = optional(string)
max_connections = optional(number)
max_connections_per_instance = optional(number)
max_connections_per_endpoint = optional(number)
max_rate = optional(number)
max_rate_per_instance = optional(number)
max_rate_per_endpoint = optional(number)
max_utilization = optional(number)
}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
}))
| n/a | yes | +| backends | Map backend indices to list of backend maps. |
map(object({
port = optional(number)
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

timeout_sec = optional(number)
connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)

health_check = object({
host = optional(string)
request_path = optional(string)
request = optional(string)
response = optional(string)
port = optional(number)
port_name = optional(string)
proxy_header = optional(string)
port_specification = optional(string)
protocol = optional(string)
check_interval_sec = optional(number)
timeout_sec = optional(number)
healthy_threshold = optional(number)
unhealthy_threshold = optional(number)
logging = optional(bool)
})

log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

balancing_mode = optional(string)
capacity_scaler = optional(number)
description = optional(string)
max_connections = optional(number)
max_connections_per_instance = optional(number)
max_connections_per_endpoint = optional(number)
max_rate = optional(number)
max_rate_per_instance = optional(number)
max_rate_per_endpoint = optional(number)
max_utilization = optional(number)
}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
outlier_detection = optional(object({
base_ejection_time = optional(object({
seconds = number
nanos = optional(number)
}))
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)
interval = optional(object({
seconds = number
nanos = 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)
}))
}))
| n/a | yes | | certificate | Content of the SSL certificate. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true` | `string` | `null` | no | | certificate\_map | Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy. Requires `ssl` to be set to `true` | `string` | `null` | no | | create\_address | Create a new global IPv4 address | `bool` | `true` | no | @@ -154,6 +154,7 @@ module "gce-lb-http" { | http\_proxy | The HTTP proxy used by this module. | | https\_proxy | The HTTPS proxy used by this module. | | ipv6\_enabled | Whether IPv6 configuration is enabled on this load-balancer | +| ssl\_certificate\_created | The SSL certificate create from key/pem | | url\_map | The default URL map used by this module. | diff --git a/modules/dynamic_backends/outputs.tf b/modules/dynamic_backends/outputs.tf index c17a0ef4..f6d9da29 100644 --- a/modules/dynamic_backends/outputs.tf +++ b/modules/dynamic_backends/outputs.tf @@ -49,3 +49,8 @@ output "url_map" { description = "The default URL map used by this module." value = google_compute_url_map.default[*].self_link } + +output "ssl_certificate_created" { + description = "The SSL certificate create from key/pem" + value = google_compute_ssl_certificate.default.*.self_link +} diff --git a/modules/serverless_negs/README.md b/modules/serverless_negs/README.md index 062aaac6..f40a9551 100644 --- a/modules/serverless_negs/README.md +++ b/modules/serverless_negs/README.md @@ -79,7 +79,7 @@ module "lb-http" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | address | Existing IPv4 address to use (the actual IP address value) | `string` | `null` | no | -| backends | Map backend indices to list of backend maps. |
map(object({
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)


log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
}))
| n/a | yes | +| backends | Map backend indices to list of backend maps. |
map(object({
project = optional(string)
protocol = optional(string)
port_name = optional(string)
description = optional(string)
enable_cdn = optional(bool)
compression_mode = optional(string)
security_policy = optional(string, null)
edge_security_policy = optional(string, null)
custom_request_headers = optional(list(string))
custom_response_headers = optional(list(string))

connection_draining_timeout_sec = optional(number)
session_affinity = optional(string)
affinity_cookie_ttl_sec = optional(number)


log_config = object({
enable = optional(bool)
sample_rate = optional(number)
})

groups = list(object({
group = string

}))
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
})
cdn_policy = optional(object({
cache_mode = optional(string)
signed_url_cache_max_age_sec = optional(string)
default_ttl = optional(number)
max_ttl = optional(number)
client_ttl = optional(number)
negative_caching = optional(bool)
negative_caching_policy = optional(object({
code = optional(number)
ttl = optional(number)
}))
serve_while_stale = optional(number)
cache_key_policy = optional(object({
include_host = optional(bool)
include_protocol = optional(bool)
include_query_string = optional(bool)
query_string_blacklist = optional(list(string))
query_string_whitelist = optional(list(string))
include_http_headers = optional(list(string))
include_named_cookies = optional(list(string))
}))
}))
outlier_detection = optional(object({
base_ejection_time = optional(object({
seconds = number
nanos = optional(number)
}))
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)
interval = optional(object({
seconds = number
nanos = 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)
}))
}))
| n/a | yes | | certificate | Content of the SSL certificate. Requires `ssl` to be set to `true` and `create_ssl_certificate` set to `true` | `string` | `null` | no | | certificate\_map | Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy. Requires `ssl` to be set to `true` | `string` | `null` | no | | create\_address | Create a new global IPv4 address | `bool` | `true` | no | @@ -116,6 +116,7 @@ module "lb-http" { | http\_proxy | The HTTP proxy used by this module. | | https\_proxy | The HTTPS proxy used by this module. | | ipv6\_enabled | Whether IPv6 configuration is enabled on this load-balancer | +| ssl\_certificate\_created | The SSL certificate create from key/pem | | url\_map | The default URL map used by this module. | diff --git a/modules/serverless_negs/outputs.tf b/modules/serverless_negs/outputs.tf index c17a0ef4..f6d9da29 100644 --- a/modules/serverless_negs/outputs.tf +++ b/modules/serverless_negs/outputs.tf @@ -49,3 +49,8 @@ output "url_map" { description = "The default URL map used by this module." value = google_compute_url_map.default[*].self_link } + +output "ssl_certificate_created" { + description = "The SSL certificate create from key/pem" + value = google_compute_ssl_certificate.default.*.self_link +} diff --git a/outputs.tf b/outputs.tf index c17a0ef4..f6d9da29 100644 --- a/outputs.tf +++ b/outputs.tf @@ -49,3 +49,8 @@ output "url_map" { description = "The default URL map used by this module." value = google_compute_url_map.default[*].self_link } + +output "ssl_certificate_created" { + description = "The SSL certificate create from key/pem" + value = google_compute_ssl_certificate.default.*.self_link +} From bad379e816f6fcfb8621d1d23e99d3e6323da502 Mon Sep 17 00:00:00 2001 From: Imran Nayer Date: Mon, 6 Nov 2023 22:00:23 +0000 Subject: [PATCH 3/7] fix certificate map --- README.md | 2 +- autogen/README.md | 2 +- docs/upgrading_to_v10.0.md | 20 ++++++++++++++++++++ modules/dynamic_backends/README.md | 2 +- modules/serverless_negs/README.md | 2 +- 5 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 docs/upgrading_to_v10.0.md diff --git a/README.md b/README.md index 529b025e..8aac0f26 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Current version is 9.0. Upgrade guides: - [6.X -> 7.0](/docs/upgrading_to_v7.0.md) - [7.X -> 8.0](/docs/upgrading_to_v8.0.md) - [8.X -> 9.0](/docs/upgrading_to_v9.0.md) - +- [9.X -> 10.0](/docs/upgrading_to_v10.0.m) ## Usage diff --git a/autogen/README.md b/autogen/README.md index 08217367..ec5cc46e 100644 --- a/autogen/README.md +++ b/autogen/README.md @@ -50,7 +50,7 @@ Current version is 9.0. Upgrade guides: - [6.X -> 7.0](/docs/upgrading_to_v7.0.md) - [7.X -> 8.0](/docs/upgrading_to_v8.0.md) - [8.X -> 9.0](/docs/upgrading_to_v9.0.md) - +- [9.X -> 10.0](/docs/upgrading_to_v10.0.m) ## Usage diff --git a/docs/upgrading_to_v10.0.md b/docs/upgrading_to_v10.0.md new file mode 100644 index 00000000..1e414f3a --- /dev/null +++ b/docs/upgrading_to_v10.0.md @@ -0,0 +1,20 @@ +# Upgrading to v10.0 + +The 10.0 release contains backwards-incompatible changes. + +--- + +The `use_ssl_certificates` parameter has been removed. A new parmater `create_ssl_certificate` has been added. + +In order to create https load balancer you need to pass `ssl = true` and one of the following: + +1) list of self links to your own certificates passed to`ssl_certificates` OR +2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR +3) list of domains for `managed_ssl_certificate_domains`, OR +4) Managed certificate using certificate manager by passing `certificate_map` + +Load balancer allows Either 1,2,3 or option 4 + +--- +See example [user-managed-google-managed-ssl](/examples/user-managed-google-managed-ssl) for combination of `option 1,2,3` where root module will pass self link to certificates, private key/Pem and domain for google managed certificates +See example [certificate-map](/examples/certificate-map) for `option 4` where root module will pass certificate map \ No newline at end of file diff --git a/modules/dynamic_backends/README.md b/modules/dynamic_backends/README.md index 6f6f4219..892a3d1c 100644 --- a/modules/dynamic_backends/README.md +++ b/modules/dynamic_backends/README.md @@ -27,7 +27,7 @@ Current version is 9.0. Upgrade guides: - [6.X -> 7.0](/docs/upgrading_to_v7.0.md) - [7.X -> 8.0](/docs/upgrading_to_v8.0.md) - [8.X -> 9.0](/docs/upgrading_to_v9.0.md) - +- [9.X -> 10.0](/docs/upgrading_to_v10.0.m) ## Usage diff --git a/modules/serverless_negs/README.md b/modules/serverless_negs/README.md index f40a9551..5999a26d 100644 --- a/modules/serverless_negs/README.md +++ b/modules/serverless_negs/README.md @@ -22,7 +22,7 @@ Current version is 9.0. Upgrade guides: - [6.X -> 7.0](/docs/upgrading_to_v7.0.md) - [7.X -> 8.0](/docs/upgrading_to_v8.0.md) - [8.X -> 9.0](/docs/upgrading_to_v9.0.md) - +- [9.X -> 10.0](/docs/upgrading_to_v10.0.m) ## Usage From 8f850089fd00ca87eee50402d47d4bb49fd686b0 Mon Sep 17 00:00:00 2001 From: Imran Nayer Date: Mon, 6 Nov 2023 22:12:13 +0000 Subject: [PATCH 4/7] fix lint --- docs/upgrading_to_v10.0.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/upgrading_to_v10.0.md b/docs/upgrading_to_v10.0.md index 1e414f3a..a95019a4 100644 --- a/docs/upgrading_to_v10.0.md +++ b/docs/upgrading_to_v10.0.md @@ -4,17 +4,17 @@ The 10.0 release contains backwards-incompatible changes. --- -The `use_ssl_certificates` parameter has been removed. A new parmater `create_ssl_certificate` has been added. +The `use_ssl_certificates` parameter has been removed. A new parmater `create_ssl_certificate` has been added. In order to create https load balancer you need to pass `ssl = true` and one of the following: -1) list of self links to your own certificates passed to`ssl_certificates` OR -2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR -3) list of domains for `managed_ssl_certificate_domains`, OR +1) list of self links to your own certificates passed to`ssl_certificates` OR +2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR +3) list of domains for `managed_ssl_certificate_domains`, OR 4) Managed certificate using certificate manager by passing `certificate_map` Load balancer allows Either 1,2,3 or option 4 --- See example [user-managed-google-managed-ssl](/examples/user-managed-google-managed-ssl) for combination of `option 1,2,3` where root module will pass self link to certificates, private key/Pem and domain for google managed certificates -See example [certificate-map](/examples/certificate-map) for `option 4` where root module will pass certificate map \ No newline at end of file +See example [certificate-map](/examples/certificate-map) for `option 4` where root module will pass certificate map From 212411804d2c5ce3a125fb4f8823ddc5c3891b04 Mon Sep 17 00:00:00 2001 From: Imran Nayer Date: Mon, 6 Nov 2023 23:32:10 +0000 Subject: [PATCH 5/7] updated integration test timeout --- build/int.cloudbuild.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index 4054a752..3e6797d7 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -timeout: 4200s +timeout: 5400s steps: - id: swap-module-refs name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' From 12dda6a5f9a755d2b8b87671ec59cb4e98e64733 Mon Sep 17 00:00:00 2001 From: Imran Nayer Date: Tue, 7 Nov 2023 14:57:39 +0000 Subject: [PATCH 6/7] fixed typo --- build/int.cloudbuild.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index 3e6797d7..ecada0c0 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -65,16 +65,16 @@ steps: # certificate-map example - id: certificate-map-example-init name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' - args: ['/bin/bash', '-c', 'cft test run TTestAll/examples/certificate-map --stage init --verbose'] + args: ['/bin/bash', '-c', 'cft test run TestAll/examples/certificate-map --stage init --verbose'] - id: certificate-map-example-apply name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' - args: ['/bin/bash', '-c', 'cft test run TTestAll/examples/certificate-map --stage apply --verbose'] + args: ['/bin/bash', '-c', 'cft test run TestAll/examples/certificate-map --stage apply --verbose'] - id: certificate-map-example-verify name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' - args: ['/bin/bash', '-c', 'cft test run TTestAll/examples/certificate-map --stage verify --verbose'] + args: ['/bin/bash', '-c', 'cft test run TestAll/examples/certificate-map --stage verify --verbose'] - id: certificate-map-example-teardown name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' - args: ['/bin/bash', '-c', 'cft test run TTestAll/examples/certificate-map --stage teardown --verbose'] + args: ['/bin/bash', '-c', 'cft test run TestAll/examples/certificate-map --stage teardown --verbose'] # managed-manual-certificates example - id: user-managed-google-managed-ssl-example-init name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' From f258141739086931cc44e613a1064f70b5218b6c Mon Sep 17 00:00:00 2001 From: Imran Nayer Date: Wed, 8 Nov 2023 15:25:09 +0000 Subject: [PATCH 7/7] fixed lint --- docs/upgrading_to_v10.0.md | 55 +++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/docs/upgrading_to_v10.0.md b/docs/upgrading_to_v10.0.md index a95019a4..0eb5f8a2 100644 --- a/docs/upgrading_to_v10.0.md +++ b/docs/upgrading_to_v10.0.md @@ -4,9 +4,11 @@ The 10.0 release contains backwards-incompatible changes. --- -The `use_ssl_certificates` parameter has been removed. A new parmater `create_ssl_certificate` has been added. +### use_ssl_certificates is replaced with create_ssl_certificate -In order to create https load balancer you need to pass `ssl = true` and one of the following: +The `use_ssl_certificates` parameter has been removed. A new parameter `create_ssl_certificate` has been added. You can now create a load balancer with multiple certificates using certificate manager map or certificates (self managed, google managed) + +In order to create https load balancer you need to pass `ssl = true` and at least one of the following: 1) list of self links to your own certificates passed to`ssl_certificates` OR 2) `create_ssl_certificate` set to `true` and `private_key/certificate` OR @@ -16,5 +18,52 @@ In order to create https load balancer you need to pass `ssl = true` and one of Load balancer allows Either 1,2,3 or option 4 --- -See example [user-managed-google-managed-ssl](/examples/user-managed-google-managed-ssl) for combination of `option 1,2,3` where root module will pass self link to certificates, private key/Pem and domain for google managed certificates +See example [user-managed-google-managed-ssl](/examples/user-managed-google-managed-ssl) for combination of `option 1,2,3` where root module will pass self link to certificates, private key/Pem and domain for google managed certificates. You can now attach google managed certificates and user managed certificates to the load balancer at the same time. + + +```diff +module "gce-lb-https" { +- source = "GoogleCloudPlatform/lb-http/google" +- version = "~> 9.0" ++ source = "GoogleCloudPlatform/lb-http/google" ++ version = "~> 10.0" +- use_ssl_certificates = false ++ create_ssl_certificate = true + ssl = true + private_key = tls_private_key.single_key.private_key_pem + certificate = tls_self_signed_cert.single_cert.cert_pem + managed_ssl_certificate_domains = ["test.example.com"] + ssl_certificates = google_compute_ssl_certificate.example.*.self_link +``` + +Here is an example of how to pass list of self managed certificates and domain for google managed certificates. Leave pem/certificate parameter empty + + +```diff +module "gce-lb-https" { +- source = "GoogleCloudPlatform/lb-http/google" +- version = "~> 9.0" ++ source = "GoogleCloudPlatform/lb-http/google" ++ version = "~> 10.0" +- use_ssl_certificates = false ++ create_ssl_certificate = false + ssl = true + managed_ssl_certificate_domains = ["test.example.com"] + ssl_certificates = google_compute_ssl_certificate.example.*.self_link +``` + +--- + See example [certificate-map](/examples/certificate-map) for `option 4` where root module will pass certificate map + +```diff +module "gce-lb-https" { +- source = "GoogleCloudPlatform/lb-http/google" +- version = "~> 9.0" ++ source = "GoogleCloudPlatform/lb-http/google" ++ version = "~> 10.0" +- use_ssl_certificates = false ++ create_ssl_certificate = false + ssl = true + certificate_map = var.cert_map_name +```