GitPedia

Terraform google network

Sets up a new VPC network on Google Cloud

From terraform-google-modules·Updated June 18, 2026·View on GitHub·

This module makes it easy to set up a new VPC Network in GCP by defining your network and subnet ranges in a concise syntax. The project is written primarily in HCL, distributed under the Apache License 2.0 license, first published in 2018. Key topics include: cft-terraform, networking.

Latest release: v18.1.2
June 10, 2026View Changelog →

Terraform Network Module

This module makes it easy to set up a new VPC Network in GCP by defining your network and subnet ranges in a concise syntax.

It supports creating:

  • A Google Virtual Private Network (VPC)
  • Subnets within the VPC
  • Secondary ranges for the subnets (if applicable)
  • routes
  • firewall rules
  • network firewall policy
  • hierarchical firewall policy
  • serverless vpc access connector
  • network connectivity center

Sub modules are provided for creating individual vpc, subnets, routes, firewall rules, network firewall policies, hierarchical firewall policy, serverless vpc access connector and network connectivity center. See the modules directory for the various sub modules usage.

Compatibility

This module is meant for use with Terraform 1.3+.
If you find incompatibilities using Terraform >=1.3, please open an issue.

Usage

Comprehensive examples are available in examples folder. Simple usage:

hcl
module "vpc" { source = "terraform-google-modules/network/google" version = "~> 18.1" project_id = "<PROJECT ID>" network_name = "example-vpc" routing_mode = "GLOBAL" subnets = [ { subnet_name = "subnet-01" subnet_ip = "10.10.10.0/24" subnet_region = "us-west1" }, { subnet_name = "subnet-02" subnet_ip = "10.10.20.0/24" subnet_region = "us-west1" subnet_private_access = "true" subnet_flow_logs = "true" description = "This subnet has a description" }, { subnet_name = "subnet-03" subnet_ip = "10.10.30.0/24" subnet_region = "us-west1" subnet_flow_logs = "true" subnet_flow_logs_interval = "INTERVAL_10_MIN" subnet_flow_logs_sampling = 0.7 subnet_flow_logs_metadata = "INCLUDE_ALL_METADATA" } ] secondary_ranges = { subnet-01 = [ { range_name = "subnet-01-secondary-01" ip_cidr_range = "192.168.64.0/24" }, ] subnet-02 = [] } routes = [ { name = "egress-internet" description = "route through IGW to access internet" destination_range = "0.0.0.0/0" tags = ["egress-inet"] next_hop_internet = true }, { name = "app-proxy" description = "route through proxy to reach app" destination_range = "10.50.10.0/24" tags = ["app-proxy"] next_hop_instance = "app-proxy-instance" next_hop_instance_zone = "us-west1-a" }, ] }

Then perform the following commands on the root folder:

  • terraform init to get the plugins
  • terraform plan to see the infrastructure plan
  • terraform apply to apply the infrastructure build
  • terraform destroy to destroy the built infrastructure
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Inputs

