Getting started with Terraform on GCP

1_wVfnIRL2g8D39z7-KATBQw.png

This is the first part of potentially a few tutorials on how to get started with deploying infrastructure on Google Cloud Platform.

If you are new to Terraform it might be worth checking out my quick introduction to what Terraform is and why to use it.

Getting started

So to get started you'll need a GCP project, you can get started for free with (I still believe there is) a free tier and/or $300 credit to get going.

You'll also need to download and install the Terraform binary for your OS of choice. You'll also need to be used to working in the terminal and you'll need to create an empty working directory for your Terraform code.

In this example, we are going to be running as our own Google user identity but I'll explain in future tutorials the benefits of service accounts and impersonation.

Firstly we going to tell Terraform how to interact with our chosen platform, GCP.

In the root of our directory, we'll create providers.tfand add the following:

provider "google" {}

But we'll add some configuration for our project here too, just the project and region for now, it saves us typing it in on all our resources later.

provider "google" {
  project = "my-terraform-gcp-project"
  region = "europe-west2"
}

Adding resources

Next, we need somewhere to declare what we want to create in GCP, these are referred to as resources. eg. A VPC network is a google cloud resource, a subnet in that VPC would be a separate resource and the VM that is attached to that subnet would be another resource etc. You get the picture. Here is an example of a VPC and a subnet in a main.tf file:

resource "google_compute_network" "custom-vpc" {
  name                    = "test-tf-network"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "subnet" {
  name              = "test-tf-subnetwork"
  ip_cidr_range = "10.2.0.0/16"
  region             = "europe-west2"
  network          = google_compute_network.custom-vpc.id
}

That's it!

That's about 10 lines of code to create a VPC network and a subnet, it's pretty impressive and cool eh?!

Now, there are a lot more options and inputs we could add for an even more opinionated VPC and Subnet which is covered in Terraform's very handy and helpful available provider registry documentation via the Terraform registry when you really get going you'll spend a lot of time here!

Planning and applying

So we have our resources in our main.tf ready to go, we need to plan our additions and then apply when we're happy

To run our plan you need to enter the command terraform plan Terraform will then take a look at the resources in our Terraform files and it will also take a look at the state, now we haven't really covered state in much detail yet. Later!

This is the really cool part, we are declaratively telling Terraform what we want our infrastructure in GCP to look like.

In our case, we don't have anything in the state as this Terraform is all new so we should see a plan of 2 to add. The VPC network and the subnet. Think of terraform plan as a dry run or what would this current code add, change or remove if I applied.

After running a plan we can now run terraform apply it will run a plan once more but will ask us "do you want to perform these actions" type yes and enter and all going well, the resources in our terraform will be deployed in GCP!

Additions and changes

So that's our VPC and subnet running and configured in GCP, great! but what if we wanted to make changes or even add some more resources? Well, we can add something to our existing code, let's add a Compute instance to run on our network. This is where the state comes in. you might have noticed a new file appear in your directory terraform.tfstate this is the state file which represents our GCP infrastructure in JSON.

Let's add a web server VM and a firewall rule:

resource "google_compute_firewall" "web-fw" {
  name          = "http-rule"
  network      = google_compute_network.custom-vpc.id
  description = "Creates firewall rule targeting tagged instances"

  allow {
    protocol = "tcp"
    ports      = ["80"]
  }

  target_tags       = ["web"]
  source_ranges = ["0.0.0.0/0"]
}

resource "google_compute_instance" "default" {
  name               = "tf-test-web-vm"
  machine_type = "g1-small"
  zone                = "europe-west2-b"
  tags                 = ["web"]

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
  }

  network_interface {
    subnetwork = google_compute_subnetwork.subnet.self_link

    access_config {
      // Ephemeral public IP
    }
  }

  metadata_startup_script = file("./startup.sh")

  service_account {
    scopes = ["cloud-platform"]
  }
}

When we run teraform plan again it will check the terraformstate.tf file for what already exists and notice the difference is the new compute instance resource and the firewall resource, it will then proceed to add the 2 new resources when we run a terraform apply

Making our code declarative! we are declaring to Terraform what we want our infrastructure to look like and how it's configured.

If we didn't add any new resources to our code and ran a plan or apply then Terraform would inform us that everything looks as it should according to the terraformstate.tf file.

Now if someone went into the console and decided to add another port to our firewall when we run apply again it would notice that it hasn't been declared in the terraform files, our main.tf in this example and would remove it leaving just the configured port 80. So it works by removing configuration and resources too.

Destroying

Lastly, to wrap up, let's get rid of any resources that you've created so you don't get charged for them. Running the command terraform destroy will offer if you are sure you want to destroy the resources as this cannot be undone.

That's it for this tutorial, I hope this has helped you get started with Terraform and explained its uses and demonstrated why it's pretty much the standard for deploying infrastructure at the moment and such a valuable skill to have experience with.

I have a repo which the code that I used for this tutorial which you can find here.

Please let me know if you spot any inconsistencies in my code, wording etc. I'm open to all feedback!

Next up I'm aiming to get a tutorial on running Terraform in a pipeline, this is where the really cool magic happens!