Google Cloud Shared VPC Terraform Module#
This module creates and configures a Google Cloud Shared VPC host project with associated networking resources. It provides a comprehensive solution for organizations looking to implement a centralized network architecture in GCP.
Overview#
The Shared VPC architecture in Google Cloud allows organizations to connect resources from multiple projects to a common VPC network administered in a central host project. This provides:
- Centralized network control: Network administrators maintain control over network resources, configurations, and security policies
- Decentralized application development: Service project owners can provision and manage their own application resources
- Resource sharing: Service projects can use subnets, routes, and other network resources from the host project
Compatibility#
This module is compatible with Terraform version ~> 1.0 and has been tested with the following provider versions:
- Google Provider:
>= 6.28.0, < 7.0.0 - Google Beta Provider:
>= 6.28.0, < 7.0.0
Features#
This module will:
- Create a host project with Shared VPC enabled
- Create a VPC network with customizable subnets
- Configure secondary IP address ranges for subnets (essential for GKE clusters)
- Create custom routes
- Set up Cloud NAT configurations per region
- Create service accounts
- Configure Private Google Access
- Set up Private Service Connect endpoints
- Support beta subnet features like REGIONAL_MANAGED_PROXY
Architecture#
┌───────────────────────────────────────┐
│ │
│ Shared VPC Host Project │
│ │
│ ┌─────────────────────────────────┐ │
│ │ │ │
│ │ Shared VPC Network │ │
│ │ │ │
│ │ ┌───────┐ ┌───────┐ ┌─────┐ │ │
│ │ │Subnet1│ │Subnet2│ │ ... │ │ │
│ │ └───────┘ └───────┘ └─────┘ │ │
│ │ │ │
│ │ ┌─────────┐ ┌───────────────┐ │ │
│ │ │Cloud NAT│ │Private Service│ │ │
│ │ └─────────┘ │ Connect │ │ │
│ │ └───────────────┘ │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────┐ │
│ │Service │ │
│ │Accounts │ │
│ └─────────────┘ │
│ │
└───────────────────────────────────────┘
Usage#
Advanced Usage with Optional Resources#
module "shared_vpc" {
source = "github.com/your-org/gcp-terraform-modules/terraform-google-shared-vpc"
host_project_name = "gcp-blues-7-shared-vpc-host"
billing_account = "YOUR_BILLING_ACCOUNT_ID"
domain = "labs.example.com"
environment = "prod"
deletion_policy = "DELETE"
subnets = [
{
subnet_name = "dev-default"
subnet_ip = "10.150.1.0/24"
subnet_region = "me-west1"
subnet_private_access = true
subnet_flow_logs = true
}
]
subnets_beta = [
{
subnet_name = "dev-proxy"
subnet_ip = "10.150.0.0/24"
subnet_region = "me-west1"
subnet_private_access = false
subnet_flow_logs = false
purpose = "REGIONAL_MANAGED_PROXY"
role = "ACTIVE"
}
]
secondary_ranges = {
"subnet-1" = [
{
range_name = "pods"
ip_cidr_range = "10.0.1.0/16"
}
]
}
network_name = "shared-vpc-network"
private_access = true
private_access_range = "10.100.0.0"
private_access_prefix = 24
folder_id = "123456789123"
lien = false
default_service_account = "deprivilege"
service_accounts = ["ops-sa", "readonly-sa"]
routing_mode = "REGIONAL"
create_nat_ips = false
cloud_nats = {
me-west1 = {
cloud_nat_name = "cloud-nat"
router_name = "router"
router_asn = "64514"
source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
log_config_enable = true
log_config_filter = "ALL"
subnetworks = []
}
}
min_ports_per_vm = 64
forwarding_rule_target = "all-apis"
private_service_connect = false
mtu = 1460
delete_default_routes = false
}
Optional Resources#
The following resources are optional and can be enabled/configured as needed:
| Resource | Description | How to Enable |
|---|---|---|
| Cloud NAT | Provides outbound internet connectivity for instances without public IPs | Set create_nat_ips = true and configure cloud_nats map |
| Private Google Access | Allows resources without public IPs to access Google APIs and services | Set private_access = true and provide private_access_range |
| Private Service Connect | Provides private connectivity to services | Set private_service_connect = true and provide private_service_connect_ip |
| Custom Routes | Define custom routes for network traffic | Configure the routes list |
| Secondary IP Ranges | Additional IP ranges for resources like GKE pods and services | Configure secondary_ranges map |
| Beta Subnet Features | Special subnet types (e.g., proxy-only subnets) | Configure subnets_beta list |
| Service Accounts | Create service accounts in the host project | Add to service_accounts list |
| VPC Flow Logs | Capture network flow logs for monitoring and forensics | Enable with subnet-level subnet_flow_logs = true |
Important Considerations#
- Resource Protection: Set
lien = trueto protect the project from accidental deletion - API Activation: By default, the module activates essential APIs for networking, but you can customize the list
- MTU Settings: The default MTU is Google Cloud's standard 1460, but can be customized for special requirements
Migration Considerations#
When migrating existing projects to use Shared VPC:
- Plan IP address allocation carefully to avoid overlaps
- Consider using larger CIDR blocks to accommodate future growth
- Review IAM permissions required for service project administrators
- Test connectivity between service projects and the host VPC before migrating production workloads
Software#
This module requires the following software dependencies:
- Terraform
~> 1.0 - Google Cloud Provider
>= 6.28.0, < 7.0.0 - Google Cloud Beta Provider
>= 6.28.0, < 7.0.0
Service Account#
The service account used to run this module must have the following IAM roles:
roles/compute.xpnAdmin- To enable and manage Shared VPCroles/compute.networkAdmin- To create and manage VPC networks and subnetsroles/compute.securityAdmin- To manage firewall rulesroles/iam.serviceAccountAdmin- To create and manage service accountsroles/servicenetworking.networksAdmin- To configure private service accessroles/dns.admin- To manage Cloud DNS (if using private zones)
APIs#
The following GCP APIs must be enabled in the target project:
- Compute Engine API (
compute.googleapis.com) - Service Networking API (
servicenetworking.googleapis.com) - Cloud DNS API (
dns.googleapis.com) - Required for private DNS zones - Cloud Resource Manager API (
cloudresourcemanager.googleapis.com)
License#
This module is covered by a commercial license. Please see LICENSE for details.
Support#
This module is developed and maintained by MyOps Limited. For any support inquiries, please contact us at info@myops.co.il.
Requirements#
| Name | Version |
|---|---|
| terraform | ~> 1 |
| >= 6.28.0, < 7.0.0 | |
| google-beta | >= 6.28.0, < 7.0.0 |
Providers#
| Name | Version |
|---|---|
| >= 6.28.0, < 7.0.0 | |
| google-beta | >= 6.28.0, < 7.0.0 |
Modules#
| Name | Source | Version |
|---|---|---|
| cloud-nat | terraform-google-modules/cloud-nat/google | ~> 5.3.0 |
| eip | terraform-google-modules/address/google | ~> 4.1.0 |
| host_project | terraform-google-modules/project-factory/google | ~> 18.0.0 |
| private_service_connect | terraform-google-modules/network/google//modules/private-service-connect | ~> 11.0.0 |
| subnets_beta | terraform-google-modules/network/google//modules/subnets-beta | ~> 11.0.0 |
| vpc | terraform-google-modules/network/google | ~> 11.0.0 |
Resources#
| Name | Type |
|---|---|
| google-beta_google_compute_global_address.private_ip_address | resource |
| google-beta_google_service_networking_connection.private_vpc_connection | resource |
| google_service_account.service_accounts | resource |
| google_organization.org | data source |
Inputs#
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| active_apis | List of Google Cloud APIs to enable in the host project | list(string) |
[ |
no |
| billing_account | GCP Billing Account ID in the format 'XXXXXX-XXXXXX-XXXXXX' | string |
n/a | yes |
| cloud_nats | Map of Cloud NAT configurations per region | map(object({ |
{} |
no |
| create_nat_ips | Whether to create external IP addresses for Cloud NAT | bool |
false |
no |
| default_service_account | Project default service account setting: can be one of delete, deprivilege, disable, or keep. |
string |
"deprivilege" |
no |
| delete_default_routes | Whether to delete default internet gateway routes in the VPC | bool |
false |
no |
| deletion_policy | Deletion policy for the host project | string |
"PREVENT" |
no |
| domain | Organization domain for lookup (e.g., example.com) to fetch org ID | string |
n/a | yes |
| folder_id | If specified, the host project will be created under this folder | string |
null |
no |
| forwarding_rule_target | Target resource to receive the matched traffic. Only all-apis and vpc-sc are valid. |
string |
"all-apis" |
no |
| host_project_name | Base name for the host project. Actual project ID will be {var.host_project_name}-{var.geo}-{var.environment} | string |
n/a | yes |
| lien | Whether to apply a Resource Manager Lien on the project to prevent deletion | bool |
false |
no |
| min_ports_per_vm | Minimum number of ports allocated per VM for Cloud NAT | number |
null |
no |
| mtu | The network MTU (If set to 0, meaning MTU is unset - defaults to '1460'). Recommended values: 1460 (default for historic reasons), 1500 (Internet default), or 8896 (for Jumbo packets). Allowed are all values in the range 1300 to 8896, inclusively. | number |
0 |
no |
| network_name | Name of the VPC network to create | string |
n/a | yes |
| private_access | Whether to enable Private Google Access in the network | bool |
false |
no |
| private_access_prefix | Prefix length for Private Google Access range (default 24) | number |
24 |
no |
| private_access_range | CIDR range (/24) reserved for Private Google Access VPC peering | string |
null |
no |
| private_service_connect | Whether to enable Private Service Connect on the network | bool |
false |
no |
| private_service_connect_ip | Internal IP address for the Private Service Connect endpoint; must not overlap existing networks | string |
"" |
no |
| routing_mode | Cloud network routing mode: 'REGIONAL' or 'GLOBAL' | string |
"REGIONAL" |
no |
| secondary_ranges | Map of lists of secondary IP ranges per subnet | map(list(object({ range_name = string, ip_cidr_range = string }))) |
{} |
no |
| service_accounts | List of custom service account IDs to create in the host project | list(string) |
[] |
no |
| subnets | List of subnet definitions with keys: name, ip, region, and optional private_access, flow_logs | list(map(string)) |
[] |
no |
| subnets_beta | List of beta subnet definitions (same structure as 'subnets') + keys purpose, role | list(map(string)) |
[] |
no |
Outputs#
| Name | Description |
|---|---|
| domain | The organization's domain |
| nat_ips | n/a |
| network | The created network |
| network_name | The name of the VPC being created |
| network_self_link | The URI of the VPC being created |
| project_bucket_self_link | Project's bucket selfLink |
| project_bucket_url | Project's bucket url |
| project_id | VPC project id |
| project_name | Project factory outputs |
| project_number | n/a |
| proxy_subnets | A map with keys of form subnet_region/subnet_name and values being the outputs of the google_compute_subnetwork resources used to create corresponding proxy subnets. |
| route_names | The route names associated with this VPC |
| service_account_display_name | The display name of the default service account |
| service_account_email | The email of the default service account |
| service_account_id | The id of the default service account |
| service_account_name | The fully-qualified name of the default service account |
| service_account_unique_id | The unique id of the default service account |
| subnets | A map with keys of form subnet_region/subnet_name and values being the outputs of the google_compute_subnetwork resources used to create corresponding subnets. |
| subnets_flow_logs | Whether the subnets will have VPC flow logs enabled |
| subnets_ips | The IPs and CIDRs of the subnets being created |
| subnets_names | The names of the subnets being created |
| subnets_private_access | Whether the subnets will have access to Google API's without a public IP |
| subnets_regions | The region where the subnets will be created |
| subnets_secondary_ranges | The secondary ranges associated with these subnets |
| subnets_self_links | The self-links of subnets being created |