How to setup Virtual machine on Google Cloud Platform
Working on a cloud platform always sounds interesting but what if you have some framework where you can automate your cloud infrastructure. In this article, we are going to see How to set up your first Virtual Machine on Google Cloud The platform using Terraform
This article is aimed at the beginner who is just starting with Terraform and Google Cloud Platform(GCP).
Prerequisite
- The only prerequisite is - You must install Terraform before jumping to Google Cloud Setup.
Table of Content
- Create a project on GCP
- Create Service Account
- Assign additional roles to the Service Account
- Generate Keys for Service Account
- Prepare terraform file
main.tf
(Add google provider details along with google_compute_instance) - Run - terraform init, terraform plan, terraform apply
- Setup Network and Firewall for virtual machine
- Verify your Setup
- Destroy Virtual Machine on Google Cloud
- Conclusion
1. Create a project on GCP (Google Cloud Platform)
I am assuming you already have GCP account, if not then I would suggest you use 1 Year free GCP account.
Alright so to begin with the first thing which we are going to do is Create Project on GCP.
Head over to GCP and create your First Project.
Click on the New Project
For this article, I have created a project with the name gcp-terraform
2.Create a Service account for the project
In the second step, we need to create the Service Account inside the project which we created in the Step 1
Before creating the service account make sure to select the project which you created.
Head over to left navigation and select IAM & Admin -> Service Accounts
It will redirect you to Service Account to create the page.
Now you need to input some meaningful name for the service account. In my case, I have kept the name gcp-terraform-acc
3. Assign additional roles to the Service Account
3.1 Add Project --> Owner role
Now you have created your service account and in the third step we are going to create our first role for the service account.
In the roles dropdown look for Project and inside project add Owner role. (Refer to the screenshot)
Project --> Owner
3.2 Add Compute --> Compute admin role
The next role which we need is Compute Admin Role available inside Compute
Compute Engine --> Compute Admin Role
3.3 Add Compute --> Compute Network Admin
The third role which you need to add is Compute Network Admin available inside Compute
Compute Engine --> Compute Network Admin
4. Generate Keys for Service Account
After adding the roles now we need to generate the keys for the authorization. We are going to use these keys from our Terrafrom module later.
From the service account list select the account which you have created (In my case the service account name is gcp-terrafrom-acc) and then click on the 3 dots options.
Now you need to look for the manage keys options -
Under the Keys section click on ADD KEY -> Create New Key
In the next option, you need to select the type of key. For the current example, we are going to select the JSON.
Now you need to download the key and save it somewhere onto your local computer. (It would be nice if you could rename the file JSON keys file, I have renamed it - gcp-account.json but you can choose any name of your choice)
5. Prepare terraform file "main.tf"
Now we are going to write our first Terrafrom script.
Create a file named main.tf
5.1 Add the provider details
As you know we are going to provision the virtual machine on Google, so we need to select the provider as google.
1 provider "google" {
2 credentials = file("gcp-account.json")
3 project = "gcp-terraform-307119"
4 region = "europe-west4"
5 zone = "europe-west4-a"
6}
Few points to take care -
- gcp-account.json - It is the JSON key file which we have downloaded in Step 4 . Please save the gcp-account.json at the same location where you have created main.tf
- project - You need to mention the Project ID from your google console
- region && zone - Select the region and zone which is near from your current location
5.2 Add "google_compute_instance" instance
Since we aim to create a Virtual Machine on Google Cloud Platform, so we need to add google_compute_instance
configuration.
1# main.tf
2
3resource "google_compute_instance" "default" {
4 name = "test"
5 machine_type = "e2-micro"
6
7 boot_disk {
8 initialize_params {
9 image = "debian-cloud/debian-9"
10 }
11 }
12
13 # To keep the setup simple you can set the network_interface to default
14 # For Advance network setup refer to Point-7 : Setup Network and Firewall for virtual machine
15 network_interface {
16 network = "default"
17
18 access_config {
19 // Ephemeral IP
20 }
21 }
22}
Few points to take care -
- name - You can keep the name of your virtual instance as per your choice
- machine_type - I have chosen e2-micro but you can choose from - e2-small, e2-medium, e2-standard-2 etc.
- boot_disk - Here you need to mention the host OS and I have opted for -
debian-cloud/debian-9
- network_interface - This configuration is needed for getting the IP address of the virtual machine.
6. Run - terraform init, terraform plan, terraform apply
Now we have completed all the pre-requisites needed for provisioning the Virtual Machine(VM) on Google Cloud.
The first command which we are going to run is -
6.1 terraform init
The first command we need to run is -
1terraform init
This command is going to download all the required dependencies based on the provider name mentioned in the main.tf
.
In the current example the provider name is Google so it is going to install Google's terraform
dependencies onto your laptop.
You should see something similar in your console -
1Initializing the backend...
2
3Initializing provider plugins...
4- Reusing the previous version of hashicorp/google from the dependency lock file
5- Installing hashicorp/google v3.59.0...
6- Installed hashicorp/google v3.59.0 (signed by HashiCorp)
7
8Terraform has been successfully initialized!
6.2 terraform plan
The second command which we are going to run is -
1terraform plan
This command tells you -
- How many resources are going to be created
- How many resources are going to be destroyed
- How many resources are going to change.
Note - terraform plan never creates the VM on google plan, it just tells you what it is going to perform.
As you know this is our first example so the terraform plan
is going to create 1 resource for us.
Here is the output of the command -
1An execution plan has been generated and is shown below.
2Resource actions are indicated with the following symbols:
3 + create
4
5Terraform will perform the following actions:
6
7 # google_compute_instance.default will be created
8 + resource "google_compute_instance" "default" {
9 + can_ip_forward = false
10 + cpu_platform = (known after apply)
11 + current_status = (known after apply)
12 + deletion_protection = false
13 + guest_accelerator = (known after apply)
14 + id = (known after apply)
15 + instance_id = (known after apply)
16 + label_fingerprint = (known after apply)
17 + machine_type = "e2-micro"
18 + metadata_fingerprint = (known after apply)
19 + min_cpu_platform = (known after apply)
20 + name = "test"
21 + project = (known after apply)
22 + self_link = (known after apply)
23 + tags_fingerprint = (known after apply)
24 + zone = (known after apply)
25
26 + boot_disk {
27 + auto_delete = true
28 + device_name = (known after apply)
29 + disk_encryption_key_sha256 = (known after apply)
30 + kms_key_self_link = (known after apply)
31 + mode = "READ_WRITE"
32 + source = (known after apply)
33
34 + initialize_params {
35 + image = "debian-cloud/debian-9"
36 + labels = (known after apply)
37 + size = (known after apply)
38 + type = (known after apply)
39 }
40 }
41
42 + confidential_instance_config {
43 + enable_confidential_compute = (known after apply)
44 }
45
46 + network_interface {
47 + name = (known after apply)
48 + network = "default"
49 + network_ip = (known after apply)
50 + subnetwork = (known after apply)
51 + subnetwork_project = (known after apply)
52
53 + access_config {
54 + nat_ip = (known after apply)
55 + network_tier = (known after apply)
56 }
57 }
58
59 + scheduling {
60 + automatic_restart = (known after apply)
61 + on_host_maintenance = (known after apply)
62 + preemptible = (known after apply)
63
64 + node_affinities {
65 + key = (known after apply)
66 + operator = (known after apply)
67 + values = (known after apply)
68 }
69 }
70 }
71
72Plan: 1 to add, 0 to change, 0 to destroy.
73
74------------------------------------------------------------------------
6.3 terraform apply
The final command which we are going to run is terraform apply
.
This command is going to install/setup the virtual machine on Google Cloud.
1terraform apply
After running the above command you should see the following message on your terminal
1
2Do you want to perform these actions?
3 Terraform will perform the actions described above.
4 Only 'yes' will be accepted to approve.
5
6 Enter a value: yes
7
8google_compute_instance.default: Creating...
9google_compute_instance.default: Still creating... [10s elapsed]
10google_compute_instance.default: Creation complete after 15s [id=projects/gcp-terraform-307119/zones/europe-west4-a/instances/test]
11
12Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
If you see a similar message on your terminal which means it is has provisioned the Virtual Machine successfully on Google Cloud.
(If you face issue - Error creating service account: googleapi: Error 403: Identity and Access Management (IAM) API has not been used in project 46864460xxxx before or it is disabled - Click here for troubleshooting)
7. Setup Network and Firewall for virtual machine
To start with the network setup first we need to create the VPC(Virtual Private Network). Please refer to the following Terraform configuration for VPC and Subnet -
1. Create VPC and Subnet configuration
1# main.tf
2# Please append the following VPC code to main.tf explained in point 5.2
3
4resource "google_compute_network" "vpc" {
5 name = "test-vpc-for-vm"
6 auto_create_subnetworks = "false"
7 routing_mode = "GLOBAL"
8}
9
10# create the public subnet
11resource "google_compute_subnetwork" "test_public_subnet" {
12 name = "test-public-subnet-1"
13 ip_cidr_range = "10.10.1.0/24"
14 network = google_compute_network.vpc.name
15 region = "europe-west1"
16}
17
2. Set Firewall Rules - To work with a virtual machine or any kind of Linux server we need to set the following rules -
1. Allow Port 80 - This port will allow you to send HTTP traffic.
2. Allow Port 443 - This port will enable the HTTPS on all incoming and outgoing traffic.
3. Allow Port 22 - This port is for allowing SSH traffic so that developers like us can SSH into the server.
4. Allow Port 3389 - This port will allow the RDP traffic.
Here is the Terraform configuration which you can add to your Terraform file -
1# main.tf
2# Please append the following VPC code to main.tf explained in point 5.2
3
4 # Enable port 90 to allow http traffic
5resource "google_compute_firewall" "allow-http" {
6 name = "test-fw-allow-http"
7 network = "${google_compute_network.vpc.name}"
8 allow {
9 protocol = "tcp"
10 ports = ["80"]
11 }
12 target_tags = ["http"]
13}
14
15# Enable port 443 to allow https traffic
16resource "google_compute_firewall" "allow-https" {
17 name = "test-fw-allow-https"
18 network = "${google_compute_network.vpc.name}"
19 allow {
20 protocol = "tcp"
21 ports = ["443"]
22 }
23 target_tags = ["https"]
24}
25
26# Enable port 22 to allow ssh traffic
27resource "google_compute_firewall" "allow-ssh" {
28 name = "${var.app_name}-fw-allow-ssh"
29 network = "${google_compute_network.vpc.name}"
30 allow {
31 protocol = "tcp"
32 ports = ["22"]
33 }
34 target_tags = ["ssh"]
35}
36
37# Enable port 3389 to allow rdp traffic
38resource "google_compute_firewall" "allow-rdp" {
39 name = "${var.app_name}-fw-allow-rdp"
40 network = "${google_compute_network.vpc.name}"
41 allow {
42 protocol = "tcp"
43 ports = ["3389"]
44 }
45 target_tags = ["rdp"]
46}
3. Setup Virtual Machine- Now let's setup the Virtual Machine on Google cloud using above mentioned network configuration -
1# main.tf
2# append following configuration
3
4# Create VM #1
5resource "google_compute_instance" "test_vm_instance_public" {
6 name = "test-vm-instance"
7 machine_type = "f1-micro"
8 zone = "europe-west1"
9 hostname = "testvm-${var.app_domain}"
10 tags = ["ssh","http"]
11
12 boot_disk {
13 initialize_params {
14 image = "debian-cloud/debian-9"
15 }
16 }
17
18 network_interface {
19 network = google_compute_network.vpc.name
20
21 # Refer to subnet
22 subnetwork = google_compute_subnetwork.public_subnet_1.name
23
24 access_config { }
25 }
26}
8. Verify your Setup
Now at last we are going to verify it by actually logging into the Google Cloud.
Navigate to Compute Engine -> VM Instances
You should see a virtual machine running
Congratulations! You have successfully provisioned your first Virtual machine running on Google Cloud using Terraform.
9. Destroy Virtual Machine
You can destroy the virtual machine running on Google Cloud using the following command
1terraform destroy
Once you run the terraform destroy command then you should see something similar on your terminal
1
2Do you want to destroy all resources?
3 Terraform will destroy all your managed infrastructure, as shown above.
4 There is no undo. Only 'yes' will be accepted to confirm.
5
6 Enter a value: yes
7
8google_compute_instance.default: Destroying... [id=projects/gcp-terraform-307119/zones/europe-west4-a/instances/test]
9google_compute_instance.default: Still destroying... [id=projects/gcp-terraform-307119/zones/europe-west4-a/instances/test, 10s elapsed]
10google_compute_instance.default: Still destroying... [id=projects/gcp-terraform-307119/zones/europe-west4-a/instances/test, 20s elapsed]
11google_compute_instance.default: Destruction complete after 22s
Conclusion
- This guide will help you to getting started with terraform
- It will give a very good idea of how to write your first terraform configuration file.
- You will also have a very good understanding of how to use -
terraform init
,terraform plan
,terrafrom apply
,terraform destroy
- In the end you will have a very good understanding of how to use google provider's dependencies with Terraform
Read More - Terragrunt -
Posts in this Series
- Securing Sensitive Data in Terraform
- Boost Your AWS Security with Terraform : A Step-by-Step Guide
- How to Load Input Data from a File in Terraform?
- Can Terraform be used to provision on-premises infrastructure?
- Fixing the Terraform Error creating IAM Role. MalformedPolicyDocument Has prohibited field Resource
- In terraform how to handle null value with default value?
- Terraform use module output variables as inputs for another module?
- How to Reference a Resource Created by a Terraform Module?
- Understanding Terraform Escape Sequences
- How to fix private-dns-enabled cannot be set because there is already a conflicting DNS domain?
- Use Terraform to manage AWS IAM Policies, Roles and Users
- How to split Your Terraform main.tf File into Multiple Files
- How to use Terraform variable within variable
- Mastering the Terraform Lookup Function for Dynamic Keys
- Copy files to EC2 and S3 bucket using Terraform
- Troubleshooting Error creating EC2 Subnet InvalidSubnet Range The CIDR is Invalid
- Troubleshooting InvalidParameter Security group and subnet belong to different networks
- Managing strings in Terraform: A comprehensive guide
- How to use terraform depends_on meta argument?
- What is user_data in Terraform?
- Why you should not store terraform state file(.tfstate) inside Git Repository?
- How to import existing resource using terraform import comand?
- Terraform - A detailed guide on setting up ALB(Application Load Balancer) and SSL?
- Testing Infrastructure as Code with Terraform?
- How to remove a resource from Terraform state?
- What is Terraform null Resource?
- In terraform how to skip creation of resource if the resource already exist?
- How to setup Virtual machine on Google Cloud Platform
- How to use Terraform locals?
- Terraform Guide - Docker Containers & AWS ECR(elastic container registry)?
- How to generate SSH key in Terraform using tls_private_key?
- How to fix-Terraform Error acquiring the state lock ConditionalCheckFiledException?
- Terraform Template - A complete guide?
- How to use Terragrunt?
- Terraform and AWS Multi account Setup?
- Terraform and AWS credentials handling?
- How to fix-error configuring S3 Backend no valid credential sources for S3 Backend found?
- Terraform state locking using DynamoDB (aws_dynamodb_table)?
- Managing Terraform states?
- Securing AWS secrets using HashiCorp Vault with Terraform?
- How to use Workspaces in Terraform?
- How to run specific terraform resource, module, target?
- How Terraform modules works?
- Secure AWS EC2s & GCP VMs with Terraform SSH Keys!
- What is terraform provisioner?
- Is terraform destroy needed before terraform apply?
- How to fix terraform error Your query returned no results. Please change your search criteria and try again?
- How to use Terraform Data sources?
- How to use Terraform resource meta arguments?
- How to use Terraform Dynamic blocks?
- Terraform - How to nuke AWS resources and save additional AWS infrastructure cost?
- Understanding terraform count, for_each and for loop?
- How to use Terraform output values?
- How to fix error configuring Terraform AWS Provider error validating provider credentials error calling sts GetCallerIdentity SignatureDoesNotMatch?
- How to fix Invalid function argument on line in provider credentials file google Invalid value for path parameter no file exists
- How to fix error value for undeclared variable a variable named was assigned on the command line?
- What is variable.tf and terraform.tfvars?
- How to use Terraform Variables - Locals,Input,Output
- Terraform create EC2 Instance on AWS
- How to fix Error creating service account googleapi Error 403 Identity and Access Management (IAM) API has not been used in project before or it is disabled
- Install terraform on Ubuntu 20.04, CentOS 8, MacOS, Windows 10, Fedora 33, Red hat 8 and Solaris 11