Added multi-region API Gateway recipe, that was removed by accident (#3128)
This commit is contained in:
@@ -1,6 +1,16 @@
|
||||
# API Gateway
|
||||
This module allows creating an API with its associated API config and API gateway. It also allows you grant IAM roles on the created resources.
|
||||
|
||||
<!-- BEGIN TOC -->
|
||||
- [Examples](#examples)
|
||||
- [Basic example](#basic-example)
|
||||
- [Use existing service account](#use-existing-service-account)
|
||||
- [Create service account](#create-service-account)
|
||||
- [Recipes](#recipes)
|
||||
- [Variables](#variables)
|
||||
- [Outputs](#outputs)
|
||||
<!-- END TOC -->
|
||||
|
||||
# Examples
|
||||
|
||||
## Basic example
|
||||
@@ -57,6 +67,9 @@ module "gateway" {
|
||||
# tftest modules=1 resources=11 inventory=create-sa.yaml
|
||||
```
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Recipes
|
||||
|
||||
- [Multi-region deployment for API Gateway](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/blob/master/modules/api-gateway/recipe-multi-region)
|
||||
|
||||
## Variables
|
||||
|
||||
@@ -85,5 +98,4 @@ module "gateway" {
|
||||
| [service_account](outputs.tf#L94) | Service account resource. | |
|
||||
| [service_account_email](outputs.tf#L99) | The service account for creating API configs. | |
|
||||
| [service_account_iam_email](outputs.tf#L104) | The service account for creating API configs. | |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
|
||||
47
modules/api-gateway/recipe-multi-region/README.md
Normal file
47
modules/api-gateway/recipe-multi-region/README.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Multi-region deployment for API Gateway
|
||||
|
||||
This recipe shows you how to configure an HTTP(S) load balancer to enable multi-region deployments for API Gateway. For more details on how this set up work have a look at the article [here](https://cloud.google.com/api-gateway/docs/multi-region-deployment).
|
||||
|
||||
The diagram below depicts the architecture that this blueprint sets up.
|
||||
|
||||

|
||||
|
||||
Once deployed do the following to see that it works:
|
||||
|
||||
1. Copy the IP address returned as output
|
||||
|
||||
2. Execute the following command:
|
||||
|
||||
curl -k -v <https://example.com/hello> --resolve example.com:443:<IP_ADDRESS>
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [project_id](variables.tf#L27) | Identifier of the project. | <code>string</code> | ✓ | |
|
||||
| [regions](variables.tf#L32) | List of regions to deploy the proxy in. | <code>list(string)</code> | ✓ | |
|
||||
| [_testing](variables.tf#L17) | Populate this variable to avoid triggering the data source. | <code title="object({ name = string number = number services_enabled = optional(list(string), []) })">object({…})</code> | | <code>null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [address](outputs.tf#L17) | LB IP address. | |
|
||||
<!-- END TFDOC -->
|
||||
## Test
|
||||
|
||||
```hcl
|
||||
module "test" {
|
||||
source = "./fabric/modules/api-gateway/recipe-multi-region"
|
||||
project_id = "project-1"
|
||||
regions = [
|
||||
"europe-west1",
|
||||
"us-central1"
|
||||
]
|
||||
_testing = {
|
||||
name = "project-1"
|
||||
number = 1234567890
|
||||
}
|
||||
}
|
||||
# tftest modules=8 resources=43
|
||||
```
|
||||
BIN
modules/api-gateway/recipe-multi-region/diagram.png
Normal file
BIN
modules/api-gateway/recipe-multi-region/diagram.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
@@ -0,0 +1,7 @@
|
||||
const functions = require('@google-cloud/functions-framework');
|
||||
|
||||
// Register an HTTP function with the Functions Framework that will be executed
|
||||
// when you make an HTTP request to the deployed function's endpoint.
|
||||
functions.http('helloGET', (req, res) => {
|
||||
res.send('Hello World!');
|
||||
});
|
||||
1439
modules/api-gateway/recipe-multi-region/function/package-lock.json
generated
Normal file
1439
modules/api-gateway/recipe-multi-region/function/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "function",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=22.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google-cloud/functions-framework": "^4.0.0"
|
||||
}
|
||||
}
|
||||
152
modules/api-gateway/recipe-multi-region/main.tf
Normal file
152
modules/api-gateway/recipe-multi-region/main.tf
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* Copyright 2025 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 {
|
||||
api_id_prefix = "api"
|
||||
function_name_prefix = "cf-hello"
|
||||
specs = { for region in var.regions : region =>
|
||||
templatefile("${path.module}/spec.yaml", {
|
||||
api_id = "${local.api_id_prefix}-${region}"
|
||||
function_name = "${local.function_name_prefix}-${region}"
|
||||
region = region
|
||||
project_id = var.project_id
|
||||
})
|
||||
}
|
||||
backends = [
|
||||
for region in var.regions : {
|
||||
backend = google_compute_region_network_endpoint_group.serverless-negs[region].id
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
resource "tls_private_key" "default" {
|
||||
algorithm = "RSA"
|
||||
rsa_bits = 2048
|
||||
}
|
||||
|
||||
resource "tls_self_signed_cert" "default" {
|
||||
private_key_pem = tls_private_key.default.private_key_pem
|
||||
subject {
|
||||
common_name = "example.com"
|
||||
organization = "ACME Examples, Inc"
|
||||
}
|
||||
validity_period_hours = 720
|
||||
allowed_uses = [
|
||||
"key_encipherment",
|
||||
"digital_signature",
|
||||
"server_auth",
|
||||
]
|
||||
}
|
||||
|
||||
module "project" {
|
||||
source = "../../../modules/project"
|
||||
name = var.project_id
|
||||
project_reuse = {
|
||||
use_data_source = var._testing == null
|
||||
project_attributes = var._testing
|
||||
}
|
||||
services = [
|
||||
"apigateway.googleapis.com",
|
||||
"cloudbuild.googleapis.com",
|
||||
"cloudfunctions.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"run.googleapis.com",
|
||||
"servicemanagement.googleapis.com",
|
||||
"servicecontrol.googleapis.com"
|
||||
]
|
||||
}
|
||||
|
||||
module "sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = module.project.project_id
|
||||
name = "sa-api"
|
||||
}
|
||||
|
||||
|
||||
module "functions" {
|
||||
for_each = toset(var.regions)
|
||||
source = "../../../modules/cloud-function-v2"
|
||||
project_id = module.project.project_id
|
||||
name = "${local.function_name_prefix}-${each.value}"
|
||||
bucket_name = "bkt-${module.project.project_id}-${each.value}"
|
||||
region = each.value
|
||||
ingress_settings = "ALLOW_ALL"
|
||||
bucket_config = {
|
||||
location = null
|
||||
lifecycle_delete_age_days = 1
|
||||
}
|
||||
bundle_config = {
|
||||
path = "${path.module}/function"
|
||||
}
|
||||
function_config = {
|
||||
entry_point = "helloGET"
|
||||
runtime = "nodejs22"
|
||||
}
|
||||
service_account_create = true
|
||||
iam = {
|
||||
"roles/run.invoker" = [module.sa.iam_email]
|
||||
}
|
||||
}
|
||||
|
||||
module "gateways" {
|
||||
for_each = toset(var.regions)
|
||||
source = "../../../modules/api-gateway"
|
||||
project_id = module.project.project_id
|
||||
api_id = "${local.api_id_prefix}-${each.value}"
|
||||
region = each.value
|
||||
spec = local.specs[each.value]
|
||||
service_account_email = module.sa.email
|
||||
}
|
||||
|
||||
module "glb" {
|
||||
source = "../../../modules/net-lb-app-ext"
|
||||
project_id = module.project.project_id
|
||||
name = "glb"
|
||||
use_classic_version = false
|
||||
protocol = "HTTPS"
|
||||
backend_service_configs = {
|
||||
default = {
|
||||
backends = local.backends
|
||||
health_checks = []
|
||||
port_name = ""
|
||||
}
|
||||
}
|
||||
ssl_certificates = {
|
||||
create_configs = {
|
||||
default = {
|
||||
certificate = tls_self_signed_cert.default.cert_pem
|
||||
private_key = tls_private_key.default.private_key_pem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_region_network_endpoint_group" "serverless-negs" {
|
||||
for_each = toset(var.regions)
|
||||
provider = google-beta
|
||||
name = "serverless-neg-${module.gateways[each.value].gateway_id}"
|
||||
project = module.project.project_id
|
||||
network_endpoint_type = "SERVERLESS"
|
||||
region = each.value
|
||||
serverless_deployment {
|
||||
platform = "apigateway.googleapis.com"
|
||||
resource = module.gateways[each.value].gateway_id
|
||||
url_mask = ""
|
||||
}
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
}
|
||||
}
|
||||
20
modules/api-gateway/recipe-multi-region/outputs.tf
Normal file
20
modules/api-gateway/recipe-multi-region/outputs.tf
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright 2025 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 "address" {
|
||||
description = "LB IP address."
|
||||
value = module.glb.address[""]
|
||||
}
|
||||
35
modules/api-gateway/recipe-multi-region/spec.yaml
Normal file
35
modules/api-gateway/recipe-multi-region/spec.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
# Copyright 2025 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.
|
||||
|
||||
swagger: '2.0'
|
||||
info:
|
||||
title: ${api_id} Sample API
|
||||
description: Sample API on API Gateway with a Google Cloud Functions backend
|
||||
version: 1.0.0
|
||||
schemes:
|
||||
- https
|
||||
produces:
|
||||
- application/json
|
||||
paths:
|
||||
/hello:
|
||||
get:
|
||||
summary: Greet a user
|
||||
operationId: hello
|
||||
x-google-backend:
|
||||
address: https://${region}-${project_id}.cloudfunctions.net/${function_name}
|
||||
responses:
|
||||
'200':
|
||||
description: A successful response
|
||||
schema:
|
||||
type: string
|
||||
35
modules/api-gateway/recipe-multi-region/variables.tf
Normal file
35
modules/api-gateway/recipe-multi-region/variables.tf
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright 2025 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 "_testing" {
|
||||
description = "Populate this variable to avoid triggering the data source."
|
||||
type = object({
|
||||
name = string
|
||||
number = number
|
||||
services_enabled = optional(list(string), [])
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Identifier of the project."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "regions" {
|
||||
description = "List of regions to deploy the proxy in."
|
||||
type = list(string)
|
||||
}
|
||||
Reference in New Issue
Block a user