Skip to content
Merged
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
21 changes: 21 additions & 0 deletions build/int.cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,27 @@ steps:
- verify backend-with-iap
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestLbBackendServiceIap --stage teardown --verbose']
# backend-with-psc-negs example
- id: init backend-with-psc-negs
waitFor:
- teardown backend-with-iap
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestLbBackendServiceWithPscNeg --stage init --verbose']
- id: apply backend-with-psc-negs
waitFor:
- init backend-with-psc-negs
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestLbBackendServiceWithPscNeg --stage apply --verbose']
- id: verify backend-with-psc-negs
waitFor:
- apply backend-with-psc-negs
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestLbBackendServiceWithPscNeg --stage verify --verbose']
- id: teardown backend-with-psc-negs
waitFor:
- verify backend-with-psc-negs
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestLbBackendServiceWithPscNeg --stage teardown --verbose']
tags:
- 'ci'
- 'integration'
Expand Down
149 changes: 149 additions & 0 deletions examples/backend-with-psc-negs/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/**
* 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.
*/


module "producer-network" {
source = "terraform-google-modules/network/google//modules/vpc"
version = "~> 10.0.0"
project_id = var.project_id
network_name = "producer-network"
auto_create_subnetworks = false
}

module "producer-subnet" {
source = "terraform-google-modules/network/google//modules/subnets"
version = "~> 10.0.0"

subnets = [
{
subnet_name = "producer-subnet-a"
subnet_ip = "10.1.2.0/24"
subnet_region = "us-central1"
},
{
subnet_name = "producer-subnet-b"
subnet_ip = "10.1.3.0/24"
subnet_region = "us-central1"
purpose = "PRIVATE_SERVICE_CONNECT"
}
]

network_name = module.producer-network.network_name
project_id = var.project_id
depends_on = [module.producer-network]
}

module "gce-ilb" {
source = "GoogleCloudPlatform/lb-internal/google"
version = "~> 6.0"
project = var.project_id
region = "us-central1"
name = "group2-ilb"
ports = ["80"]

source_tags = ["allow-group1"]
target_tags = ["allow-group2"]

global_access = true

network = module.producer-network.network_name
subnetwork = module.producer-subnet.subnets["us-central1/producer-subnet-a"].name

health_check = {
type = "http"
check_interval_sec = 1
healthy_threshold = 4
timeout_sec = 1
unhealthy_threshold = 5
response = ""
proxy_header = "NONE"
port = 80
port_name = "health-check-port"
request = ""
request_path = "/"
host = "1.2.3.4"
enable_log = false
}

backends = []
depends_on = [module.producer-subnet]

}

resource "google_compute_service_attachment" "minimal_sa" {
project = var.project_id
name = "sa"
region = "us-central1"
enable_proxy_protocol = false
connection_preference = "ACCEPT_AUTOMATIC"
nat_subnets = [module.producer-subnet.subnets["us-central1/producer-subnet-b"].name]
target_service = module.gce-ilb.forwarding_rule

depends_on = [module.gce-ilb]
}


module "psc-neg-network" {
source = "terraform-google-modules/network/google//modules/vpc"
version = "~> 10.0.0"
project_id = var.project_id
network_name = "psc-neg-network"
auto_create_subnetworks = false
}

module "psc-neg-subnet" {
source = "terraform-google-modules/network/google//modules/subnets"
version = "~> 10.0.0"

subnets = [
{
subnet_name = "psc-neg-subnet-a"
subnet_ip = "10.1.2.0/24"
subnet_region = "us-central1"
}
]

network_name = module.psc-neg-network.network_name
project_id = var.project_id
depends_on = [module.psc-neg-network]
}

module "lb-backend-psc-neg" {
source = "terraform-google-modules/lb-http/google//modules/backend"
version = "~> 12.0"

project_id = var.project_id
name = "backend-with-psc-negs"
psc_neg_backends = [{
name = "test-psc-1"
region = "us-central1"
psc_target_service = google_compute_service_attachment.minimal_sa.self_link
network = module.psc-neg-network.network_name
subnetwork = module.psc-neg-subnet.subnets["us-central1/psc-neg-subnet-a"].name
producer_port = "80"
}]

depends_on = [google_compute_service_attachment.minimal_sa]
}

module "lb-frontend" {
source = "terraform-google-modules/lb-http/google//modules/frontend"
version = "~> 12.0"

project_id = var.project_id
name = "global-lb-fe-psc-neg"
url_map_input = module.lb-backend-psc-neg.backend_service_info
}
26 changes: 26 additions & 0 deletions examples/backend-with-psc-negs/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* 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 "project_id" {
value = var.project_id
description = "Project ID of the service"
}