NameDescriptionTypeDefaultRequired
auto_create_subnetworksWhen set to true, the network is created in 'auto subnet mode' and it will create a subnet for each region automatically across the 10.128.0.0/9 address range. When set to false, the network is created in 'custom subnet mode' so the user can explicitly connect subnetwork resources.boolfalseno
bgp_always_compare_medIf set to true, the Cloud Router will use MED values from the peer even if the AS paths differ. Default is false.boolfalseno
bgp_best_path_selection_modeSpecifies the BGP best path selection mode. Valid values are STANDARD or LEGACY. Default is LEGACY.string"LEGACY"no
bgp_inter_region_costSpecifies the BGP inter-region cost mode. Valid values are DEFAULT or ADD_COST_TO_MED.stringnullno
delete_default_internet_gateway_routesIf set, ensure that all routes within the network specified whose names begin with 'default-route' and with a next hop of 'default-internet-gateway' are deletedboolfalseno
descriptionAn optional description of this resource. The resource must be recreated to modify this field.string""no
egress_rulesList of egress rules. This will be ignored if variable 'rules' is non-empty<pre>list(object({<br> name = string<br> description = optional(string, null)<br> disabled = optional(bool, null)<br> priority = optional(number, null)<br> destination_ranges = optional(list(string), [])<br> source_ranges = optional(list(string), [])<br> source_tags = optional(list(string))<br> source_service_accounts = optional(list(string))<br> target_tags = optional(list(string))<br> target_service_accounts = optional(list(string))<br><br> allow = optional(list(object({<br> protocol = string<br> ports = optional(list(string))<br> })), [])<br> deny = optional(list(object({<br> protocol = string<br> ports = optional(list(string))<br> })), [])<br> log_config = optional(object({<br> metadata = string<br> }))<br> }))</pre>[]no
enable_ipv6_ulaEnabled IPv6 ULA, this is a permanent change and cannot be undone! (default 'false')boolfalseno
firewall_rulesThis is DEPRECATED and available for backward compatibility. Use ingress_rules and egress_rules variables. List of firewall rules<pre>list(object({<br> name = string<br> description = optional(string, null)<br> direction = optional(string, "INGRESS")<br> disabled = optional(bool, null)<br> priority = optional(number, null)<br> ranges = optional(list(string), [])<br> source_tags = optional(list(string))<br> source_service_accounts = optional(list(string))<br> target_tags = optional(list(string))<br> target_service_accounts = optional(list(string))<br><br> allow = optional(list(object({<br> protocol = string<br> ports = optional(list(string))<br> })), [])<br> deny = optional(list(object({<br> protocol = string<br> ports = optional(list(string))<br> })), [])<br> log_config = optional(object({<br> metadata = string<br> }))<br> }))</pre>[]no
ingress_rulesList of ingress rules. This will be ignored if variable 'rules' is non-empty<pre>list(object({<br> name = string<br> description = optional(string, null)<br> disabled = optional(bool, null)<br> priority = optional(number, null)<br> destination_ranges = optional(list(string), [])<br> source_ranges = optional(list(string), [])<br> source_tags = optional(list(string))<br> source_service_accounts = optional(list(string))<br> target_tags = optional(list(string))<br> target_service_accounts = optional(list(string))<br><br> allow = optional(list(object({<br> protocol = string<br> ports = optional(list(string))<br> })), [])<br> deny = optional(list(object({<br> protocol = string<br> ports = optional(list(string))<br> })), [])<br> log_config = optional(object({<br> metadata = string<br> }))<br> }))</pre>[]no
internal_ipv6_rangeWhen enabling IPv6 ULA, optionally, specify a /48 from fd20::/20 (default null)stringnullno
mtuThe 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.number0no
network_firewall_policy_enforcement_orderSet the order that Firewall Rules and Firewall Policies are evaluated. Valid values are BEFORE_CLASSIC_FIREWALL and AFTER_CLASSIC_FIREWALL. (default null or equivalent to AFTER_CLASSIC_FIREWALL)stringnullno
network_nameThe name of the network being createdstringn/ayes
network_profile"A full or partial URL of the network profile to apply to this network.<br>This field can be set only at resource creation time. For example, the<br>following are valid URLs:<br> * https://www.googleapis.com/compute/beta/projects/{projectId}/global/networkProfiles/{network_profile_name}<br> * projects/{projectId}/global/networkProfiles/{network_profile_name}stringnullno
private_service_access_configConfiguration for Private Service Access (PSA) connection.<pre>object({<br> enable_private_services_connection = bool<br> address_name = string<br> prefix_length = number<br> })</pre><pre>{<br> "address_name": "private-ip-address",<br> "enable_private_services_connection": false,<br> "prefix_length": 16<br>}</pre>no
project_idThe ID of the project where this VPC will be createdstringn/ayes
routesList of routes being created in this VPC.<pre>list(object({<br> name = string<br> description = optional(string)<br> tags = optional(list(string), [])<br> destination_range = string<br> next_hop_gateway = optional(string)<br> next_hop_internet = optional(bool, false)<br> next_hop_ip = optional(string)<br> next_hop_instance = optional(string)<br> next_hop_instance_zone = optional(string)<br> next_hop_vpn_tunnel = optional(string)<br> next_hop_ilb = optional(string)<br> priority = optional(number, 1000)<br> }))</pre>[]no
routing_modeThe network routing mode (default 'GLOBAL')string"GLOBAL"no
secondary_rangesSecondary ranges that will be used in some of the subnetsmap(list(object({ range_name = string, ip_cidr_range = optional(string), reserved_internal_range = optional(string) }))){}no
shared_vpc_hostMakes this project a Shared VPC host if 'true' (default 'false')boolfalseno
subnetsThe list of subnets being created<pre>list(object({<br> subnet_name = string<br> subnet_ip = string<br> subnet_region = optional(string)<br> subnet_private_access = optional(string)<br> subnet_private_ipv6_access = optional(string)<br> subnet_flow_logs = optional(string)<br> subnet_flow_logs_interval = optional(string)<br> subnet_flow_logs_sampling = optional(string)<br> subnet_flow_logs_metadata = optional(string)<br> subnet_flow_logs_filter = optional(string)<br> subnet_flow_logs_metadata_fields = optional(list(string))<br> description = optional(string)<br> purpose = optional(string)<br> role = optional(string)<br> stack_type = optional(string)<br> ipv6_access_type = optional(string)<br> ip_collection = optional(string)<br> external_ipv6_prefix = optional(string)<br> }))</pre>n/ayes
subnets_regionOptional subnets region. If set, all subnets will be created in this region.stringnullno

Outputs

