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"]