Deploying An IaC Project In GCP Using Terraform.
Tags: iac, terraform, googlecloud, agile
Published: 2022-12-16 20:31:11

The creation of resources in the cloud and the management of the lifecycle of these resources can be a tedious process, especially when doing this on a largescale. The response to this is infrastructure as code(IaC). Infrastructure as code is essentially the provisioning and management of your cloud resources as reusable code that can be managed, versioned, and monitored in a source control system like git. Currently, the most popularly used IaC tool is terraform and this is for good reason, considering the myriad of benefits it provides.

The adoption of IaC has very important benefits in the software development life cycle(SDLC), be it in a startup or a large scale organization. These include the effective reduction and avoidance of errors that are concomitant and prone with manual configurations.

Secondly, terraform can be used to make multiple copies of large deployments that have the same environment designated for development, testing, and production, so that we are confident an application that has been tested and is running in development will equally run without a problem when shipped to production.

Terraform as an IaC tool offers the aforementioned benefits, and in addition, it can be used to provision resources across all cloud service providers and it is equally applicable in the migration of on-premises workloads to the cloud.

Terraform is written in Hashicorp Configuration Language(HCL). HCL is identical to JSON but with extra functionalities.

In this project I will be using terraform to create a number of resources in Google Cloud Platform. These resources include an auto mode network, a configuration for a firewall rule, and compute engine.

To begin with, you need to be registered as a GCP user. The process involved to do this is simple and you can easily set up your account by following the step by step guide offered on the Google cloud website https://console.cloud.google.com/ Alternatively you can register an account on Qwiklabs https://www.cloudskillsboost.google/ to follow this demonstration.

Now that we have explored the various means to access the Google Cloud console we can login and access the GCP console .


Fortunately, GCP has terraform integrated into cloud shell(GCP’s web-based shell environment), thus creating a GCP account gives you automatic access to use terraform in cloud shell. ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zfxmz57t14b50orqb6k0.jpeg)

&nbsp;


Entering the command [terraform —version] in cloud shell will verify its installation along with the exact version it is running.

Based on your preference you can use any text editor you are conversant with or use cloud shell's in built text editor located at top right of your cloud shell window. It is denoted by the pencil icon.![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tjb3p0el4s78959oe6ei.jpeg)


&nbsp;

Now we can dive right into the source files and code we will be writing in terraform to achieve the objective of this project.

I will be going with the editor on cloud shell. Prior to that we must create a new directory for our project. We will be naming it “tfinfra”. 

**Type `mkdir tfinfra && cd tfinfra` in your terminal to create and open your project directory. Now we can navigate to our text editor and create a new file called “provider.tf” inside the newly created directory.**￼![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g35wk3r6hmxwp5mt6dtf.jpeg)

&nbsp;

**Inside this file we enter the line of code shown below to declare the cloud service provider we will be using. In this case “google”**![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bx4x5im0isbq5brvavco.jpeg)

&nbsp;


**After saving the above file we can toggle back to cloud shell and initialize the directory by entering the command `terraform init`. Upon completion we should view a success message just like the one below**![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/it0czgk66wrpb94zqv9p.jpeg)

&nbsp;

**To configure network resources. Return to the code editor and create a file called “mynetwork.tf” in the “tfinfra” directory.** ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bmio5n690w6j5lqsvr2w.jpeg)

&nbsp;

The first code block below defines the resource we want to configure, that is, the network of our workload. This is referred to as a virtual private cloud(VPC) in GCP. The subsequent code block below defines our network resources. It consists of the network subnets and firewall rules as indicated in the commented lines preceding each resource definition. The syntax of terraform is simple. Thus a perusal of the code by each line explains what we want to configure.![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r81b3du8mnhhy4997q9l.jpeg)

&nbsp;


In a declarative format. Terraform allows us to write in code the configuration for each component that constitutes our workload in great detail.![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1343m4dp1m7qinw9jusz.jpeg)

&nbsp;