NameDescription
networkThe created network
network_idThe ID of the VPC being created
network_nameThe name of the VPC being created
network_self_linkThe URI of the VPC being created
project_idVPC project id
route_namesThe route names associated with this VPC
subnetsA 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_by_region_purposeA list of subnet summary objects containing id, purpose, and region extracted from the subnets map.
subnets_flow_logsWhether the subnets will have VPC flow logs enabled
subnets_idsThe IDs of the subnets being created
subnets_ipsThe IPs and CIDRs of the subnets being created
subnets_namesThe names of the subnets being created
subnets_overviewA high-level overview of the created subnets and their core addressing/routing attributes such as id, purpose,ip_cidr_range and region extracted from the subnets map.
subnets_private_accessWhether the subnets will have access to Google API's without a public IP
subnets_regionsThe region where the subnets will be created
subnets_secondary_rangesThe secondary ranges associated with these subnets
subnets_self_linksThe self-links of subnets being created
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Subnet Inputs

The subnets list contains maps, where each object represents a subnet. Each map has the following inputs (please see examples folder for additional references):

NameDescriptionTypeDefaultRequired
subnet_nameThe name of the subnet being createdstring-yes
subnet_ipThe IP and CIDR range of the subnet being createdstring-yes
subnet_regionThe region where the subnet will be createdstring-yes
subnet_private_accessWhether this subnet will have private Google access enabledstring"false"no
subnet_private_ipv6_accessThe private IPv6 google access type for the VMs in this subnetstring-no
subnet_flow_logsWhether the subnet will record and send flow log data to loggingstring"false"no
subnet_flow_logs_intervalIf subnet_flow_logs is true, sets the aggregation interval for collecting flow logsstring"INTERVAL_5_SEC"no
subnet_flow_logs_samplingIf subnet_flow_logs is true, set the sampling rate of VPC flow logs within the subnetworkstring"0.5"no
subnet_flow_logs_metadataIf subnet_flow_logs is true, configures whether metadata fields should be added to the reported VPC flow logsstring"INCLUDE_ALL_METADATA"no
subnet_flow_logs_filterExport filter defining which VPC flow logs should be logged, see https://cloud.google.com/vpc/docs/flow-logs#filtering for formatting detailsstring"true"no
subnet_flow_logs_metadata_fieldsList of metadata fields that should be added to reported logs. Can only be specified if VPC flow logs for this subnetwork is enabled and "metadata" is set to CUSTOM_METADATA.any-no
descriptionAn optional description of this resource. Provide this property when you create the resource. This field can be set only at resource creation timestring-no
purposeThe purpose of the subnet usage. Whether it is to be used as a regular subnet or for proxy or loadbalacing purposes, see https://cloud.google.com/vpc/docs/subnets#purpose for more detailsstring"PRIVATE"no
roleThe role of the subnet when using it as a proxy or loadbalancer network. Whether it is to be used as the active or as a backup subnet, see https://cloud.google.com/load-balancing/docs/proxy-only-subnets#proxy_only_subnet_create for more detailsstring-no
stack_typeIPV4_ONLY or IPV4_IPV6 for dual-stack networkingstring-no
ipv6_access_typeINTERNAL or EXTERNAL. INTERNAL requires ULA be enabled on the VPCstring-no

Route Inputs

The routes list contains maps, where each object represents a route. For the next_hop_* inputs, only one is possible to be used in each route. Having two next_hop_* inputs will produce an error. Each map has the following inputs (please see examples folder for additional references):

NameDescriptionTypeDefaultRequired
nameThe name of the route being createdstring-no
descriptionThe description of the route being createdstring-no
tagsThe network tags assigned to this route. This is a list in string format. Eg. "tag-01,tag-02"string-yes
destination_rangeThe destination range of outgoing packets that this route applies to. Only IPv4 is supportedstring-yes
next_hop_internetWhether the next hop to this route will the default internet gateway. Use "true" to enable this as next hopstring"false"yes
next_hop_ipNetwork IP address of an instance that should handle matching packetsstring-yes
next_hop_instanceURL or name of an instance that should handle matching packets. If just name is specified "next_hop_instance_zone" is requiredstring-yes
next_hop_instance_zoneThe zone of the instance specified in next_hop_instance. Only required if next_hop_instance is specified as a namestring-no
next_hop_vpn_tunnelURL to a VpnTunnel that should handle matching packetsstring-yes
priorityThe priority of this route. Priority is used to break ties in cases where there is more than one matching route of equal prefix length. In the case of two routes with equal prefix length, the one with the lowest-numbered priority value winsstring"1000"yes

Requirements

Installed Software

Configure a Service Account

In order to execute this module you must have a Service Account with the following roles:

  • roles/compute.networkAdmin on the organization or folder

If you are going to manage a Shared VPC, you must have either:

  • roles/compute.xpnAdmin on the organization
  • roles/compute.xpnAdmin on the folder (beta)

Enable API's

In order to operate with the Service Account you must activate the following API on the project where the Service Account was created:

  • Compute Engine API - compute.googleapis.com

Contributing

Refer to the contribution guidelines for
information on contributing to this module.

Contributors

Showing top 12 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from terraform-google-modules/terraform-google-network via the GitHub API.Last fetched: 6/21/2026