Setting up a Google Cloud Platform (GCP) virtual machine (VM) using Terraform offers an efficient way to automate infrastructure provisioning and management. Terraform, an Infrastructure as Code (IaC) tool, allows users to define their desired cloud infrastructure using declarative code, ensuring consistent and reproducible environments. GCP, one of the leading cloud service providers, offers a vast array of services, and Terraform simplifies the process of creating, modifying, and destroying resources within this cloud ecosystem.
By employing Terraform's concise and human-readable configuration language (HCL), Infrastructure as Code becomes accessible to a broader range of users, from seasoned cloud engineers to developers and operations teams, empowering them to efficiently manage complex cloud infrastructure.
To set up a Google Cloud Platform (GCP) virtual machine (VM) using Terraform, you need to follow these steps:
Install required tools:
Install Terraform: Download and install Terraform from the official website and ensure it is added to your system's PATH.
Install the Google Cloud SDK: Follow this Answer to install the Google Cloud SDK, which includes the gcloud
command-line tool.
Set up authentication:
Create a Google Cloud project: Go to the Google Cloud Console and create a new project or use an existing one.
Enable the Compute Engine API: In the Cloud Console, navigate to "APIs & Services" > "Library," search for "Compute Engine API," and enable it.
Authenticate with gcloud: Run gcloud auth login
and follow the instructions to log in and authenticate the SDK with your Google Cloud account.
Create a Terraform configuration file:
Create a new directory for your Terraform configuration and navigate to it in the terminal.
Create a file named main.tf
in this directory. This is where you'll define the Terraform configuration.
Define the provider and VM Configuration:
In the main.tf
file, specify the GCP provider and the VM resource. Here's a basic example:
locals {project_id = var.project_id}provider "google" {project = local.project_idregion = "us-central1"zone = "us-central1-b"}resource "google_project_service" "compute_service" {project = local.project_idservice = "compute.googleapis.com"}resource "google_compute_instance" "vm_instance" {name = "nginx-instance"machine_type = "f1-micro"tags = ["nginx-instance"]boot_disk {initialize_params {image = "centos-7-v20210420"}}
The code starts by defining a local variable project_id
using the user-provided input variable var.project_id
, which represents the GCP project ID where resources will be created.
Next, the GCP provider is configured with the google
provider block. It sets the GCP project ID to the previously defined local variable project_id
. The region is set to us-central1
, and the zone is set to us-central1-b
, specifying the location for resource creation.
A google_project_service
resource is defined to enable the Compute Engine API (compute.googleapis.com
) for the specified GCP project. This API is essential for creating compute resources like virtual machines.
Finally, a google_compute_instance
resource is defined to create a GCP virtual machine instance. The VM will be named nginx-instance
and will use the f1-micro
machine type, which provides limited resources. The VM's boot disk is initialized with the CentOS 7 image specified as centos-7-v20210420
.
A VPC network provides a logically isolated and private environment within GCP. It allows you to segment your resources and control their communication, providing a secure and controlled infrastructure.
resource "google_compute_network" "vpc_network" {name = "terraform-network"auto_create_subnetworks = falsedelete_default_routes_on_create = truedepends_on = [google_project_service.compute_service]}
The new resource block creates a Google Compute Engine network in the specified GCP project.
The name
attribute sets the name of the Virtual Private Cloud (VPC) network to terraform-network
. This network will be identified by this name within the GCP project.
The auto_create_subnetworks
attribute is set to false
. This means that no subnetworks will be automatically created within this VPC network. Subnetworks will need to be created manually.
The delete_default_routes_on_create
attribute is set to true
. When creating a custom network, this setting will delete the default routes that are automatically created for the network.
The depends_on
attribute specifies that the creation of this VPC network depends on the successful creation of the google_project_service.compute_service
. This ensures that the Compute Engine API (compute.googleapis.com
) is enabled before creating the VPC network.
Creating a private subnetwork in Google Cloud Platform (GCP) allows you to further segment your Virtual Private Cloud (VPC) network into smaller subnets with distinct IP address ranges. Each subnetwork can be associated with a specific region and can contain a subset of resources within the larger VPC.
resource "google_compute_subnetwork" "private_network" {name = "private-network"ip_cidr_range = "10.2.0.0/16"network = google_compute_network.vpc_network.self_link}
The new resource block creates a Google Compute Engine subnetwork within the previously defined VPC network.
The name
attribute sets the name of the subnetwork to "private-network". This name is used to identify the subnetwork within the GCP project.
The ip_cidr_range
attribute defines the IP address range for the subnetwork. Here, it is set to 10.2.0.0/16
, which means the subnetwork will have a private IP address range from 10.2.0.0 to 10.2.255.255.
The network
attribute specifies the self_link
of the VPC network where the subnetwork will be created. The google_compute_network.vpc_network
is a reference to the previously defined VPC network resource, and self_link
retrieves the unique identifier of that network.
VPC router in Google Cloud Platform (GCP) enables the establishment of network connectivity and routing capabilities within your Virtual Private Cloud (VPC) network. The VPC router acts as a central hub for handling traffic between subnets and external networks.
resource "google_compute_router" "router" {name = "quickstart-router"network = google_compute_network.vpc_network.self_link}
The new resource block creates a Google Compute Engine router within the specified VPC network.
The name
attribute sets the name of the router to quickstart-router
. This name is used to identify the router within the GCP project.
The network
attribute specifies the self_link of the VPC network where the router will be associated. The google_compute_network.vpc_network
is a reference to the previously defined VPC network resource, and .self_link
retrieves the unique identifier of that network.
Configuring NAT (Network Address Translation) in Google Cloud Platform (GCP) with a VPC router enables instances within private subnets to access the internet or external services using a single or a pool of public IP addresses. NAT allows private IP addresses to be translated into a publicly routable IP address when communicating with resources outside the VPC.
resource "google_compute_router_nat" "nat" {name = "quickstart-router-nat"router = google_compute_router.router.nameregion = google_compute_router.router.regionnat_ip_allocate_option = "AUTO_ONLY"source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"}
The new resource block creates a Google Compute Engine NAT (Network Address Translation) configuration within the previously defined router.
The name
attribute sets the name of the NAT configuration to quickstart-router-nat
. This name is used to identify the NAT configuration within the GCP project.
The router
attribute specifies the name of the router to which the NAT configuration will be associated. The value is taken from the name
attribute of the previously defined google_compute_router.router
resource.
The region
attribute specifies the region where the router is located. The value is taken from the region
attribute of the previously defined google_compute_router.router
resource.
The nat_ip_allocate_option
attribute sets the NAT IP allocation option. Here, it is set to AUTO_ONLY
, which means the NAT IP addresses will be automatically allocated from the available pool.
The source_subnetwork_ip_ranges_to_nat
attribute determines which subnetwork IP ranges are subjected to NAT. Here, it is set to ALL_SUBNETWORKS_ALL_IP_RANGES,
which means that all IP ranges from all subnetworks associated with the router will be subject to NAT.
Internet route for a private network in Google Cloud Platform (GCP) enables instances within a private subnet to access the internet for outbound communication. This is achieved by routing traffic destined for the internet through a specific route in the VPC network.
resource "google_compute_route" "private_network_internet_route" {name = "private-network-internet"dest_range = "0.0.0.0/0"network = google_compute_network.vpc_network.self_linknext_hop_gateway = "default-internet-gateway"priority = 100}
The new resource block creates a Google Compute Engine route within the specified VPC network to allow outbound internet access for the private network.
The name
attribute sets the name of the route to private-network-internet
. This name is used to identify the route within the GCP project.
The dest_range
attribute specifies the destination IP range for the route. Here, it is set to 0.0.0.0/0
, which represents all IP addresses. This means the route will apply to all outbound traffic from the private network.
The network
attribute specifies the self_link of the VPC network where the route will be associated. The google_compute_network.vpc_network
is a reference to the previously defined VPC network resource, and .self_link
retrieves the unique identifier of that network.
The next_hop_gateway
attribute sets the next hop for the route. In this case, it is set to default-internet-gateway
, indicating that the outbound traffic will be forwarded to the default internet gateway to access the internet.
The priority
attribute sets the priority of the route. The priority determines the precedence of the route when multiple routes match the same destination. Here, it is set to 100
, which means it has a higher priority compared to routes with lower values (e.g., default routes).
Here's the overall code in the main.tf
file:
variable "project_id" {type = string}locals {project_id = var.project_id}provider "google" {project = local.project_idregion = "us-central1"zone = "us-central1-b"}resource "google_project_service" "compute_service" {project = local.project_idservice = "compute.googleapis.com"}resource "google_compute_network" "vpc_network" {name = "terraform-network"auto_create_subnetworks = falsedelete_default_routes_on_create = truedepends_on = [google_project_service.compute_service]}resource "google_compute_subnetwork" "private_network" {name = "private-network"ip_cidr_range = "10.2.0.0/16"network = google_compute_network.vpc_network.self_link}resource "google_compute_router" "router" {name = "quickstart-router"network = google_compute_network.vpc_network.self_link}resource "google_compute_router_nat" "nat" {name = "quickstart-router-nat"router = google_compute_router.router.nameregion = google_compute_router.router.regionnat_ip_allocate_option = "AUTO_ONLY"source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"}resource "google_compute_route" "private_network_internet_route" {name = "private-network-internet"dest_range = "0.0.0.0/0"network = google_compute_network.vpc_network.self_linknext_hop_gateway = "default-internet-gateway"priority = 100}resource "google_compute_instance" "vm_instance" {name = "nginx-instance"machine_type = "f1-micro"tags = ["nginx-instance"]boot_disk {initialize_params {image = "centos-7-v20210420"}}network_interface {network = google_compute_network.vpc_network.self_linksubnetwork = google_compute_subnetwork.private_network.self_link}}
Initialize and apply the configuration:
In the terminal, run terraform init
to initialize the Terraform configuration and download the required plugins.
II. Then, run terraform apply
to apply the configuration and create the VM. Confirm the action when prompted.