**The code block below is the full declaration of the network resources we want to provision and a full version of the code in the  above screenshots(mynetwork.tf).**
```
# Create the mynetwork network
resource "google_compute_network" "mynetwork" {
  name                    = "mynetwork"
  auto_create_subnetworks = true
}

# Add a firewall rule to allow HTTP, SSH, RDP, and ICMP traffic on mynetwork
resource "google_compute_firewall" "mynetwork-allow-http-ssh-rdp-icmp" {
  name    = "mynetwork-allow-http-ssh-rdp-icmp"
  network = google_compute_network.mynetwork.self_link

  allow {
    protocol = "tcp"
    ports    = ["22", "80", "3389"]
  }
  allow {
    protocol = "icmp"
  }
  source_ranges = ["0.0.0.0/0"]
}

# Create the mynet-us-vm instance
module "mynet-us-vm" {
  source           = "./instance"
  instance_name    = "mynet-us-vm"
  instance_zone    = "us-central1-a"
  instance_network = google_compute_network.mynetwork.self_link
}

# Create the mynet-eu-vm" instance
module "mynet-eu-vm" {
  source           = "./instance"
  instance_name    = "mynet-eu-vm"
  instance_zone    = "europe-west1-d"
  instance_network = google_compute_network.mynetwork.self_link
}


```

A conventional technique in coding is to leverage modules which are reusable configurations for a section of a program. This ensures that we do not reproduce code and make our programs efficient, as prescribed by the DRY principle. Similarly, modules can also be used in terraform. In this project we will leverage modules to configure our compute resources(VM instances). 

**To do this, create a subdirectory titled "instance" in the parent directory("tfinfra"). Create a file inside the subdirectory and save it as "main.tf".**![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1ehs7t9sq9wmdoaw986.jpeg)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vgwhv0kl05ju1ac6wds.jpeg)


**Inside the "main.tf" file, the declaration in the code block below should be issued and saved afterwards.**

```
variable "instance_name" {}
variable "instance_zone" {}
variable "instance_type" {
  default = "n1-standard-1"
  }
variable "instance_network" {}

resource "google_compute_instance" "vm_instance" {
  name         = "${var.instance_name}"
  zone         = "${var.instance_zone}"
  machine_type = "${var.instance_type}"
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
      }
  }
  network_interface {
    network = "${var.instance_network}"
    access_config {
      # Allocate a one-to-one NAT IP to the instance
    }
  }
}
```

**Create another file in the "instance" subdirectory and save it as "variables.tf". Enter the declaration in the code block below in this file. The fields in this file have been defined in the "my network.tf" file**

```
variable "instance_name" {}
variable "instance_zone" {}
variable "instance_type" {
  default = "e2-micro"
  }
variable "instance_network" {}

```

&nbsp;

**Navigate back to cloud shell and ensure that you are in the working directory of this project("tfinfra"). Enter the command `terraform init` to initialize terraform. Enter `terraform plan` to create an execution plan for our project. This command is to essentially confirm the desired resources we want provisioned. To apply this plan, enter `terraform apply`. You should see a response like the one below if it runs successfully.**![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vml9cco1fvsaxi8xo6tm.png)

&nbsp;

**To verify that our resources have been deployed. We can go to the GCP console and navigate the respective sections of the resources we defined and declared in terraform. As shown below our auto mode network is up.**![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/17zkkcb9hzf7gq1gxoy7.jpeg)

&nbsp;


**The firewall rules have also been created successfully!**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oaxry2bepztfgvmhydio.jpeg)


&nbsp;

**Similarly, the two VM instances we declared in our terraform file have been provisioned.**![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uds1jwusikxpzvlitw4h.jpeg)


&nbsp;

**Additional details about the VM instances can be viewed from the images below.**![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gemo8g1umbt0xhvvm9l2.jpeg)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lnzncro9ny4ili4w9tkm.jpeg)

&nbsp;

**To confirm that our deployed VMs have connectivity and are sending traffic. We can SSH into the VM and enter the command `ping -c 3 <Enter mynet-eu-vm's internal IP here>` and you should see the details of the connectivity like the one below.**![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/szjp1nx4tmtbruf60ra3.jpeg)

&nbsp;


**As mentioned from the onset of this article, IaC expedites the process of creating your resources and this equally applies to their management as well. Thus, with the entry of a single terraform command, all the provisioned resources in GCP can be easily deleted. The command for this is `terraform destroy`. As shown below, all our resources have been deleted following the affirmation of this action(enter 'yes' when prompted).**


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9pxifmn0611jse6xdnov.jpeg)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t0zqcyd7bksfqxfe2e30.jpeg)

&nbsp;



This article has sought to provide some insight, on how cloud infrastructure creation and management can be efficiently  carried out using an IaC tool like terraform to automate these processes. This was demonstrated through provisioning and managing resources in Google Cloud. However, terraform can be used across all cloud service providers as stated earlier. IaC is undoubtedly an efficient tool and agile methodology that must be encouraged in the deployment of workloads in enterprise environments and startups to reduce the errors associated with manual and repetitive configurations.
￼

￼

￼


￼

￼

￼

￼

￼

￼

￼

￼



￼
￼
￼