diff --git a/modules/net-vpc/README.md b/modules/net-vpc/README.md
index 5e982798..61e1b678 100644
--- a/modules/net-vpc/README.md
+++ b/modules/net-vpc/README.md
@@ -121,6 +121,26 @@ module "vpc-host" {
# tftest:modules=1:resources=7
```
+### Private Service Networking
+
+```hcl
+module "vpc" {
+ source = "./modules/net-vpc"
+ project_id = "my-project"
+ name = "my-network"
+ subnets = [
+ {
+ ip_cidr_range = "10.0.0.0/24"
+ name = "production"
+ region = "europe-west1"
+ secondary_ip_range = null
+ }
+ ]
+ private_service_networking_range = "10.10.0.0/16"
+}
+# tftest:modules=1:resources=4
+```
+
## Variables
@@ -137,6 +157,7 @@ module "vpc-host" {
| *mtu* | Maximum Transmission Unit in bytes. The minimum value for this field is 1460 and the maximum value is 1500 bytes. |
| | null
|
| *peering_config* | VPC peering configuration. | object({...})
| | null
|
| *peering_create_remote_end* | Skip creation of peering on the remote end when using peering_config | bool
| | true
|
+| *private_service_networking_range* | RFC1919 CIDR range used for Google services that support private service networking. | string
| | ...
|
| *routes* | Network routes, keyed by name. | map(object({...}))
| | {}
|
| *routing_mode* | The network routing mode (default 'GLOBAL') | string
| | ...
|
| *shared_vpc_host* | Enable shared VPC for this project. | bool
| | false
|
diff --git a/modules/net-vpc/main.tf b/modules/net-vpc/main.tf
index 9fb6218b..c241aca1 100644
--- a/modules/net-vpc/main.tf
+++ b/modules/net-vpc/main.tf
@@ -227,3 +227,21 @@ resource "google_compute_route" "vpn_tunnel" {
tags = each.value.tags
next_hop_vpn_tunnel = each.value.next_hop
}
+
+resource "google_compute_global_address" "psn_range" {
+ count = var.private_service_networking_range == null ? 0 : 1
+ project = var.project_id
+ name = "google-private-service-networking"
+ purpose = "VPC_PEERING"
+ address_type = "INTERNAL"
+ address = split("/", var.private_service_networking_range)[0]
+ prefix_length = split("/", var.private_service_networking_range)[1]
+ network = local.network.id
+}
+
+resource "google_service_networking_connection" "psn_connection" {
+ count = var.private_service_networking_range == null ? 0 : 1
+ network = local.network.id
+ service = "servicenetworking.googleapis.com"
+ reserved_peering_ranges = [google_compute_global_address.psn_range.0.name]
+}
diff --git a/modules/net-vpc/outputs.tf b/modules/net-vpc/outputs.tf
index 353e92a8..0967e174 100644
--- a/modules/net-vpc/outputs.tf
+++ b/modules/net-vpc/outputs.tf
@@ -17,16 +17,25 @@
output "network" {
description = "Network resource."
value = local.network
+ depends_on = [
+ google_service_networking_connection.psn_connection
+ ]
}
output "name" {
description = "The name of the VPC being created."
value = local.network.name
+ depends_on = [
+ google_service_networking_connection.psn_connection
+ ]
}
output "self_link" {
description = "The URI of the VPC being created."
value = local.network.self_link
+ depends_on = [
+ google_service_networking_connection.psn_connection
+ ]
}
output "project_id" {
@@ -38,7 +47,8 @@ output "project_id" {
)
depends_on = [
google_compute_shared_vpc_host_project.shared_vpc_host,
- google_compute_shared_vpc_service_project.service_projects
+ google_compute_shared_vpc_service_project.service_projects,
+ google_service_networking_connection.psn_connection
]
}
diff --git a/modules/net-vpc/variables.tf b/modules/net-vpc/variables.tf
index f13182ae..b98f324c 100644
--- a/modules/net-vpc/variables.tf
+++ b/modules/net-vpc/variables.tf
@@ -159,3 +159,16 @@ variable "vpc_create" {
type = bool
default = true
}
+
+variable "private_service_networking_range" {
+ description = "RFC1919 CIDR range used for Google services that support private service networking."
+ type = string
+ default = null
+ validation {
+ condition = (
+ var.private_service_networking_range == null ||
+ can(cidrnetmask(var.private_service_networking_range))
+ )
+ error_message = "Specify a valid RFC1918 CIDR range for private service networking."
+ }
+}
diff --git a/tests/modules/net_vpc/fixture/main.tf b/tests/modules/net_vpc/fixture/main.tf
index 6c30e799..42217101 100644
--- a/tests/modules/net_vpc/fixture/main.tf
+++ b/tests/modules/net_vpc/fixture/main.tf
@@ -15,19 +15,20 @@
*/
module "test" {
- source = "../../../../modules/net-vpc"
- project_id = var.project_id
- name = var.name
- iam = var.iam
- log_configs = var.log_configs
- log_config_defaults = var.log_config_defaults
- peering_config = var.peering_config
- routes = var.routes
- shared_vpc_host = var.shared_vpc_host
- shared_vpc_service_projects = var.shared_vpc_service_projects
- subnets = var.subnets
- subnet_descriptions = var.subnet_descriptions
- subnet_flow_logs = var.subnet_flow_logs
- subnet_private_access = var.subnet_private_access
- auto_create_subnetworks = var.auto_create_subnetworks
+ source = "../../../../modules/net-vpc"
+ project_id = var.project_id
+ name = var.name
+ iam = var.iam
+ log_configs = var.log_configs
+ log_config_defaults = var.log_config_defaults
+ peering_config = var.peering_config
+ routes = var.routes
+ shared_vpc_host = var.shared_vpc_host
+ shared_vpc_service_projects = var.shared_vpc_service_projects
+ subnets = var.subnets
+ subnet_descriptions = var.subnet_descriptions
+ subnet_flow_logs = var.subnet_flow_logs
+ subnet_private_access = var.subnet_private_access
+ auto_create_subnetworks = var.auto_create_subnetworks
+ private_service_networking_range = var.private_service_networking_range
}
diff --git a/tests/modules/net_vpc/fixture/variables.tf b/tests/modules/net_vpc/fixture/variables.tf
index 9ba39b7d..efa2ba7a 100644
--- a/tests/modules/net_vpc/fixture/variables.tf
+++ b/tests/modules/net_vpc/fixture/variables.tf
@@ -119,3 +119,9 @@ variable "subnet_private_access" {
type = map(bool)
default = {}
}
+
+variable "private_service_networking_range" {
+ description = "RFC1919 CIDR range used for Google services that support private service networking."
+ type = string
+ default = null
+}
diff --git a/tests/modules/net_vpc/test_plan.py b/tests/modules/net_vpc/test_plan.py
index e04d62a5..9bce2a5c 100644
--- a/tests/modules/net_vpc/test_plan.py
+++ b/tests/modules/net_vpc/test_plan.py
@@ -88,3 +88,20 @@ def test_vpc_routes(plan_runner):
resource = [r for r in resources if r['values']
['name'] == 'my-vpc-next-hop-test'][0]
assert resource['values']['next_hop_%s' % next_hop_type]
+
+
+def test_vpc_psn(plan_runner):
+ _, resources = plan_runner(
+ FIXTURES_DIR, private_service_networking_range="10.10.0.0/16"
+ )
+ assert len(resources) == 3
+
+ address = [r["values"] for r in resources if r["type"] == "google_compute_global_address"][0]
+ assert address["address"] == "10.10.0.0"
+ assert address["address_type"] == "INTERNAL"
+ assert address["prefix_length"] == 16
+ assert address["purpose"] == "VPC_PEERING"
+
+ connection = [r["values"] for r in resources if r["type"] == "google_service_networking_connection"][0]
+ assert connection["service"] == "servicenetworking.googleapis.com"
+ assert connection["reserved_peering_ranges"] == ["google-private-service-networking"]