output "psc_negs" {
value = module.lb-backend-psc-neg.psc_negs
description = "Psc Neg created for this load balancer"
}
19 changes: 19 additions & 0 deletions examples/backend-with-psc-negs/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* 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 "project_id" {
type = string
}
4 changes: 3 additions & 1 deletion metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ spec:
examples:
- name: backend-with-iap
location: examples/backend-with-iap
- name: backend-with-psc-negs
location: examples/backend-with-psc-negs
- name: cdn-policy
location: examples/cdn-policy
- name: certificate-map
Expand Down Expand Up @@ -338,13 +340,13 @@ spec:
roles:
- level: Project
roles:
- roles/run.admin
- roles/iam.serviceAccountUser
- roles/certificatemanager.owner
- roles/vpcaccess.admin
- roles/iam.serviceAccountAdmin
- roles/storage.admin
- roles/compute.admin
- roles/run.admin
services:
- certificatemanager.googleapis.com
- cloudresourcemanager.googleapis.com
Expand Down
2 changes: 2 additions & 0 deletions modules/backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ This module creates `google_compute_backend_service` resource and its dependenci
| port\_name | Name of backend port. The same name should appear in the instance groups referenced by this service. Required when the load balancing scheme is EXTERNAL. | `string` | `"http"` | no |
| project\_id | The project to deploy to, if not set the default provider project is used. | `string` | n/a | yes |
| protocol | The protocol this BackendService uses to communicate with backends. | `string` | `"HTTP"` | no |
| psc\_neg\_backends | The list of Private Service Connect backends which serve the traffic. | <pre>list(object({<br> name = string<br> region = string<br> psc_target_service = string<br> network = string<br> subnetwork = string<br> producer_port = optional(string)<br> }))</pre> | `[]` | no |
| security\_policy | The resource URL for the security policy to associate with the backend service | `string` | `null` | no |
| serverless\_neg\_backends | The list of serverless backend which serves the traffic. | <pre>list(object({<br> region = string<br> type = string // cloud-run, cloud-function, and app-engine<br> service_name = string<br> service_version = optional(string)<br> }))</pre> | `[]` | no |
| session\_affinity | Type of session affinity to use. Possible values are: NONE, CLIENT\_IP, CLIENT\_IP\_PORT\_PROTO, CLIENT\_IP\_PROTO, GENERATED\_COOKIE, HEADER\_FIELD, HTTP\_COOKIE, STRONG\_COOKIE\_AFFINITY. | `string` | `null` | no |
Expand All @@ -44,5 +45,6 @@ This module creates `google_compute_backend_service` resource and its dependenci
|------|-------------|
| apphub\_service\_uri | Service URI in CAIS style to be used by Apphub. |
| backend\_service\_info | Host, path and backend service mapping |
| psc\_negs | Private Service Connect backends that were created for this backend service |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
31 changes: 31 additions & 0 deletions modules/backend/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
locals {
is_backend_bucket = var.backend_bucket_name != null && var.backend_bucket_name != ""
serverless_neg_backends = local.is_backend_bucket ? [] : var.serverless_neg_backends
psc_neg_backends = local.is_backend_bucket ? [] : var.psc_neg_backends
iap_access_members = var.iap_config.enable ? coalesce(var.iap_config.iap_members, []) : []
}

Expand Down Expand Up @@ -72,6 +73,13 @@ resource "google_compute_backend_service" "default" {
}
}

dynamic "backend" {
for_each = toset(var.psc_neg_backends)
content {
group = google_compute_region_network_endpoint_group.psc_negs[backend.value.name].id
}
}

dynamic "log_config" {
for_each = var.log_config.enable ? [1] : []
content {
Expand Down Expand Up @@ -200,6 +208,29 @@ resource "google_compute_region_network_endpoint_group" "serverless_negs" {
}
}

resource "google_compute_region_network_endpoint_group" "psc_negs" {
for_each = { for psc_neg_backend in local.psc_neg_backends :
psc_neg_backend.name => psc_neg_backend
}

provider = google-beta
project = var.project_id
name = each.key
network_endpoint_type = "PRIVATE_SERVICE_CONNECT"
region = each.value.region
psc_target_service = each.value.psc_target_service
network = each.value.network
subnetwork = each.value.subnetwork

psc_data {
producer_port = try(each.value.producer_port, null)
}

lifecycle {
create_before_destroy = true
}
}

resource "google_compute_health_check" "default" {
provider = google-beta
count = var.health_check != null ? 1 : 0
Expand Down
20 changes: 18 additions & 2 deletions modules/backend/metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ spec:
examples:
- name: backend-with-iap
location: examples/backend-with-iap
- name: backend-with-psc-negs
location: examples/backend-with-psc-negs
- name: cdn-policy
location: examples/cdn-policy
- name: certificate-map
Expand Down Expand Up @@ -180,6 +182,18 @@ spec:
version: ">= 0.13"
spec:
outputExpr: "{\"region\": location, \"service_name\": service_name, \"type\": \"cloud-run\", \"service_version\": \"\"}"
- name: psc_neg_backends
description: The list of Private Service Connect backends which serve the traffic.
varType: |-
list(object({
name = string
region = string
psc_target_service = string
network = string
subnetwork = string
producer_port = optional(string)
}))
defaultValue: []
- name: backend_bucket_name
description: The name of GCS bucket which serves the traffic.
varType: string
Expand Down Expand Up @@ -330,17 +344,19 @@ spec:
- backend_service: string
host: string
path: string
- name: psc_negs
description: Private Service Connect backends that were created for this backend service
requirements:
roles:
- level: Project
roles:
- roles/iam.serviceAccountUser
- roles/iam.serviceAccountAdmin
- roles/compute.admin
- roles/storage.admin
- roles/run.admin
- roles/compute.networkAdmin
- roles/iap.admin
- roles/iam.serviceAccountUser
- roles/iam.serviceAccountAdmin
services:
- cloudresourcemanager.googleapis.com
- compute.googleapis.com
Expand Down
7 changes: 7 additions & 0 deletions modules/backend/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,10 @@ output "apphub_service_uri" {
)
description = "Service URI in CAIS style to be used by Apphub."
}

output "psc_negs" {
value = !local.is_backend_bucket ? [
for neg_key, neg in google_compute_region_network_endpoint_group.psc_negs : neg.self_link
] : []
description = "Private Service Connect backends that were created for this backend service"
}
Loading