How to create a VM(virtual machine) on GCP with Terraform

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.

Set up GCP virtual machine

To set up a Google Cloud Platform (GCP) virtual machine (VM) using Terraform, you need to follow these steps:

  1. 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.

  1. Set up authentication:

  • Create a Google Cloud project: Go to the Google Cloud Console and create a new project or use an existing one.

Google Cloud project
Google Cloud project
  • Enable the Compute Engine API: In the Cloud Console, navigate to "APIs & Services" > "Library," search for "Compute Engine API," and enable it.

Compute Engine API
Compute Engine API
  • Authenticate with gcloud: Run gcloud auth login and follow the instructions to log in and authenticate the SDK with your Google Cloud account.

gcloud auth login
gcloud auth login
  1. 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.

main.tf file contents
main.tf file contents
  1. 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_id
region = "us-central1"
zone = "us-central1-b"
}
resource "google_project_service" "compute_service" {
project = local.project_id
service = "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"
}
}
Provider and VM configuration

Code explanation

  • 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.

Create a VPC network

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 = false
delete_default_routes_on_create = true
depends_on = [
google_project_service.compute_service
]
}
VPC network configuration

Code explanation

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.

Create a private subnetwork

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
}
Private subnetworks configuration

Code explanation

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.

Create a VPC router

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
}
VPC router configuration

Code explanation

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.

Configure NAT (Network Address Translation)

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.name
region = google_compute_router.router.region
nat_ip_allocate_option = "AUTO_ONLY"
source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
}
NAT configuration

Code explanation

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.

Create an internet route for private network

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_link
next_hop_gateway = "default-internet-gateway"
priority = 100
}
Internet route for private network configuration

Code explanation

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_id
region = "us-central1"
zone = "us-central1-b"
}
resource "google_project_service" "compute_service" {
project = local.project_id
service = "compute.googleapis.com"
}
resource "google_compute_network" "vpc_network" {
name = "terraform-network"
auto_create_subnetworks = false
delete_default_routes_on_create = true
depends_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.name
region = google_compute_router.router.region
nat_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_link
next_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_link
subnetwork = google_compute_subnetwork.private_network.self_link
}
}
Overall main.tf

  1. Initialize and apply the configuration:

    1. In the terminal, run terraform init to initialize the Terraform configuration and download the required plugins.

terraform init output
terraform init output

II. Then, run terraform apply to apply the configuration and create the VM. Confirm the action when prompted.

Copyright ©2024 Educative, Inc. All rights reserved