Infrastructure-as-Code (IaC) has fundamentally shifted how engineering teams approach cloud provisioning, moving away from manual console clicks and fragile shell scripts toward deterministic, version-controlled deployments. At the forefront of this paradigm shift stands HashiCorp Terraform, a declarative tool that allows users to define the desired state of their infrastructure in code. For organizations leveraging Google Cloud Platform, the integration between Terraform and the Google Provider is seamless, particularly when managing the foundational networking layer. The google_compute_network resource represents the virtual private cloud (VPC) backbone of any Compute Engine deployment. Understanding its properties, lifecycle, state management, and integration with other resources is critical for building scalable, secure, and maintainable cloud environments. This article provides an expert-level examination of deploying, inspecting, and modifying VPC networks using Terraform, dissecting the execution plans, state file mechanics, and the specific attributes that govern network behavior.
Foundational Architecture: How Terraform Interacts with Compute Engine
To effectively utilize the google_compute_network resource, one must first grasp the operational model of Terraform. Terraform is not merely a deployment tool; it is a stateful orchestrator. It operates on a declarative and configuration-oriented syntax, meaning users describe what the infrastructure should look like, not how to build it step-by-step. This distinction is crucial for engineers transitioning from imperative scripting languages to infrastructure code. You define the network, the subnets, and the firewall rules in configuration files, and Terraform’s logic engine determines the necessary actions to reconcile the current state with the desired state.
The interaction between Terraform and Google Cloud is mediated through plugins known as providers. The Google Provider specifically exposes the Google Cloud APIs as Terraform resources. For Compute Engine resources, the provider handles the complexity of API authentication, retries, and resource dependencies. When you include the google_compute_network resource in your configuration, you are instructing the Terraform CLI to interact with the Compute Engine API via the Google Provider. The resource type google_compute_network maps directly to the provider name google, establishing a clear namespace for all Google Cloud resources managed by Terraform. This naming convention ensures that resource identifiers are unique and traceable, which is essential for multi-cloud or hybrid environments where other providers (such as aws or azurerm) may be present in the same workspace.
Authentication is a prerequisite for any infrastructure modification. Terraform relies on the Google Cloud SDK, specifically the gcloud CLI, to establish secure credentials. Before executing any terraform plan or terraform apply commands that affect Google Cloud resources, the environment must be configured with Application Default Credentials. This is achieved by running gcloud auth application-default login in the terminal. This command initiates a browser-based login flow, allowing the user to authorize the Terraform process to access their Google Cloud account. Once authenticated, Terraform can securely read the current state of the infrastructure and apply changes without manual intervention.
Anatomy of the googlecomputenetwork Resource
The google_compute_network resource block is where the core configuration of the VPC is defined. In a standard Terraform configuration file, a resource block defines the resource type, a unique local name, and a set of arguments. For example, a resource might be defined as google_compute_network.vpc_network. Here, google_compute_network is the resource type, and vpc_network is the logical name assigned by the developer. Together, these form a unique ID for the resource within the Terraform state file. This ID is critical for referencing the resource in other parts of the configuration, such as when assigning a network to a virtual machine instance.
The arguments within this resource block dictate the behavior of the VPC. These arguments are categorized into required and optional, as documented in the Terraform Registry. Key attributes include:
| Attribute | Description | Type | Default/Note |
|---|---|---|---|
name |
The name of the network resource. | String | Required |
auto_create_subnetworks |
Specifies whether the project should automatically create subnetworks in each region. | Boolean | true |
routing_mode |
Determines whether the network uses regional or global routing mode. | String | REGIONAL or GLOBAL |
mtu |
The maximum transmission unit, in bytes, for packets on this network. | Integer | 0 (auto) |
network_firewall_policy_enforcement_order |
Defines the order in which firewall rules are evaluated. | String | AFTER_CLASSIC_FIREWALL |
description |
An optional description of the resource. | String | null |
delete_default_routes_on_create |
Specifies whether default routes to the internet should be deleted upon creation. | Boolean | false |
The auto_create_subnetworks argument is particularly significant for legacy and new VPCs. When set to true, the system creates a default subnet in every region, which simplifies initial setup but can limit flexibility for strict network segmentation strategies. Conversely, setting it to false requires the explicit definition of google_compute_subnetwork resources, offering greater control over IP range allocation and zone-specific routing. The routing_mode attribute further differentiates the network’s scope; REGIONAL mode restricts routes to the specific region, while GLOBAL mode allows for more complex, cross-regional routing scenarios.
Execution Plan and Previewing Changes
Before any infrastructure is touched, Terraform executes a terraform plan command. This command evaluates the configuration files against the current state and generates an execution plan. The output of this command is a critical artifact for engineering review, as it predicts exactly what changes will be made. The format of this plan is designed to be easily readable, utilizing symbols similar to the diff output of version control systems like Git.
When creating a new network, the plan output will display a plus sign (+) next to the resource declaration. This indicates that the resource does not exist in the current state and will be created. The plan lists the arguments that will be set. A key concept in Terraform’s planning phase is the attribute value marked as (known after apply). This designation appears for values that are generated by the cloud provider during the creation process and cannot be predicted by the plan. For instance, the id, gateway_ipv4, numeric_id, and self_link of a network are often assigned by Google Cloud upon resource creation. Therefore, during the planning phase, these fields appear as (known after apply).
Consider the following execution plan output for a new VPC:
```text
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# googlecomputenetwork.vpcnetwork will be created
+ resource "googlecomputenetwork" "vpcnetwork" {
+ autocreatesubnetworks = true
+ deletedefaultroutesoncreate = false
+ gatewayipv4 = (known after apply)
+ id = (known after apply)
+ internalipv6range = (known after apply)
+ mtu = (known after apply)
+ name = "terraform-network"
+ networkfirewallpolicyenforcementorder = "AFTERCLASSICFIREWALL"
+ numericid = (known after apply)
+ project = (known after apply)
+ routingmode = (known after apply)
+ selflink = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
```
This output serves as a safety checkpoint. If any part of the plan appears incorrect or dangerous—for example, if it proposes destroying a production database or modifying a critical firewall rule—it is safe to abort the process without making any changes to the infrastructure. The plan is read-only and does not interact with the cloud provider to make modifications. Once the engineer is satisfied that the plan aligns with the intent, they proceed to the application phase.
Applying Configuration and State Management
The transition from plan to reality occurs with the terraform apply command. When executed, Terraform presents the execution plan again and prompts the user for confirmation. In non-interactive environments or when the plan is trusted, users can type yes to proceed. The application process involves the Terraform CLI communicating with the Google Provider, which in turn makes API calls to the Google Cloud Platform.
The console output during an apply operation provides real-time feedback on the progress of resource creation. For a VPC network, the creation process is typically fast but involves background coordination within Google’s infrastructure. The output will indicate that the resource is being created, followed by status updates if the operation takes longer than a few seconds.
```text
$ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions
are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# googlecomputenetwork.vpcnetwork will be created
+ resource "googlecomputenetwork" "vpcnetwork" {
+ autocreatesubnetworks = true
+ deletedefaultroutesoncreate = false
+ gateway_ipv4 = (known after apply)
+ id = (known after apply)
# (10 omitted attributes)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
googlecomputenetwork.vpcnetwork: Creating...
googlecomputenetwork.vpcnetwork: Still creating... [10s elapsed]
googlecomputenetwork.vpcnetwork: Still creating... [20s elapsed]
googlecomputenetwork.vpcnetwork: Still creating... [30s elapsed]
googlecomputenetwork.vpc_network: Creation complete after 38s [id=projects/testing-project/global/networks/terraform-network]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```
Upon successful completion, the console reports Apply complete! Resources: 1 added, 0 changed, 0 destroyed. This summary confirms that the infrastructure now matches the configuration. The resource ID, projects/testing-project/global/networks/terraform-network, is now recorded in the state file. This ID is critical for subsequent operations, as it allows Terraform to identify the specific remote object it manages.
The state file is the heart of Terraform’s functionality. It is a local or remote data store that maps your defined infrastructure to the real objects created in your cloud provider. It stores the resource IDs, attributes, and dependencies. For production environments, it is strongly recommended to store this state file remotely using services like HCP Terraform or Terraform Enterprise. Local state files are susceptible to corruption or loss and do not support concurrent operations by multiple engineers. Remote backends provide locking mechanisms, version history, and shared access, ensuring that the state remains consistent and accessible across the team.
Inspecting Current State with terraform show
After a successful apply, the terraform show command becomes an invaluable tool for inspecting the current state. This command reads the state file and displays the current attributes of the resources as Terraform understands them. It is particularly useful for verifying that the resource was created with the expected properties and for retrieving attribute values that were (known after apply) during the plan phase.
Running terraform show on the previously created network reveals the populated state:
```text
$ terraform show
googlecomputenetwork.vpc_network:
resource "googlecomputenetwork" "vpcnetwork" {
autocreatesubnetworks = true
deletedefaultroutesoncreate = false
description = null
enableulainternalipv6 = false
gatewayipv4 = null
id = "projects/test-project/global/networks/terraform-network"
internalipv6range = null
mtu = 0
name = "terraform-network"
networkfirewallpolicyenforcementorder = "AFTERCLASSICFIREWALL"
numericid = "1234567890123456789"
project = "test-project"
routingmode = "REGIONAL"
selflink = "https://www.googleapis.com/compute/v1/projects/test-project/global/networks/terraform-network"
}
```
In this output, note that id, numeric_id, and self_link now contain concrete values rather than placeholders. The self_link is the API URL for the network, which can be used in other configurations or for debugging API calls directly. The numeric_id is a unique identifier assigned by Google Cloud, distinct from the user-defined name. Terraform gathers this metadata from the Google provider and records it in the state file. Later in your configuration, you can reference these values using interpolation, such as ${google_compute_network.vpc_network.self_link}, to configure other resources or to output values for use in external systems.
Modifying Resources: In-Place Updates vs. Destructive Changes
One of the primary strengths of Terraform is its ability to manage ongoing changes to infrastructure. When a configuration file is modified, Terraform compares the new configuration with the current state to determine the necessary updates. Not all changes are treated equally. Some changes result in in-place updates, while others require the resource to be destroyed and recreated.
For the google_compute_network resource, most attribute changes are treated as in-place updates. However, certain critical changes may require replacement. A "destructive change" is defined as a change that requires the provider to replace the existing resource rather than updating it in-place. This is a critical distinction because destroying and recreating a VPC network can cause significant downtime for any resources attached to it, such as Compute Engine instances.
Consider a scenario where you need to add tags to a Compute Engine instance associated with this network. While the google_compute_network resource itself does not support tags in the same way instances do, other resources within the network do. Let’s look at a modification to a google_compute_instance resource to illustrate how Terraform handles changes. Suppose you add a tags argument to your instance resource:
hcl
resource "google_compute_instance" "vm_instance" {
name = "terraform-instance"
machine_type = "f1-micro"
network_interface {
network = google_compute_network.vpc_network.self_link
}
tags = ["web", "dev"]
}
When you run terraform apply again, Terraform will refresh the state of all resources first. The output will show a tilde symbol (~) next to the resource declaration, indicating an in-place update.
```text
$ terraform apply
googlecomputenetwork.vpcnetwork: Refreshing state... [id=projects/testing-project/global/networks/terraform-network]
googlecomputeinstance.vminstance: Refreshing state... [id=projects/testing-project/zones/us-central1-c/instances/terraform-instance]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# googlecomputeinstance.vminstance will be updated in-place
~ resource "googlecomputeinstance" "vminstance" {
id = "projects/testing-project/zones/us-central1-c/instances/terraform-instance"
name = "terraform-instance"
~ tags = [
+ "dev",
+ "web",
]
# (15 unchanged attributes hidden)
# (3 unchanged blocks hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
```
The prefix ~ signifies that the resource will be updated in-place without being destroyed. You can apply this change by responding yes, and Terraform will add the tags to the instance. This in-place update is non-destructive and does not interrupt the instance's operation. Understanding the difference between + (create), ~ (update in-place), and -/+ (replace/destroy and create) is essential for predicting the impact of configuration changes.
For the google_compute_network resource specifically, changing the name would likely result in a replacement (-/+) because the network ID is tied to the name. However, changing the auto_create_subnetworks flag might be handled differently depending on the provider version and the specific constraints of the VPC. Engineers must always review the plan carefully to identify if a change will trigger a destructive replacement before approving the apply command.
Best Practices for Production Environments
While local state management is suitable for development and learning, production environments demand higher standards of reliability and security. As noted in best practices, storing your state remotely with HCP Terraform or Terraform Enterprise is recommended. These services provide a centralized, secure location for state files, ensuring that multiple team members can work on the same infrastructure without conflicts. They also offer features like remote execution, policy as code, and audit logging.
When defining google_compute_network resources in production, it is advisable to explicitly define google_compute_subnetwork resources rather than relying on auto_create_subnetworks = true. This approach allows for precise control over IP ranges, ensuring that subnets in different regions or zones do not overlap. It also facilitates the application of specific firewall policies to subnets, enhancing security granularity. Furthermore, setting routing_mode to REGIONAL is often preferred for multi-region deployments to ensure that traffic flows predictably within defined boundaries.
The use of terraform show and terraform plan should be standard practices in CI/CD pipelines. By generating plans in automated workflows, teams can detect potential destructive changes before they reach production. This shift-left approach to infrastructure validation reduces the risk of accidental deletions or misconfigurations.
Conclusion
The google_compute_network resource is the cornerstone of Google Cloud infrastructure managed by Terraform. It encapsulates the complexity of VPC networking into a manageable, declarative interface. By understanding the resource’s attributes, the mechanics of the execution plan, and the nuances of state management, engineers can build robust cloud architectures. The ability to preview changes via terraform plan, inspect real-world attributes via terraform show, and apply modifications safely via terraform apply empowers teams to manage infrastructure with precision and confidence. As cloud architectures grow in complexity, the integration of Terraform with the Google Provider provides a scalable path to managing networking resources, ensuring that every change is tracked, reviewed, and executed deterministically. Mastery of these tools and concepts is not merely beneficial but essential for modern cloud engineering roles, enabling the delivery of reliable, secure, and efficient infrastructure at scale.