Welcome back to GCP Security and Networking Fundamentals! In this third lesson, we're making an important transition. While the previous two lessons gave you a solid foundation in GCP IAM for controlling who can access your Google Cloud resources, we now shift our focus to the foundational layer that determines where those resources live and how they communicate. Today, we explore Virtual Private Cloud networks (VPCs), which create isolated network environments within Google Cloud where your resources operate securely.
You'll learn to define network address spaces using CIDR notation, divide those spaces into subnets, distribute subnets across regions and zones for resilience, and programmatically manage these networking components using the GCP Discovery API. By the end of this lesson, you'll understand how GCP isolates your infrastructure in its own private network, giving you complete control over IP addressing and network topology.
Before writing any code, let's understand why VPCs are the cornerstone of GCP's networking architecture. A Virtual Private Cloud (VPC) is your own private section of the Google Cloud network, logically isolated from other customers' resources. Imagine GCP as a massive office building: while everyone shares the same physical infrastructure, each company has its own locked office suite, and neighbors can't access your space. Your VPC is that office suite — a logically isolated network where you define address ranges, create subnets, configure routing, and control network gateways.
This isolation is fundamental to cloud security. When you launch a Compute Engine VM, it doesn't just float freely in GCP's network; it lives inside a specific VPC with defined network boundaries. You control which resources can communicate with each other, what traffic flows in and out, and how your private network connects to the public internet or other networks. This level of control mirrors what network administrators have traditionally managed in physical data centers, but with the flexibility and scalability of the cloud. Every VPC requires a CIDR block that defines its overall IP address space, and within that space, you create smaller subnets for organizing and securing different types of resources.
To work effectively with VPCs, you need to understand CIDR notation, which is how we express network address ranges. CIDR stands for Classless Inter-Domain Routing, and it's a compact way to specify both a base IP address and how many addresses the range contains. A CIDR block looks like 10.0.0.0/16, where the number after the slash indicates how many bits are fixed in the network portion of the address.
The formula for calculating available addresses is: , where n is the number after the slash. For example, 10.0.0.0/16 means 16 bits are fixed for the network, leaving 16 bits for host addresses, giving us total IP addresses. Smaller numbers after the slash mean more addresses; provides 65,536 addresses, while provides only 256.
As in Lesson 1 and Lesson 2, this unit continues to use the course's mock GCP environment. To stay consistent across the course, all examples use:
os.environ.get("GCP_DISCOVERY_URL")to retrieve the mock discovery endpointcredentials=Nonewhen building discovery clients
This works because requests are sent to a local practice service rather than real Google Cloud APIs, so real authentication is not required. In production code, you would typically use Application Default Credentials (ADC) instead of credentials=None.
Let's start by setting up our environment and building the discovery client:
This setup uses environment variables to configure all our networking parameters, making it easy to adapt the code for different environments. The discovery client connects to a mock server for safe practice exercises, but the same API patterns work identically against real GCP infrastructure.
Important Note on Naming Conventions: GCP resource names must comply with RFC1035. This means network and subnet names can only contain lowercase letters, digits, and hyphens, must start with a lowercase letter, and must be between 1-63 characters long. Names like my-custom-vpc and my-subnet are valid, but , , or names starting with a digit would be rejected by the API.
Let's build our first VPC programmatically, defining its network mode and routing configuration. In GCP, VPCs are global resources, but their subnets are regional. We'll create a custom-mode VPC where we manually define all subnets, giving us complete control over the network topology.
This function creates a custom VPC network (with auto_create_subnetworks=False, so you define your own subnets). The network is created at the project level and is global in scope. Setting routingMode to REGIONAL means that dynamic routes learned by Cloud Router are only available within the region where they're learned. The IPv4Range field defines the overall CIDR block for the VPC. The function returns the operation name along with network configuration details, which you'll need when creating subnets.
With a VPC established, the next step is dividing that large address space into smaller, manageable pieces called subnets. Each subnet represents a logical subdivision of your VPC's IP range, and subnets serve multiple important purposes in network architecture. Subnets let you organize resources by function or security requirements; for example, you might place web servers in one subnet and databases in another. In GCP, subnets are regional resources, meaning each subnet exists in a single region but can span all zones within that region.
When creating subnets, GCP automatically reserves four IP addresses in every subnet for its internal networking operations. The first address is the network address, the second is reserved for the default gateway, the third is reserved for future use, and the last address is the broadcast address. For a subnet with CIDR block 10.0.1.0/24 (256 total addresses), GCP reserves 10.0.1.0, 10.0.1.1, 10.0.1.2, and 10.0.1.255, leaving 252 addresses for your resources. This reservation applies to every subnet regardless of size, so the impact is proportionally larger on smaller subnets.
Let's implement subnet creation, specifying the region and CIDR block. Note how we construct the network reference using the full selfLink format:
This function creates a subnet within an existing VPC network by providing the network name, region, subnet name, and CIDR range. The subnet's CIDR block must be a subset of the VPC's range and must not overlap with other subnets in the same VPC. In GCP, subnets are regional, so you specify the region (e.g., us-central1). The subnet can be used by resources in any zone within that region. The network_self_link is constructed in the format expected by the GCP Compute API, referencing the global network resource.
GCP regions are named like us-central1, europe-west1, etc., and each region contains multiple zones, such as us-central1-a, us-central1-b, and so on. Unlike some other clouds, GCP's region and zone names are consistent across all projects and accounts.
For this course, we use hardcoded region and zone names in examples (configurable via environment variables) to keep the code simple and focused on core concepts. In production environments, you would typically discover available regions and zones dynamically using the regions and zones list APIs.
Understanding exactly how many usable IP addresses a CIDR block provides is crucial for capacity planning. Let's build a calculator that reveals both theoretical and practical IP counts, accounting for GCP's four-address reservation per subnet.
This function extracts the prefix length from a CIDR string, calculates the total number of IP addresses, and subtracts GCP's four reserved addresses to determine what's actually usable for resources. The max() function ensures we never return a negative number for very small subnets. This calculation is valuable before creating subnets because it helps you verify that your chosen CIDR block provides enough addresses for your planned resources.
After building networking infrastructure, you often need to inspect what you've created to verify configurations or troubleshoot issues. Let's implement a VPC inspector using the discovery API's aggregated list method:
This function first retrieves the VPC network resource itself so we can include basic network-level configuration such as its CIDR block and whether it auto-creates subnetworks. It then enumerates all subnets belonging to this network using the aggregated list API. The aggregated API returns results grouped by scope (typically by region), so we iterate through each scope's subnets, filtering for those that belong to our target network. For each matching subnet, we extract its name, CIDR block, region, and gateway address. The final return dictionary provides both VPC-level information and a detailed subnet inventory.
Let's execute our complete networking stack: creating a VPC, adding a subnet, and analyzing the results to see exactly what we've built.
This orchestration demonstrates the complete lifecycle of VPC creation and configuration. We start by creating a VPC with a custom name, receiving an operation identifier that tracks the creation process. Next, we carve out a subnet with the /24 CIDR block (by default 10.0.1.0/24) in the configured region (by default us-central1). After creating resources, we retrieve complete details about our VPC, which now includes both network-level settings and a subnet inventory. Finally, we calculate capacity for both a typical VPC CIDR (10.0.0.0/16) and our specific subnet: for the VPC, we report total addresses (no reservation at the VPC level), and for the /24 subnet, we see 256 total with only 252 usable after GCP's four-address reservation.
You've now built the foundation of GCP networking by creating isolated Virtual Private Cloud networks, dividing them into subnets with precise CIDR blocks, and distributing those subnets across regions for resilience. You've learned to calculate IP address capacity, account for GCP's reservations, create network infrastructure programmatically using the Google Discovery API, and inspect configurations to understand how address spaces are organized. These VPC fundamentals form the backbone of every GCP deployment, providing the isolated network environment where your applications and data reside securely.
The practice exercises ahead will challenge you to design multi-subnet architectures, experiment with different CIDR allocations, and create networks that span multiple regions. This hands-on experience will transform the theory you've learned into practical networking skills you'll use throughout your GCP journey, building upon the IAM and service account knowledge you've already mastered to create comprehensive, secure cloud infrastructures.
