Skip to content

Commit

Permalink
feat: Add creating serverless negs inside module/serverless-negs itse…
Browse files Browse the repository at this point in the history
…lf (#438)
q2w authored Aug 22, 2024
1 parent 16dd047 commit ec0b73b
Showing 15 changed files with 491 additions and 13 deletions.
52 changes: 52 additions & 0 deletions autogen/main.tf.tmpl
Original file line number Diff line number Diff line change
@@ -239,6 +239,15 @@ resource "google_compute_backend_service" "default" {
}
}

{% if serverless %}
dynamic "backend" {
for_each = toset(each.value["serverless_neg_backends"])
content {
group = google_compute_region_network_endpoint_group.serverless_negs["neg-${each.key}-${backend.value.region}"].id
}
}

{% endif %}
dynamic "log_config" {
for_each = lookup(lookup(each.value, "log_config", {}), "enable", true) ? [1] : []
content {
@@ -339,6 +348,49 @@ resource "google_compute_backend_service" "default" {
}
{% endif %}
}
{% if serverless %}

resource "google_compute_region_network_endpoint_group" "serverless_negs" {
for_each = merge([
for backend_index, backend in var.backends : {
for serverless_neg_backend in backend.serverless_neg_backends :
"neg-${backend_index}-${serverless_neg_backend.region}" => serverless_neg_backend
}
]...)

provider = google-beta
project = var.project
name = "${each.key}"
network_endpoint_type = "SERVERLESS"
region = each.value.region

dynamic "cloud_run" {
for_each = each.value.type == "cloud-run" ? [1] : []
content {
service = each.value.service.name
}
}

dynamic "cloud_function" {
for_each = each.value.type == "cloud-function" ? [1] : []
content {
function = each.value.service.name
}
}

dynamic "app_engine" {
for_each = each.value.type == "app-engine" ? [1] : []
content {
service = each.value.service.name
version = each.value.service.version
}
}

lifecycle {
create_before_destroy = true
}
}
{% endif %}

{% if not serverless %}{# doesn't apply to serverless NEGs #}
resource "google_compute_health_check" "default" {
23 changes: 23 additions & 0 deletions autogen/variables.tf.tmpl
Original file line number Diff line number Diff line change
@@ -83,6 +83,18 @@ variable "target_service_accounts" {

variable "backends" {
description = "Map backend indices to list of backend maps."
{% if serverless %}
validation {
condition = alltrue([
for backend_key, backend_value in var.backends :
alltrue([
for neg_backend in backend_value.serverless_neg_backends :
contains(["cloud-run", "cloud-function", "app-engine"], neg_backend.type)
])
])
error_message = "serverless_neg_backend type should be either 'cloud-run' or 'cloud-function' or 'app-engine'."
}
{% endif %}
type = map(object({
{% if not serverless %}{# not necessary for serverless as default port_name=http, protocol=HTTP #}
port = optional(number)
@@ -148,6 +160,17 @@ variable "backends" {
max_utilization = optional(number)
{% endif %}
}))
{% if serverless %}

// serverless_neg_backends is mutually exclusive to groups.There can only be one serverless neg per region
// with one of cloud-run, cloud-functions and app-engine as service.
serverless_neg_backends = optional(list(object({
region = string,
type = string, // cloud-run, cloud-function and app-engine
service = object({ name : string, version : optional(string) })
})), [])

{% endif %}
iap_config = object({
enable = bool
oauth2_client_id = optional(string)
23 changes: 22 additions & 1 deletion build/int.cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

timeout: 5400s
timeout: 6120s
steps:
- id: swap-module-refs
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
@@ -24,6 +24,27 @@ steps:
- 'TF_VAR_org_id=$_ORG_ID'
- 'TF_VAR_folder_id=$_FOLDER_ID'
- 'TF_VAR_billing_account=$_BILLING_ACCOUNT'
# cloudrun implicit serverless negs
- id: init-all
waitFor:
- prepare
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run all --stage init --verbose']
- id: apply cloudrun-implicit
waitFor:
- init-all
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestCloudrunImplicit --stage apply --verbose']
- id: verify cloudrun-implicit
waitFor:
- apply cloudrun-implicit
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'sleep 720 && cft test run TestCloudrunImplicit --stage verify --verbose']
- id: teardown cloudrun-implicit
waitFor:
- verify cloudrun-implicit
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestCloudrunImplicit --stage teardown --verbose']
- id: create
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do create']
107 changes: 107 additions & 0 deletions examples/cloudrun-implicit-serverless-neg/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# HTTPS load balancer with Cloud Run

[![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/cloudrun-implicit-serverless-neg&page=shell&tutorial=README.md)

This example deploys a Cloud Run application and exposes it behind a Cloud HTTPS load balancer with
HTTP-to-HTTPS redirection (which creates a Serverless Network
Endpoint Group (NEG) implicitly). In the examples/cloudrun, the serverless neg is created explicitly.

You can tweak this example to enable other functionalities such as:

- serving static assets from Cloud CDN
- enabling a security profile via Cloud Armor
- run global endpoints by deploying Cloud Run service to multiple regions.

## Change to the example directory

```
[[ `basename $PWD` != cloudrun-implicit-serverless-neg ]] && cd examples/cloudrun-implicit-serverless-neg
```

## Install Terraform

1. Install Terraform if it is not already installed (visit
[terraform.io](https://terraform.io) for other distributions):

## 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)
```

## Option 1: Run on HTTP load balancer (unencrypted, not recommended)

This option provisions an HTTP forwarding rule (insecure) and is not recommended
for production use. It is provided since it provisions faster than the Option 2.

1. Initialize:

```
terraform init
```
1. Deploy the load balancer, replace `example.com` with your domain name.
```
terraform apply -var=project_id=$PROJECT \
-var=ssl=false -var=domain=null
```
1. It may take some time for the load balancer to provision. Visit the output
IP address of the load balancer.
## Option 2: Run on HTTPS load balancer (with HTTP-to-HTTPS redirect)
This options creates a Google-managed SSL certificate for your domain name,
sets it up on HTTPS forwarding rule and creates a HTTP forwarding rule to
redirect HTTP traffic to HTTPS.
1. Make sure you have a **domain name**. This is required since we provision a
Google-managed SSL certificate specifically for this domain name.
1. Initialize:
```
terraform init
```
1. Deploy the load balancer, replace `example.com` with your domain name.
```
terraform apply -var=project_id=$PROJECT \
-var=domain=example.com
```
1. After the deployment completes it outputs the IP address of the load balancer.
Update DNS records for your domain to point to this IP address.
1. It may take around half an hour for the SSL certificate to be provisioned
and the application to start serving traffic.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| project\_id | n/a | `string` | n/a | yes |
## Outputs
| Name | Description |
|------|-------------|
| load-balancer-ip | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
72 changes: 72 additions & 0 deletions examples/cloudrun-implicit-serverless-neg/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* 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.
*/

module "lb-http" {
source = "terraform-google-modules/lb-http/google//modules/serverless_negs"
version = "~> 10.0"

name = "tf-cr-lb-1"
project = var.project_id

ssl = false
https_redirect = false
labels = { "example-label" = "cloud-run-example" }

backends = {
default = {
description = null
groups = []
serverless_neg_backends = [{ region : "us-central1", type : "cloud-run", service : { name : google_cloud_run_service.default.name } }]
enable_cdn = false

iap_config = {
enable = false
}
log_config = {
enable = false
}
}
}
}

resource "google_cloud_run_service" "default" {
name = "example-1"
location = "us-central1"
project = var.project_id

template {
spec {
containers {
image = "gcr.io/cloudrun/hello"
}
}
}
metadata {
annotations = {
# For valid annotation values and descriptions, see
# https://cloud.google.com/sdk/gcloud/reference/run/deploy#--ingress
"run.googleapis.com/ingress" = "all"
}
}
}

resource "google_cloud_run_service_iam_member" "public-access" {
location = google_cloud_run_service.default.location
project = google_cloud_run_service.default.project
service = google_cloud_run_service.default.name
role = "roles/run.invoker"
member = "allUsers"
}
19 changes: 19 additions & 0 deletions examples/cloudrun-implicit-serverless-neg/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* 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.
*/

output "load-balancer-ip" {
value = module.lb-http.external_ip
}
20 changes: 20 additions & 0 deletions examples/cloudrun-implicit-serverless-neg/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* 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.
*/

variable "project_id" {
type = string
}

8 changes: 5 additions & 3 deletions metadata.yaml
Original file line number Diff line number Diff line change
@@ -42,6 +42,8 @@ spec:
location: examples/certificate-map
- name: cloudrun
location: examples/cloudrun
- name: cloudrun-implicit-serverless-neg
location: examples/cloudrun-implicit-serverless-neg
- name: cross-project-mig-backend
location: examples/cross-project-mig-backend
- name: dynamic-backend
@@ -322,11 +324,11 @@ spec:
roles:
- level: Project
roles:
- roles/owner
- roles/storage.admin
- roles/compute.xpnAdmin
- level: Project
roles:
- roles/compute.xpnAdmin
- roles/owner
- roles/storage.admin
services:
- cloudresourcemanager.googleapis.com
- storage-api.googleapis.com
Loading

0 comments on commit ec0b73b

Please sign in to comment.