Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions gcp/compute_engine/cloudrun_serverless_neg_https_lb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Global HTTP Load Balancer Terraform Module for Cloud Run Serverless NEGs

This submodule allows you to create Cloud HTTP(S) Load Balancer with Serverless Network Endpoint Groups (NEGs) and place serverless services from Cloud Run behind a Cloud Load Balancer.

## Example usage

```HCL
module cloudrun_serverless_neg_https_lb {
source = "github.com/mesoform/terraform-infrastructure-modules//gcp/compute_engine/cloudrun_serverless_neg_https_lb"
project = "test-project"
region = "europe-west2"
serverless_neg_name = "cr-serverless-neg"
cloudrun_service_name = "cloudrun-service"
name = "test-project-lb"
ssl = true
managed_ssl_certificate_domains = ["test-project-domain.com"]
backends = {
cloudrun = {
description = "Cloud Run backend"
groups = [
{
group = projects/test-project/regions/europe-west2/networkEndpointGroups/cr-serverless-neg
}
]
security_policy = "cloudrun-policy"
log_config = {
enable = true
sample_rate = 1.0
}
}
}
}
```

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|:--------:|
| project | The project to deploy to. | `string` | n/a | yes |
| region | Location for serverless_neg and load balancer. | `string` | n/a | yes |
| serverless_neg_name | Name for serverless network endpoint group. | `string` | n/a | yes |
| cloudrun_service_name | Name for an existing Cloud run service. | `string` | n/a | yes |
| name | Name for the forwarding rule and prefix for supporting resources | `string` | n/a | yes |
| address | Existing IPv4 address to use (the actual IP address value) | `string` | `null` | no |
| backends | Map backend indices to list of backend maps. | <pre>map(object({<br><br> description = string<br> security_policy = string<br><br> groups = list(object({<br> group = string<br><br> }))<br> log_config = object({<br> enable = bool<br> sample_rate = number<br> })<br> }))</pre> | n/a | yes |
| certificate | Content of the SSL certificate. Required if `ssl` is `true` and `ssl_certificates` is empty. | `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\_url\_map | Set to `false` if url\_map variable is provided. | `bool` | `true` | no |
| enable\_ipv6 | Enable IPv6 address on the CDN load-balancer | `bool` | `false` | no |
| ipv6\_address | An existing IPv6 address to use (the actual IP address value) | `string` | `null` | 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 |
| private\_key | Content of the private SSL key. Required if `ssl` is `true` and `ssl_certificates` is empty. | `string` | `null` | 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 |
| 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

| Name | Description |
|------|-------------|
| external\_ip | The external IPv4 assigned to the global fowarding rule. |
| https\_proxy | The HTTPS proxy used by this module. |
| url\_map | The default URL map used by this module. |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

* [`google_compute_global_forwarding_rule.https`](https://www.terraform.io/docs/providers/google/r/compute_global_forwarding_rule.html): The global HTTPS forwarding rule created when `ssl` is `true`.
* [`google_compute_target_https_proxy.default`](https://www.terraform.io/docs/providers/google/r/compute_target_https_proxy.html): The HTTPS proxy resource that binds the url map. Created when input `ssl` is `true`.
* [`google_compute_ssl_certificate.default`](https://www.terraform.io/docs/providers/google/r/compute_ssl_certificate.html): The certificate resource created when input `ssl` is `true` and `managed_ssl_certificate_domains` not specified.
* [`google_compute_managed_ssl_certificate.default`](https://www.terraform.io/docs/providers/google/r/compute_managed_ssl_certificate.html): The Google-managed certificate resource created when input `ssl` is `true` and `managed_ssl_certificate_domains` is specified.
* [`google_compute_url_map.default`](https://www.terraform.io/docs/providers/google/r/compute_url_map.html): The default URL map resource when input `url_map` is not provided.
* [`google_compute_backend_service.default.*`](https://www.terraform.io/docs/providers/google/r/compute_backend_service.html): The backend services created for each of the `backend_params` elements.
7 changes: 7 additions & 0 deletions gcp/compute_engine/cloudrun_serverless_neg_https_lb/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
locals {
address = var.create_address ? join("", google_compute_global_address.default.*.address) : var.address
ipv6_address = var.create_ipv6_address ? join("", google_compute_global_address.default_ipv6.*.address) : var.ipv6_address

url_map = var.create_url_map ? join("", google_compute_url_map.default.*.self_link) : var.url_map
create_http_forward = var.http_forward || var.https_redirect
}
167 changes: 167 additions & 0 deletions gcp/compute_engine/cloudrun_serverless_neg_https_lb/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
resource google_compute_region_network_endpoint_group serverless_neg {
name = var.serverless_neg_name
network_endpoint_type = "SERVERLESS"
project = var.project
region = var.region
cloud_run {
service = var.cloudrun_service_name
}
}

### IPv4 block ###
resource google_compute_global_forwarding_rule http {
count = local.create_http_forward ? 1 : 0
project = var.project
name = var.name
target = google_compute_target_http_proxy.default[0].self_link
ip_address = local.address
port_range = "80"
}

resource google_compute_global_forwarding_rule https {
count = var.ssl ? 1 : 0
project = var.project
name = "${var.name}-https"
target = google_compute_target_https_proxy.default[0].self_link
ip_address = local.address
port_range = "443"
load_balancing_scheme = var.load_balancing_scheme
}

resource google_compute_global_address default {
count = var.create_address ? 1 : 0
project = var.project
name = "${var.name}-address"
ip_version = "IPV4"
}

### IPv6 block ###
resource google_compute_global_forwarding_rule http_ipv6 {
count = (var.enable_ipv6 && local.create_http_forward) ? 1 : 0
project = var.project
name = "${var.name}-ipv6-http"
target = google_compute_target_http_proxy.default[0].self_link
ip_address = local.ipv6_address
port_range = "80"
}

resource google_compute_global_forwarding_rule https_ipv6 {
count = (var.enable_ipv6 && var.ssl) ? 1 : 0
project = var.project
name = "${var.name}-ipv6-https"
target = google_compute_target_https_proxy.default[0].self_link
ip_address = local.ipv6_address
port_range = "443"
}

resource google_compute_global_address default_ipv6 {
count = (var.enable_ipv6 && var.create_ipv6_address) ? 1 : 0
project = var.project
name = "${var.name}-ipv6-address"
ip_version = "IPV6"
}
### IPv6 block ###

# HTTP proxy when http forwarding is true
resource google_compute_target_http_proxy default {
count = local.create_http_forward ? 1 : 0
project = var.project
name = "${var.name}-http-proxy"
url_map = var.https_redirect == false ? local.url_map : join("", google_compute_url_map.https_redirect.*.self_link)
}

# HTTPS proxy when ssl is true
resource google_compute_target_https_proxy default {
count = var.ssl ? 1 : 0
project = var.project
name = "${var.name}-https-proxy"
url_map = local.url_map

ssl_certificates = compact(concat(var.ssl_certificates, google_compute_ssl_certificate.default.*.self_link, google_compute_managed_ssl_certificate.default.*.self_link, ), )
ssl_policy = var.ssl_policy
quic_override = var.quic ? "ENABLE" : null
}

resource google_compute_ssl_certificate default {
count = var.ssl && length(var.managed_ssl_certificate_domains) == 0 && !var.use_ssl_certificates ? 1 : 0
project = var.project
name_prefix = "${var.name}-certificate-"
private_key = var.private_key
certificate = var.certificate

lifecycle {
create_before_destroy = true
}
}

resource random_id certificate {
count = var.random_certificate_suffix == true ? 1 : 0
byte_length = 4
prefix = "${var.name}-cert-"

keepers = {
domains = join(",", var.managed_ssl_certificate_domains)
}
}

resource google_compute_managed_ssl_certificate default {
project = var.project
count = var.ssl && length(var.managed_ssl_certificate_domains) > 0 && !var.use_ssl_certificates ? 1 : 0
name = var.random_certificate_suffix == true ? random_id.certificate[0].hex : "${var.name}-cert"

lifecycle {
create_before_destroy = true
}

managed {
domains = var.managed_ssl_certificate_domains
}
}

resource google_compute_url_map default {
count = var.create_url_map ? 1 : 0
project = var.project
name = "${var.name}-url-map"
default_service = google_compute_backend_service.default[keys(var.backends)[0]].self_link
}

resource google_compute_url_map https_redirect {
count = var.https_redirect ? 1 : 0
project = var.project
name = "${var.name}-https-redirect"
default_url_redirect {
https_redirect = true
redirect_response_code = "MOVED_PERMANENTLY_DEFAULT"
strip_query = false
}
}

resource google_compute_backend_service default {
for_each = var.backends

project = var.project
name = "${var.name}-backend-${each.key}"

description = lookup(each.value, "description")
load_balancing_scheme = lookup(each.value, "load_balancing_scheme")
protocol = lookup(each.value, "protocol")
security_policy = lookup(each.value, "security_policy")

dynamic backend {
for_each = toset(each.value["groups"])
content {
description = lookup(backend.value, "description", null)
group = lookup(backend.value, "group")
}
}

dynamic log_config {
for_each = lookup(lookup(each.value, "log_config", {}), "enable", true) ? [1] : []
content {
enable = lookup(lookup(each.value, "log_config", {}), "enable", true)
sample_rate = lookup(lookup(each.value, "log_config", {}), "sample_rate", "1.0")
}
}

depends_on = [google_compute_region_network_endpoint_group.serverless_neg]
}
13 changes: 13 additions & 0 deletions gcp/compute_engine/cloudrun_serverless_neg_https_lb/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
output "load-balancer-ip" {
value = local.address
}

output "https_proxy" {
description = "The HTTPS proxy used by this module."
value = google_compute_target_https_proxy.default[*].self_link
}

output "url_map" {
description = "The default URL map used by this module."
value = google_compute_url_map.default[*].self_link
}
10 changes: 10 additions & 0 deletions gcp/compute_engine/cloudrun_serverless_neg_https_lb/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.1.0"
required_providers {

google = {
source = "hashicorp/google"
version = ">= 3.53, < 5.0"
}
}
}
Loading