diff --git a/CHANGELOG.md b/CHANGELOG.md
index 978779ecd..61fdf3ff4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
+- [[#962](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/962)] Add filtering-proxy-psc blueprint ([kunzese](https://github.com/kunzese))
- [[#913](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/913)] Adding support for PSA ranges, starting with Redis instances. ([aurelienlegrand](https://github.com/aurelienlegrand))
- [[#939](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/939)] Temporarily duplicate cloud armor example ([ludoo](https://github.com/ludoo))
@@ -64,6 +65,7 @@ All notable changes to this project will be documented in this file.
### FAST
+- [[#966](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/966)] FAST: improve GitHub workflow, stage 01 output fixes ([ludoo](https://github.com/ludoo))
- [[#963](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/963)] **incompatible change:** Refactor vps-sc module for Terraform 1.3 ([ludoo](https://github.com/ludoo))
- [[#956](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/956)] FAST: bootstrap and extra stage CI/CD improvements and fixes ([ludoo](https://github.com/ludoo))
- [[#949](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/949)] **incompatible change:** Refactor VPC firewall module for Terraform 1.3 ([ludoo](https://github.com/ludoo))
diff --git a/blueprints/README.md b/blueprints/README.md
index bfb4c4836..c0b7687b8 100644
--- a/blueprints/README.md
+++ b/blueprints/README.md
@@ -8,7 +8,7 @@ Currently available blueprints:
- **data solutions** - [GCE and GCS CMEK via centralized Cloud KMS](./data-solutions/cmek-via-centralized-kms), [Cloud Composer version 2 private instance, supporting Shared VPC and external CMEK key](./data-solutions/composer-2), [Cloud SQL instance with multi-region read replicas](./data-solutions/cloudsql-multiregion), [Data Platform](./data-solutions/data-platform-foundations), [Spinning up a foundation data pipeline on Google Cloud using Cloud Storage, Dataflow and BigQuery](./data-solutions/gcs-to-bq-with-least-privileges), [#SQL Server Always On Groups blueprint](./data-solutions/sqlserver-alwayson), [Data Playground](./data-solutions/data-playground)
- **factories** - [The why and the how of Resource Factories](./factories), [Google Cloud Identity Group Factory](./factories/cloud-identity-group-factory), [Google Cloud BQ Factory](./factories/bigquery-factory), [Google Cloud VPC Firewall Factory](./factories/net-vpc-firewall-yaml), [Minimal Project Factory](./factories/project-factory)
- **GKE** - [Binary Authorization Pipeline Blueprint](./gke/binauthz), [Storage API](./gke/binauthz/image), [Multi-cluster mesh on GKE (fleet API)](./gke/multi-cluster-mesh-gke-fleet-api), [GKE Multitenant Blueprint](./gke/multitenant-fleet), [Shared VPC with GKE support](./networking/shared-vpc-gke/)
-- **networking** - [Decentralized firewall management](./networking/decentralized-firewall), [Decentralized firewall validator](./networking/decentralized-firewall/validator), [Network filtering with Squid](./networking/filtering-proxy), [HTTP Load Balancer with Cloud Armor](./networking/glb-and-armor), [Hub and Spoke via VPN](./networking/hub-and-spoke-vpn), [Hub and Spoke via VPC Peering](./networking/hub-and-spoke-peering), [Internal Load Balancer as Next Hop](./networking/ilb-next-hop), [Nginx-based reverse proxy cluster](./networking/nginx-reverse-proxy-cluster), [On-prem DNS and Google Private Access](./networking/onprem-google-access-dns), [Calling a private Cloud Function from On-premises](./networking/private-cloud-function-from-onprem), [Hybrid connectivity to on-premise services through PSC](./networking/psc-hybrid), [PSC Producer](./networking/psc-hybrid/psc-producer), [PSC Consumer](./networking/psc-hybrid/psc-consumer), [Shared VPC with optional GKE cluster](./networking/shared-vpc-gke)
+- **networking** - [Decentralized firewall management](./networking/decentralized-firewall), [Decentralized firewall validator](./networking/decentralized-firewall/validator), [Network filtering with Squid](./networking/filtering-proxy), [Network filtering with Squid with isolated VPCs using Private Service Connect](./networking/filtering-proxy-psc), [HTTP Load Balancer with Cloud Armor](./networking/glb-and-armor), [Hub and Spoke via VPN](./networking/hub-and-spoke-vpn), [Hub and Spoke via VPC Peering](./networking/hub-and-spoke-peering), [Internal Load Balancer as Next Hop](./networking/ilb-next-hop), [Nginx-based reverse proxy cluster](./networking/nginx-reverse-proxy-cluster), [On-prem DNS and Google Private Access](./networking/onprem-google-access-dns), [Calling a private Cloud Function from On-premises](./networking/private-cloud-function-from-onprem), [Hybrid connectivity to on-premise services through PSC](./networking/psc-hybrid), [PSC Producer](./networking/psc-hybrid/psc-producer), [PSC Consumer](./networking/psc-hybrid/psc-consumer), [Shared VPC with optional GKE cluster](./networking/shared-vpc-gke)
- **serverless** - [Creating multi-region deployments for API Gateway](./serverless/api-gateway)
- **third party solutions** - [OpenShift on GCP user-provisioned infrastructure](./third-party-solutions/openshift), [Wordpress deployment on Cloud Run](./third-party-solutions/wordpress/cloudrun)
diff --git a/blueprints/networking/filtering-proxy-psc/README.md b/blueprints/networking/filtering-proxy-psc/README.md
new file mode 100644
index 000000000..6459f3bf1
--- /dev/null
+++ b/blueprints/networking/filtering-proxy-psc/README.md
@@ -0,0 +1,28 @@
+# Network filtering with Squid with isolated VPCs using Private Service Connect
+
+This blueprint shows how to deploy a filtering HTTP proxy to restrict Internet access. Here we show one way to do this using isolated VPCs and Private Service Connect:
+
+- The `app` subnet hosts the consumer VMs that will have their Internet access tightly controlled by a non-caching filtering forward proxy.
+- The `proxy` subnet hosts a Cloud NAT instance and a [Squid](http://www.squid-cache.org/) server.
+- The `psc` subnet is reserved for the Private Service Connect.
+
+The reason for using Privat Service Connect in this setup is to have a common proxy setup between all environments without having to share a VPC between projects. This allows us to enforce the `compute.vmExternalIpAccess` [organization policy](https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints), which prevents the service projects from having external IPs, thus forcing all outbound Internet connections through the proxy.
+
+To allow Internet connectivity to the proxy subnet, a Cloud NAT instance is configured to allow usage from [that subnet only](https://cloud.google.com/nat/docs/using-nat#specify_subnet_ranges_for_nat). All other subnets are not allowed to use the Cloud NAT instance.
+
+To simplify the usage of the proxy, a Cloud DNS private zone is created in each consumer VPC and the IP address of the proxy is exposed with the FQDN `proxy.internal`. In addition, system-wide `http_proxy` and `https_proxy` environment variables and an APT configuration are rolled out via a [startup script](startup.sh).
+
+
+## Variables
+
+| name | description | type | required | default |
+|---|---|:---:|:---:|:---:|
+| [prefix](variables.tf#L44) | Prefix used for resources that need unique names. | string | ✓ | |
+| [project_id](variables.tf#L66) | Project id used for all resources. | string | ✓ | |
+| [allowed_domains](variables.tf#L17) | List of domains allowed by the squid proxy. | list(string) | | […] |
+| [cidrs](variables.tf#L28) | CIDR ranges for subnets. | map(string) | | {…} |
+| [nat_logging](variables.tf#L38) | Enables Cloud NAT logging if not null, value is one of 'ERRORS_ONLY', 'TRANSLATIONS_ONLY', 'ALL'. | string | | "ERRORS_ONLY" |
+| [project_create](variables.tf#L49) | Set to non null if project needs to be created. | object({…}) | | null |
+| [region](variables.tf#L71) | Default region for resources. | string | | "europe-west1" |
+
+
diff --git a/blueprints/networking/filtering-proxy-psc/consumer.tf b/blueprints/networking/filtering-proxy-psc/consumer.tf
new file mode 100644
index 000000000..5bcf03356
--- /dev/null
+++ b/blueprints/networking/filtering-proxy-psc/consumer.tf
@@ -0,0 +1,105 @@
+/**
+ * Copyright 2022 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.
+ */
+
+###############################################################################
+# Consumer project and VPC #
+###############################################################################
+
+module "vpc-consumer" {
+ source = "../../../modules/net-vpc"
+ project_id = module.project.project_id
+ name = "${var.prefix}-app"
+ subnets = [
+ {
+ name = "${var.prefix}-app"
+ ip_cidr_range = var.cidrs.app
+ region = var.region
+ }
+ ]
+}
+
+###############################################################################
+# Test VM #
+###############################################################################
+
+module "test-vm-consumer" {
+ source = "../../../modules/compute-vm"
+ project_id = module.project.project_id
+ zone = "${var.region}-b"
+ name = "${var.prefix}-test-vm"
+ instance_type = "e2-micro"
+ tags = ["ssh"]
+ network_interfaces = [{
+ network = module.vpc-consumer.self_link
+ subnetwork = module.vpc-consumer.subnet_self_links["${var.region}/${var.prefix}-app"]
+ nat = false
+ addresses = null
+ }]
+ boot_disk = {
+ image = "debian-cloud/debian-10"
+ type = "pd-standard"
+ size = 10
+ }
+ service_account_create = true
+ metadata = {
+ startup-script = templatefile("${path.module}/startup.sh", { proxy_url = "http://proxy.internal:3128" })
+ }
+}
+
+###############################################################################
+# PSC Consuner #
+###############################################################################
+
+resource "google_compute_address" "psc_endpoint_address" {
+ name = "${var.prefix}-psc-proxy-address"
+ project = module.project.project_id
+ address_type = "INTERNAL"
+ subnetwork = module.vpc-consumer.subnet_self_links["${var.region}/${var.prefix}-app"]
+ region = var.region
+}
+
+resource "google_compute_forwarding_rule" "psc_ilb_consumer" {
+ name = "${var.prefix}-psc-proxy-fw-rule"
+ project = module.project.project_id
+ region = var.region
+ target = google_compute_service_attachment.service_attachment.id
+ load_balancing_scheme = ""
+ network = module.vpc-consumer.self_link
+ ip_address = google_compute_address.psc_endpoint_address.id
+}
+
+###############################################################################
+# DNS and Firewall #
+###############################################################################
+
+module "private-dns" {
+ source = "../../../modules/dns"
+ project_id = module.project.project_id
+ type = "private"
+ name = "${var.prefix}-internal"
+ domain = "internal."
+ client_networks = [module.vpc-consumer.self_link]
+ recordsets = {
+ "A squid" = { ttl = 60, records = [google_compute_address.psc_endpoint_address.address] }
+ "CNAME proxy" = { ttl = 3600, records = ["squid.internal."] }
+ }
+}
+
+module "firewall-consumer" {
+ source = "../../../modules/net-vpc-firewall"
+ project_id = module.project.project_id
+ network = module.vpc-consumer.name
+}
diff --git a/blueprints/networking/filtering-proxy-psc/main.tf b/blueprints/networking/filtering-proxy-psc/main.tf
new file mode 100644
index 000000000..81499c7b5
--- /dev/null
+++ b/blueprints/networking/filtering-proxy-psc/main.tf
@@ -0,0 +1,210 @@
+/**
+ * Copyright 2022 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.
+ */
+
+###############################################################################
+# Host project and VPC resources #
+###############################################################################
+
+module "project" {
+ source = "../../../modules/project"
+ project_create = var.project_create != null
+ billing_account = try(var.project_create.billing_account, null)
+ parent = try(var.project_create.parent, null)
+ name = var.project_id
+ services = [
+ "dns.googleapis.com",
+ "compute.googleapis.com",
+ "logging.googleapis.com"
+ ]
+}
+
+module "vpc" {
+ source = "../../../modules/net-vpc"
+ project_id = module.project.project_id
+ name = "${var.prefix}-vpc"
+ subnets = [
+ {
+ name = "proxy"
+ ip_cidr_range = var.cidrs.proxy
+ region = var.region
+ }
+ ]
+ subnets_psc = [
+ {
+ name = "psc"
+ ip_cidr_range = var.cidrs.psc
+ region = var.region
+ }
+ ]
+}
+
+module "firewall" {
+ source = "../../../modules/net-vpc-firewall"
+ project_id = module.project.project_id
+ network = module.vpc.name
+ ingress_rules = {
+ allow-ingress-squid = {
+ description = "Allow squid ingress traffic"
+ source_ranges = [
+ var.cidrs.psc, "35.191.0.0/16", "130.211.0.0/22"
+ ]
+ targets = [module.service-account-squid.email]
+ use_service_accounts = true
+ rules = [{
+ protocol = "tcp"
+ ports = [3128]
+ }]
+ }
+ }
+}
+
+module "nat" {
+ source = "../../../modules/net-cloudnat"
+ project_id = module.project.project_id
+ region = var.region
+ name = "default"
+ router_network = module.vpc.name
+ config_source_subnets = "LIST_OF_SUBNETWORKS"
+ # 64512/11 = 5864 . 11 is the number of usable IPs in the proxy subnet
+ config_min_ports_per_vm = 5864
+ subnetworks = [
+ {
+ self_link = module.vpc.subnet_self_links["${var.region}/proxy"]
+ config_source_ranges = ["ALL_IP_RANGES"]
+ secondary_ranges = null
+ }
+ ]
+ logging_filter = var.nat_logging
+}
+
+###############################################################################
+# PSC resources #
+###############################################################################
+
+resource "google_compute_service_attachment" "service_attachment" {
+ name = "psc"
+ project = module.project.project_id
+ region = var.region
+ enable_proxy_protocol = false
+ connection_preference = "ACCEPT_MANUAL"
+ nat_subnets = [module.vpc.subnets_psc["${var.region}/psc"].self_link]
+ target_service = module.squid-ilb.forwarding_rule_self_link
+ consumer_accept_lists {
+ project_id_or_num = module.project.project_id
+ connection_limit = 10
+ }
+}
+
+###############################################################################
+# Squid resources #
+###############################################################################
+
+module "service-account-squid" {
+ source = "../../../modules/iam-service-account"
+ project_id = module.project.project_id
+ name = "svc-squid"
+ iam_project_roles = {
+ (module.project.project_id) = [
+ "roles/logging.logWriter",
+ "roles/monitoring.metricWriter",
+ ]
+ }
+}
+
+module "cos-squid" {
+ source = "../../../modules/cloud-config-container/squid"
+ allow = var.allowed_domains
+ clients = [var.cidrs.psc]
+}
+
+module "squid-vm" {
+ source = "../../../modules/compute-vm"
+ project_id = module.project.project_id
+ zone = "${var.region}-b"
+ name = "squid-vm"
+ instance_type = "e2-medium"
+ create_template = true
+ network_interfaces = [{
+ network = module.vpc.self_link
+ subnetwork = module.vpc.subnet_self_links["${var.region}/proxy"]
+ }]
+ boot_disk = {
+ image = "cos-cloud/cos-stable"
+ }
+ service_account = module.service-account-squid.email
+ service_account_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
+ metadata = {
+ user-data = module.cos-squid.cloud_config
+ }
+}
+
+module "squid-mig" {
+ source = "../../../modules/compute-mig"
+ project_id = module.project.project_id
+ location = "${var.region}-b"
+ name = "squid-mig"
+ instance_template = module.squid-vm.template.self_link
+ target_size = 1
+ auto_healing_policies = {
+ initial_delay_sec = 60
+ }
+ autoscaler_config = {
+ max_replicas = 10
+ min_replicas = 1
+ cooldown_period = 30
+ scaling_signals = {
+ cpu_utilization = {
+ target = 0.65
+ }
+ }
+ }
+ health_check_config = {
+ enable_logging = true
+ tcp = {
+ port = 3128
+ }
+ }
+ update_policy = {
+ minimal_action = "REPLACE"
+ type = "PROACTIVE"
+ max_surge = {
+ fixed = 3
+ }
+ min_ready_sec = 60
+ }
+}
+
+module "squid-ilb" {
+ source = "../../../modules/net-ilb"
+ project_id = module.project.project_id
+ region = var.region
+ name = "squid-ilb"
+ ports = [3128]
+ service_label = "squid-ilb"
+ vpc_config = {
+ network = module.vpc.self_link
+ subnetwork = module.vpc.subnet_self_links["${var.region}/proxy"]
+ }
+ backends = [{
+ group = module.squid-mig.group_manager.instance_group
+ }]
+ health_check_config = {
+ enable_logging = true
+ tcp = {
+ port = 3128
+ }
+ }
+}
diff --git a/blueprints/networking/filtering-proxy-psc/startup.sh b/blueprints/networking/filtering-proxy-psc/startup.sh
new file mode 100644
index 000000000..bdc2b9cbc
--- /dev/null
+++ b/blueprints/networking/filtering-proxy-psc/startup.sh
@@ -0,0 +1,26 @@
+# Copyright 2022 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.
+
+cat < /etc/apt/apt.conf.d/proxy.conf
+Acquire {
+ HTTP::proxy "${proxy_url}";
+ HTTPS::proxy "${proxy_url}";
+}
+EOF
+
+cat < /etc/profile.d/proxy.sh
+export http_proxy="${proxy_url}"
+export https_proxy="${proxy_url}"
+export no_proxy="127.0.0.1,localhost"
+EOF
diff --git a/blueprints/networking/filtering-proxy-psc/variables.tf b/blueprints/networking/filtering-proxy-psc/variables.tf
new file mode 100644
index 000000000..620107e4b
--- /dev/null
+++ b/blueprints/networking/filtering-proxy-psc/variables.tf
@@ -0,0 +1,75 @@
+/**
+ * Copyright 2022 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 "allowed_domains" {
+ description = "List of domains allowed by the squid proxy."
+ type = list(string)
+ default = [
+ ".google.com",
+ ".github.com",
+ ".fastlydns.net",
+ ".debian.org"
+ ]
+}
+
+variable "cidrs" {
+ description = "CIDR ranges for subnets."
+ type = map(string)
+ default = {
+ app = "10.0.0.0/24"
+ proxy = "10.0.2.0/28"
+ psc = "10.0.3.0/28"
+ }
+}
+
+variable "nat_logging" {
+ description = "Enables Cloud NAT logging if not null, value is one of 'ERRORS_ONLY', 'TRANSLATIONS_ONLY', 'ALL'."
+ type = string
+ default = "ERRORS_ONLY"
+}
+
+variable "prefix" {
+ description = "Prefix used for resources that need unique names."
+ type = string
+}
+
+variable "project_create" {
+ description = "Set to non null if project needs to be created."
+ type = object({
+ billing_account = string
+ parent = string
+ })
+ default = null
+ validation {
+ condition = (
+ var.project_create == null
+ ? true
+ : can(regex("(organizations|folders)/[0-9]+", var.project_create.parent))
+ )
+ error_message = "Project parent must be of the form folders/folder_id or organizations/organization_id."
+ }
+}
+
+variable "project_id" {
+ description = "Project id used for all resources."
+ type = string
+}
+
+variable "region" {
+ description = "Default region for resources."
+ type = string
+ default = "europe-west1"
+}
diff --git a/blueprints/networking/filtering-proxy-psc/versions.tf b/blueprints/networking/filtering-proxy-psc/versions.tf
new file mode 100644
index 000000000..286536a65
--- /dev/null
+++ b/blueprints/networking/filtering-proxy-psc/versions.tf
@@ -0,0 +1,29 @@
+# Copyright 2022 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
+#
+# https://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.
+
+terraform {
+ required_version = ">= 1.3.1"
+ required_providers {
+ google = {
+ source = "hashicorp/google"
+ version = ">= 4.40.0" # tftest
+ }
+ google-beta = {
+ source = "hashicorp/google-beta"
+ version = ">= 4.40.0" # tftest
+ }
+ }
+}
+
+
diff --git a/tests/blueprints/networking/filtering_proxy_psc/__init__.py b/tests/blueprints/networking/filtering_proxy_psc/__init__.py
new file mode 100644
index 000000000..6d6d1266c
--- /dev/null
+++ b/tests/blueprints/networking/filtering_proxy_psc/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2022 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.
diff --git a/tests/blueprints/networking/filtering_proxy_psc/fixture/main.tf b/tests/blueprints/networking/filtering_proxy_psc/fixture/main.tf
new file mode 100644
index 000000000..eb01058d1
--- /dev/null
+++ b/tests/blueprints/networking/filtering_proxy_psc/fixture/main.tf
@@ -0,0 +1,25 @@
+/**
+ * Copyright 2022 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 "test" {
+ source = "../../../../../blueprints/networking/filtering-proxy-psc"
+ prefix = "fabric"
+ project_create = {
+ billing_account = "123456-ABCDEF-123456"
+ parent = "folders/1234567890"
+ }
+ project_id = "test-project"
+}
diff --git a/tests/blueprints/networking/filtering_proxy_psc/test_plan.py b/tests/blueprints/networking/filtering_proxy_psc/test_plan.py
new file mode 100644
index 000000000..9a2c3c2fa
--- /dev/null
+++ b/tests/blueprints/networking/filtering_proxy_psc/test_plan.py
@@ -0,0 +1,19 @@
+# Copyright 2022 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.
+
+def test_resources(e2e_plan_runner):
+ "Test that plan works and the numbers of resources is as expected."
+ modules, resources = e2e_plan_runner()
+ assert len(modules) == 12
+ assert len(resources) == 33