GCP Infrastructure as Code with Terraform and Terragrunt

Source Code

The source codes relate to this article are kept publicly in the GitHub repository here — https://github.com/its-knowledge-sharing/gcp-terragrunt-demo. I would recommend to clone the codes and read them at the same time you read this article.


Terragrunt is the Terraform wrapper tool that helps to solve many Terraform’s pain points like keeping your configurations DRY, working with multiple Terraform modules and folders, and managing remote state.

Files Structure

We place Terraform codes into several folders based on the GCP services as shown in picture below.

  • 00–0-vpc, the code to create VPC and subnet.
  • 00–1-sa, the code to create service account and role.
  • 00–2-firewall, the code to configure the firewall rules.
  • 00–3-nat, the code to create Cloud NAT for outbound internet connection.
  • 00–4-route, the code to create the route to internet.
  • 01–1-gce-manager, the code to create an example GCE instance that uses custom Ubuntu as OS image.
  • modules/gce, the internal module for creating GCE instance.
  • terragrunt.hcl, this is the shared configuration file uses for configuring Terraform codes in the folders mentioned above.

Infrastructure Provisioning

In order to use Terragrunt to provision the GCP services, we need to install Terragrunt and Terraform first. In this article we will run them in Cloud Shell (web browser base shell to interact with GCP) and assume that we already have them installed. In my shell environment, I downloaded and placed them in my local directory and point the PATH environment to.

Provisioning Order

We might ask ourselves that how Terragrunt knows that what GCP service need to be provisioned before the another one. For example, how does it knows that it needs to create the VPC before creating the GCE instance?

Provisioning GCE instance

It’s the good idea to add more explanations about how we provision the GCE instance. In this article we create the internal module here gce.tf and the module once again refers to another external module.

Custom Ubuntu OS image

As mentioned earlier, this article uses the Custom OS image when provisioning the GCE instance. There are many advantages to use custom OS image instead of each GCE instance to have its own Terraform provisioner script. The provisioning speed is the first reason for me to use the custom OS image. Think about the situation like if there are 10 GCE instances to be created.


If everything is done and we want remove them we created earlier, we can simply do it by just by calling “infra.bash destroy” command.


Congratulation!!! if you’ve read the entire article and it is able to help you solve your issues. You can support me by:

  • Follow me.
  • Share my articles.
  • Buy me a coffee via ADA address below if you want.



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