Deploy and configure Google Compute Engine VMs with Terraform

Photo by Alexandre Chambon on Unsplash

I recently wanted to deploy and configure a Virtual Machine on Google Compute Engine using Terraform. I thought I’d document my steps to help anyone looking to achieve similar goals. Read on below and easily recreate all the steps. Good luck in all your automations!

Why Terraform?

By now, my preference for using Terraform to automate deployments is well documented. I like all my environments to be throwaways because it helps me sleep better at night knowing that I can always recreate them fully! “Did my VM crash? No problem, I’ll just delete it and start again!” (note: not always the best approach, but having the option is great!)

Ok, back to the task at hand…

What will this tutorial cover?

  • Provision Compute Engine instances with Terraform
  • Add SSH keys
  • Run cloud-init to create a super user for the Terraform Provider
  • Create a custom network/subnet with IPv6 support
  • Reserve a static IPv4 address
  • Allocate IPv4/IPv6 addresses to the Compute Engine VM
  • Set PTR (reverse DNS) records

This tutorial assumes you have working knowledge of Terraform. If not, check out Google’s tutorial; Hashicorp’s site is also a good resource to peruse!

Let’s begin!

Provision a Google Compute Engine instance

Let’s spin up a standalone Ubuntu 20.04 VM.

Only required once: run terraform init to configure the required provider(s).

Run terraform apply, and you’re good to go. That was easy, right!?

But wait, what do I do with this VM? You can’t actually SSH into it yet (unless, of course, you have configured project-level SSH keys).

Let’s manually add some SSH keys!

Add SSH keys to your Compute Engine VM

Change your google_compute_instance block and add a metadata section:

Replace YOUR_USERNAME with your Google account’s username, i.e.:

  • myuser for myuser@gmail.com
  • my_user for my.user@gmail.com
  • etc. (more details here)

Then rerun terraform apply.

Using cloud-init to provision a super-user account

Cloud-init is the de-facto way for configuring cloud instances. All the major providers support it, Google being one of them. Here’s a simple example that provisions a super user for Terraform, allowing it to perform any necessary steps during instance initialization.

The following example uses the cloud-config format. There are others.

Save the file above into your Terraform directory as cloud-config.yaml.

Then, reconfigure your Cloud Engine deployment to use this file:

Once the GCP reprovisions the VM, you will notice that the changes requested in cloud-config.yaml, have been applied. This is a useful example that creates a dedicated user, allowing Terraform to SSH in and further set up the instance.

What about IPv6?

To allocate a public IPv6 address, we must add a few more resources to our Terraform config:

We must also change our VM’s network settings. Replace the network_interface block in your previous config with the following.

Rerun terraform apply (note that the VM will restart).

By the way, if you’re wondering why PREMIUM, it’s because of the following requirement “Network tier in IPv6 access config must be PREMIUM”.

What’s next? Oh right…

Reserve a static IPv4 address

Another easy config:

Granted, you must also update your instance’s network interface:

And then rerun terraform apply.

Set a PTR record

The end is in sight; one last thing to do: add the PTR record!

For example, a reverse DNS record is usually required for SMTP servers (otherwise, any emails received from your IP will end up flagged as spam).

Add the public_ptr_domain_name line in your config and rerun terraform apply.

Defining a PTR record for the instance’s IPv6 address is just as easy:

Note that the trailing dot after “YOUR.DOMAIN.COM.” is not a mistake. For DNS records, it signifies that the provided name is a complete FQDN and not an alias (CNAME) defined on the domain’s zone.

To confirm the PTR records have been set, you can run the following command:

That was all! A quick incursion into basic Google Compute Engine provisioning, using Terraform for peace of mind. Let me know what you think in the comments!

Until next time, — Mihai

--

--

Software Engineer at heart, Manager by day, Indie Hacker at night. Writing about DevOps, Software engineering, and Cloud computing. Opinions my own.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mihai Bojin

Software Engineer at heart, Manager by day, Indie Hacker at night. Writing about DevOps, Software engineering, and Cloud computing. Opinions my own.