diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index 08f66775..aa513346 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -158,6 +158,27 @@ steps: - verify internal-lb-http gce-mig name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', 'cft test run TestInternalLbGCEMIG --stage teardown --verbose'] + # Backend Service with IAP Enabled +- id: init backend-with-iap + waitFor: + - teardown internal-lb-http gce-mig + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestLbBackendServiceIap --stage init --verbose'] +- id: apply backend-with-iap + waitFor: + - init 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 apply --verbose'] +- id: verify backend-with-iap + waitFor: + - apply 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 verify --verbose'] +- id: teardown backend-with-iap + waitFor: + - 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'] tags: - 'ci' - 'integration' diff --git a/examples/backend-with-iap/main.tf b/examples/backend-with-iap/main.tf new file mode 100644 index 00000000..ce556beb --- /dev/null +++ b/examples/backend-with-iap/main.tf @@ -0,0 +1,36 @@ +/** + * 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 "lb-backend-iap" { + source = "terraform-google-modules/lb-http/google//modules/backend" + version = "~> 12.0" + + project_id = var.project_id + name = "backend-with-iap" + iap_config = { + enable = true + iap_members = ["user:test@test.test"] + } +} + +module "lb-frontend" { + source = "terraform-google-modules/lb-http/google//modules/frontend" + version = "~> 12.0" + + project_id = var.project_id + name = "global-lb-fe-bucket" + url_map_input = module.lb-backend-iap.backend_service_info +} diff --git a/examples/backend-with-iap/outputs.tf b/examples/backend-with-iap/outputs.tf new file mode 100644 index 00000000..ac843af5 --- /dev/null +++ b/examples/backend-with-iap/outputs.tf @@ -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 = module.lb-backend-iap.project_id + description = "Project ID of the service" +} + +output "service_name" { + value = module.lb-backend-iap.service_name + description = "Name of the created service" +} diff --git a/examples/backend-with-iap/variables.tf b/examples/backend-with-iap/variables.tf new file mode 100644 index 00000000..419e3a19 --- /dev/null +++ b/examples/backend-with-iap/variables.tf @@ -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 +} diff --git a/examples/lb-http-separate-frontend-and-backend/main.tf b/examples/lb-http-separate-frontend-and-backend/main.tf index 8ba29ca4..3a25f810 100644 --- a/examples/lb-http-separate-frontend-and-backend/main.tf +++ b/examples/lb-http-separate-frontend-and-backend/main.tf @@ -68,8 +68,9 @@ module "cloud-nat-group2" { } module "lb-http-backend" { - source = "terraform-google-modules/lb-http/google//modules/backend" - version = "~> 12.0" + source = "terraform-google-modules/lb-http/google//modules/backend" + version = "~> 12.0" + project_id = var.project_id name = "backend-lb" target_tags = [ diff --git a/metadata.display.yaml b/metadata.display.yaml index acb5c79d..8ea229ef 100644 --- a/metadata.display.yaml +++ b/metadata.display.yaml @@ -1,4 +1,4 @@ -# Copyright 2024 Google LLC +# 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. diff --git a/metadata.yaml b/metadata.yaml index 04497664..18e95d68 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -40,6 +40,8 @@ spec: - name: serverless_negs location: modules/serverless_negs examples: + - name: backend-with-iap + location: examples/backend-with-iap - name: cdn-policy location: examples/cdn-policy - name: certificate-map @@ -336,13 +338,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 diff --git a/modules/backend/README.md b/modules/backend/README.md index 3ffde877..34369fcc 100644 --- a/modules/backend/README.md +++ b/modules/backend/README.md @@ -22,7 +22,7 @@ This module creates `google_compute_backend_service` resource and its dependenci | groups | The list of backend instance group which serves the traffic. |
list(object({
group = string
description = optional(string)
balancing_mode = optional(string)
capacity_scaler = optional(number)
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)
})) | `[]` | no |
| health\_check | Input for creating HttpHealthCheck or HttpsHealthCheck resource for health checking this BackendService. A health check must be specified unless the backend service uses an internet or serverless NEG as a backend. | object({
host = optional(string, null)
request_path = optional(string, null)
request = optional(string, null)
response = optional(string, null)
port = optional(number, null)
port_name = optional(string, null)
proxy_header = optional(string, null)
port_specification = optional(string, null)
protocol = optional(string, null)
check_interval_sec = optional(number, 5)
timeout_sec = optional(number, 5)
healthy_threshold = optional(number, 2)
unhealthy_threshold = optional(number, 2)
logging = optional(bool, false)
}) | `null` | no |
| host\_path\_mappings | The list of host/path for which traffic could be sent to the backend service | list(object({
host = string
path = string
})) | [| no | -| iap\_config | Settings for enabling Cloud Identity Aware Proxy Structure. |
{
"host": "*",
"path": "/*"
}
]
object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
}) | {
"enable": false
} | no |
+| iap\_config | Settings for enabling Cloud Identity Aware Proxy and Users/SAs to be given IAP HttpResourceAccessor access to the service. | object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
iap_members = optional(list(string))
}) | {
"enable": false
} | no |
| load\_balancing\_scheme | Load balancing scheme type (EXTERNAL for classic external load balancer, EXTERNAL\_MANAGED for Envoy-based load balancer, INTERNAL\_MANAGED for internal load balancer and INTERNAL\_SELF\_MANAGED for traffic director) | `string` | `"EXTERNAL_MANAGED"` | no |
| locality\_lb\_policy | The load balancing algorithm used within the scope of the locality. | `string` | `null` | no |
| log\_config | This field denotes the logging options for the load balancer traffic served by this backend service. If logging is enabled, logs will be exported to Stackdriver. | object({
enable = bool
sample_rate = number
}) | {
"enable": true,
"sample_rate": 1
} | no |
@@ -44,5 +44,7 @@ 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 |
+| project\_id | Project ID of the service |
+| service\_name | Name of the created service |
diff --git a/modules/backend/main.tf b/modules/backend/main.tf
index 927ca8c4..5487fdc3 100644
--- a/modules/backend/main.tf
+++ b/modules/backend/main.tf
@@ -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
+ iap_access_members = var.iap_config.enable ? coalesce(var.iap_config.iap_members, []) : []
}
resource "google_compute_backend_service" "default" {
@@ -365,3 +366,12 @@ resource "google_compute_backend_bucket" "default" {
}
}
}
+
+resource "google_iap_web_backend_service_iam_member" "member" {
+ for_each = toset(local.iap_access_members)
+ project = google_compute_backend_service.default[0].project
+ web_backend_service = google_compute_backend_service.default[0].name
+ role = "roles/iap.httpsResourceAccessor"
+ member = each.value
+}
+
diff --git a/modules/backend/metadata.display.yaml b/modules/backend/metadata.display.yaml
index ce481043..8ec61619 100644
--- a/modules/backend/metadata.display.yaml
+++ b/modules/backend/metadata.display.yaml
@@ -1,4 +1,4 @@
-# Copyright 2024 Google LLC
+# 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.
@@ -31,6 +31,9 @@ spec:
affinity_cookie_ttl_sec:
name: affinity_cookie_ttl_sec
title: Affinity Cookie Ttl Sec
+ backend_bucket_name:
+ name: backend_bucket_name
+ title: Backend Bucket Name
cdn_policy:
name: cdn_policy
title: Cdn Policy
@@ -66,6 +69,9 @@ spec:
firewall_projects:
name: firewall_projects
title: Firewall Projects
+ firewall_source_ranges:
+ name: firewall_source_ranges
+ title: Firewall Source Ranges
groups:
name: groups
title: Groups
@@ -79,6 +85,12 @@ spec:
iap_config:
name: iap_config
title: Iap Config
+ properties:
+ iap_members:
+ name: iap_members
+ title: Iap Members
+ regexValidation: ^(?:allUsers|allAuthenticatedUsers)$|^((?:user|group|serviceAccount):(?:[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})|(?:domain:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,})|(?:projectOwner|projectEditor|projectViewer):[a-z][a-z0-9-]{0,28}[a-z0-9])$
+ validation: Must be allUsers, allAuthenticatedUsers, or a service account in the format serviceAccount:email@example.com. [More info](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iap_web_backend_service_iam#google_iap_web_backend_service_iam_member).
load_balancing_scheme:
name: load_balancing_scheme
title: Load Balancing Scheme
@@ -125,3 +137,6 @@ spec:
target_tags:
name: target_tags
title: Target Tags
+ timeout_sec:
+ name: timeout_sec
+ title: Timeout Sec
diff --git a/modules/backend/metadata.yaml b/modules/backend/metadata.yaml
index 7bb32df3..f0369f9f 100644
--- a/modules/backend/metadata.yaml
+++ b/modules/backend/metadata.yaml
@@ -32,6 +32,8 @@ spec:
description: {}
content:
examples:
+ - name: backend-with-iap
+ location: examples/backend-with-iap
- name: cdn-policy
location: examples/cdn-policy
- name: certificate-map
@@ -189,12 +191,13 @@ spec:
spec:
outputExpr: name
- name: iap_config
- description: Settings for enabling Cloud Identity Aware Proxy Structure.
+ description: Settings for enabling Cloud Identity Aware Proxy and Users/SAs to be given IAP HttpResourceAccessor access to the service.
varType: |-
object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
+ iap_members = optional(list(string))
})
defaultValue:
enable: false
@@ -327,20 +330,25 @@ spec:
- backend_service: string
host: string
path: string
+ - name: project_id
+ description: Project ID of the service
+ - name: service_name
+ description: Name of the created service
requirements:
roles:
- level: Project
roles:
- - roles/run.admin
- - roles/compute.networkAdmin
- - roles/iap.admin
- roles/iam.serviceAccountUser
- roles/iam.serviceAccountAdmin
- roles/compute.admin
- roles/storage.admin
+ - roles/run.admin
+ - roles/compute.networkAdmin
+ - roles/iap.admin
services:
- cloudresourcemanager.googleapis.com
- compute.googleapis.com
+ - iap.googleapis.com
- run.googleapis.com
- storage-api.googleapis.com
- vpcaccess.googleapis.com
diff --git a/modules/backend/outputs.tf b/modules/backend/outputs.tf
index a8dab938..d072070b 100644
--- a/modules/backend/outputs.tf
+++ b/modules/backend/outputs.tf
@@ -43,3 +43,13 @@ output "apphub_service_uri" {
)
description = "Service URI in CAIS style to be used by Apphub."
}
+
+output "project_id" {
+ value = var.project_id
+ description = "Project ID of the service"
+}
+
+output "service_name" {
+ value = var.name
+ description = "Name of the created service"
+}
diff --git a/modules/backend/variables.tf b/modules/backend/variables.tf
index 4203dd7d..f825bda1 100644
--- a/modules/backend/variables.tf
+++ b/modules/backend/variables.tf
@@ -154,11 +154,12 @@ variable "backend_bucket_name" {
}
variable "iap_config" {
- description = "Settings for enabling Cloud Identity Aware Proxy Structure."
+ description = "Settings for enabling Cloud Identity Aware Proxy and Users/SAs to be given IAP HttpResourceAccessor access to the service."
type = object({
enable = bool
oauth2_client_id = optional(string)
oauth2_client_secret = optional(string)
+ iap_members = optional(list(string))
})
default = { enable = false }
}
diff --git a/modules/dynamic_backends/metadata.display.yaml b/modules/dynamic_backends/metadata.display.yaml
index 8f5ed328..7b533863 100644
--- a/modules/dynamic_backends/metadata.display.yaml
+++ b/modules/dynamic_backends/metadata.display.yaml
@@ -1,4 +1,4 @@
-# Copyright 2024 Google LLC
+# 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.
diff --git a/modules/dynamic_backends/metadata.yaml b/modules/dynamic_backends/metadata.yaml
index 7c8c22b3..ba9a6da3 100644
--- a/modules/dynamic_backends/metadata.yaml
+++ b/modules/dynamic_backends/metadata.yaml
@@ -32,6 +32,8 @@ spec:
description: {}
content:
examples:
+ - name: backend-with-iap
+ location: examples/backend-with-iap
- name: cdn-policy
location: examples/cdn-policy
- name: certificate-map
@@ -328,13 +330,13 @@ spec:
roles:
- level: Project
roles:
+ - roles/vpcaccess.admin
+ - roles/iam.serviceAccountAdmin
- roles/storage.admin
- roles/compute.admin
- roles/run.admin
- roles/iam.serviceAccountUser
- roles/certificatemanager.owner
- - roles/vpcaccess.admin
- - roles/iam.serviceAccountAdmin
services:
- certificatemanager.googleapis.com
- cloudresourcemanager.googleapis.com
diff --git a/modules/frontend/metadata.display.yaml b/modules/frontend/metadata.display.yaml
index 20435325..cee668c1 100644
--- a/modules/frontend/metadata.display.yaml
+++ b/modules/frontend/metadata.display.yaml
@@ -1,4 +1,4 @@
-# Copyright 2024 Google LLC
+# 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.
@@ -67,6 +67,9 @@ spec:
https_redirect:
name: https_redirect
title: Https Redirect
+ internal_forwarding_rules_config:
+ name: internal_forwarding_rules_config
+ title: Internal Forwarding Rules Config
ipv6_address:
name: ipv6_address
title: Ipv6 Address
diff --git a/modules/frontend/metadata.yaml b/modules/frontend/metadata.yaml
index f80639ce..4ae47ec9 100644
--- a/modules/frontend/metadata.yaml
+++ b/modules/frontend/metadata.yaml
@@ -32,6 +32,8 @@ spec:
description: {}
content:
examples:
+ - name: backend-with-iap
+ location: examples/backend-with-iap
- name: cdn-policy
location: examples/cdn-policy
- name: certificate-map
@@ -244,11 +246,11 @@ spec:
roles:
- level: Project
roles:
- - roles/compute.admin
- roles/storage.admin
- roles/iap.admin
- roles/certificatemanager.owner
- roles/iam.serviceAccountUser
+ - roles/compute.admin
services:
- certificatemanager.googleapis.com
- compute.googleapis.com
diff --git a/modules/serverless_negs/metadata.display.yaml b/modules/serverless_negs/metadata.display.yaml
index 01ad3ef9..6a6b669b 100644
--- a/modules/serverless_negs/metadata.display.yaml
+++ b/modules/serverless_negs/metadata.display.yaml
@@ -1,4 +1,4 @@
-# Copyright 2024 Google LLC
+# 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.
diff --git a/modules/serverless_negs/metadata.yaml b/modules/serverless_negs/metadata.yaml
index 6cffd289..fae7288a 100644
--- a/modules/serverless_negs/metadata.yaml
+++ b/modules/serverless_negs/metadata.yaml
@@ -32,6 +32,8 @@ spec:
description: {}
content:
examples:
+ - name: backend-with-iap
+ location: examples/backend-with-iap
- name: cdn-policy
location: examples/cdn-policy
- name: certificate-map
@@ -292,13 +294,13 @@ spec:
roles:
- level: Project
roles:
+ - roles/iam.serviceAccountUser
+ - roles/certificatemanager.owner
- roles/vpcaccess.admin
- roles/iam.serviceAccountAdmin
- roles/storage.admin
- roles/compute.admin
- roles/run.admin
- - roles/iam.serviceAccountUser
- - roles/certificatemanager.owner
services:
- certificatemanager.googleapis.com
- cloudresourcemanager.googleapis.com
diff --git a/test/integration/backend-with-iap/backend_with_iap_test.go b/test/integration/backend-with-iap/backend_with_iap_test.go
new file mode 100644
index 00000000..bc065609
--- /dev/null
+++ b/test/integration/backend-with-iap/backend_with_iap_test.go
@@ -0,0 +1,42 @@
+// 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.
+
+package backend_with_iap
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft"
+ "github.com/stretchr/testify/assert"
+ "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud"
+)
+
+func TestLbBackendServiceIap(t *testing.T) {
+ backendServiceWithIAP := tft.NewTFBlueprintTest(t)
+
+ backendServiceWithIAP.DefineVerify(func(assert *assert.Assertions) {
+
+ projectID := backendServiceWithIAP.GetTFSetupStringOutput("project_id")
+ serviceName := backendServiceWithIAP.GetStringOutput("service_name")
+
+ backendServiceDescribeCmd := gcloud.Run(t, "compute backend-services describe", gcloud.WithCommonArgs([]string{serviceName, "--project", projectID, "--global", "--format", "json"}))
+
+ //verify IAP is enabled in backend-services
+ iapConfig := backendServiceDescribeCmd.Get("iap").Map()
+ assert.Equal("true", iapConfig["enabled"].String(), fmt.Sprintf("IAP should be enabled"))
+ })
+ backendServiceWithIAP.Test()
+}
+
diff --git a/test/setup/iam.tf b/test/setup/iam.tf
index d65b85cb..7a379c5d 100644
--- a/test/setup/iam.tf
+++ b/test/setup/iam.tf
@@ -32,7 +32,8 @@ locals {
"roles/compute.networkAdmin",
"roles/iap.admin",
"roles/iam.serviceAccountUser",
- "roles/iam.serviceAccountAdmin"
+ "roles/iam.serviceAccountAdmin",
+ "roles/iap.admin"
]
dynamic_backends = [
"roles/storage.admin",
diff --git a/test/setup/main.tf b/test/setup/main.tf
index 21e76c0e..efe704a1 100644
--- a/test/setup/main.tf
+++ b/test/setup/main.tf
@@ -32,6 +32,7 @@ locals {
"storage-api.googleapis.com",
"vpcaccess.googleapis.com",
"cloudresourcemanager.googleapis.com",
+ "iap.googleapis.com",
]
dynamic_backends = [
"cloudresourcemanager.googleapis.com",