Automating the Deployment of Infrastructure Using Terraform on GCP

Mehul Patel
6 min readApr 21, 2020

--

In this blog, we will introduce a Terraform configuration with a module to automate the deployment of GCP infrastructure. As your configuration changes, Terraform can create incremental execution plans, which allows you to build your overall configuration step by step.

The instance module allows you to re-use the same resource configuration for multiple resources while providing properties as input variables. You can leverage the configuration and module that you created as a starting point for future deployments.

What is Terraform ?

Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently, which enables you to securely and predictably create, change, and improve infrastructure.

In this blog, we are deploying one auto mode network with a firewall rule and 3 VM instances, as shown in this diagram:

Image reference from Google Cloud Docs.

Let’s begin…

STEP 1: Install Terraform

Terraform is already integrated into Cloud Shell. Check the available downloads for the latest version of Terraform : https://www.terraform.io/downloads.html

Just verify which version is installed. To check follow the steps below:

  1. In the Cloud Console, click Activate Cloud Shell
  2. If prompted, click Continue.
  3. Make sure you set the project ID before proceeding, please use this command below; gcloud config set project [PROJECT ID]
  4. To confirm that Terraform is installed, run the following command:
terraform --version

The output should look like this (do not copy; this is example output):

Terraform v0.12.24

4. To create a directory for your Terraform configuration, run the following command:

mkdir tfinfra

Now Initialize Terraform

  1. Now create a new file under the tfinfra folder.
  2. Name the new file provider.tf, and then open it.
  3. Copy the code into provider.tf:
provider "google" {}

4. To initialize Terraform, run the following command:

terraform init

The output should look like this ;

provider.google: version = “~> 3.17” Terraform has been successfully initialized!

You are now ready to work with Terraform in Cloud Shell.

STEP 2: Create mynetwork and its resources

Create the auto mode network mynetwork along with its firewall rule and two VM instances (mynet_us_vm, mynet_as_vm, mynet_eu_vm)

Create a new configuration, and define mynetwork.

  1. Crate a new file mynetwork.tf under the same folder.
  2. Copy the following base code into mynetwork.tf:
https://gist.github.com/rowdymehul/41945e36773c87cfbaa80f99399bd419

Here the name field allows you to name the resource, and the type field allows you to specify the Google Cloud resource that you want to create. You can also define properties, but these are optional for some resources.

  • Here the "google_compute_network" (with the quotes) is [RESOURCE_TYPE].
  • "mynetwork" (with the quotes) is a [RESOURCE_NAME].
  • An auto mode network automatically creates a subnetwork in each region. Therefore, we are setting auto_create_subnetworks to true.

To Configure the firewall rule we have define a firewall rule to allow HTTP, HTTPS, SSH, RDP, and ICMP traffic on mynetwork.

  • "google_compute_firewall" (with the quotes) is a [RESOURCE_TYPE].
  • "mynetwork-allow-http-ssh-rdp-icmp" (with the quotes) is [RESOURCE_NAME].
  • Also, we are using the google_compute_network.mynetwork.self_link reference to instruct Terraform to resolve these resources in a dependent order. In this case, the network is created before the firewall rule.

3. Save the mynetwork.tf file.

STEP 3: Configure the VM instance

We need to define the VM instances by creating a VM instance module. This module is a reusable configuration inside a folder.

  1. Create a new folder inside tfinfra.
  2. Name the new folder instance.
  3. Create a new file inside instance and name the new file main.tf, and then open it.

You should have the following folder structure in Cloud Shell:

4. Copy the following base code into main.tf:

https://gist.github.com/rowdymehul/fc6ef0c33eb5d18add92d8119ec716bd
  • We have defined the 4 input variables at the top of main.tf, and verify that main.tf looks like this, including brackets {}:
  • By giving instance_type a default value, you make the variable optional. The instance_name, instance_zone, and instance_subnetwork are required, and you will define them in mynetwork.tf.
  • In main.tf, "google_compute_instance" (with the quotes) is a [RESOURCE_TYPE].
  • "${var.instance_name}" (with the quotes) is a [RESOURCE_NAME].
  • The zone and machine type of the instance as input variables, there are the define properties.
  • The boot disk to use the Debian 9 OS image. Because all three VM instances will use the same image, you can hard-code this property in the module.
  • The network interface by providing the subnetwork name as an input variable and the access configuration. Leaving the access configuration empty results in an ephemeral external IP address (required in this practical). To create instances with only an internal IP address, remove the access_config section. For more information, see the Terraform documentation.

5. Save the main.tf file.

6. Add the following VM instances to mynetwork.tf:

https://gist.github.com/rowdymehul/41945e36773c87cfbaa80f99399bd419

These resources are leveraging the module in the instance folder and provide the name, zone, and network as inputs. Because these instances depend on a VPC network, we are using the google_compute_network.mynetwork.self_link reference to instruct Terraform to resolve these resources in a dependent order. In this case, the subnet is created before the instance.

The benefit of writing a Terraform module is that it can be reused across many configurations. Instead of writing your own module, you can also leverage existing modules from the Terraform Module registry.

7. Save the mynetwork.tf file.

Now it’s time to execute STEP 2;

First, let’s apply the mynetwork configuration.

  1. To rewrite the Terraform configuration files to a canonical format and style, run the following command:
terraform fmt

The output should look like this (do not copy; this is example output):

mynetwork.tf

If you get an error, revisit the previous steps to ensure that your configuration matches the steps mentioned. If you cannot troubleshoot the issue of your configuration, look at these finished configurations:

* mynetwork.tf

* main.tf

* provider.tf

2. To initialize Terraform, run the following command:

terraform init

If you get an error, revisit the previous steps to ensure that you have the correct folder/file structure. If you cannot troubleshoot the issue of your configuration, refer to the finished configurations linked above. When you have corrected the issue, re-run the previous command.

3. To create an execution plan, run the following command:

terraform plan

The output should look like this (this is example output):

4. To apply the desired changes, run the following command:

terraform apply

5. To confirm the planned actions, type: yes (this is example output)

The output should look like this (do not copy; this is example output):

Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

STEP 4: Verify your deployment

Verify your network in the Cloud Console

  1. In the Cloud Console, on the Navigation menu, click VPC network > VPC networks.
  2. View the mynetwork VPC network with a subnetwork in every region.
  3. On the Navigation menu, click VPC network > Firewall Rules.
  4. Sort the firewall rules by Network.
  5. View the mynetwork-allow-http-ssh-rdp-icmp firewall rule for mynetwork.

Verify your VM instances in the Cloud Console

  1. On the Navigation menu, click Compute Engine > VM instances.
  2. View the mynet-us-vm, mynet-as-vm and mynet-eu-vm instances.

3. Note the internal IP address for mynet-as-vm and try to ping other 2 VM’s.

This should work because both VM instances are on the same network, and the firewall rule allows ICMP traffic!

Conclusion:

In this blog, we have created a Terraform configuration with a module to automate the deployment of Google Cloud infrastructure. As your configuration changes, Terraform can create incremental execution plans, which allows you to build your overall configuration step by step.

The instance module allowed you to re-use the same resource configuration for multiple resources while providing properties as input variables. You can leverage the configuration and module that you created as a starting point for future deployments.

Thank you for reading. :)

--

--

Mehul Patel

Tech Speaker | Linux Engineer | DevOps | OpenSource Enthusiast | Independent Researcher | Technical Writer | Explorer