Book Image

Terraform Cookbook

By : Mikael Krief
Book Image

Terraform Cookbook

By: Mikael Krief

Overview of this book

HashiCorp Configuration Language (HCL) has changed how we define and provision a data center infrastructure with the launch of Terraform—one of the most popular and powerful products for building Infrastructure as Code. This practical guide will show you how to leverage HashiCorp's Terraform tool to manage a complex infrastructure with ease. Starting with recipes for setting up the environment, this book will gradually guide you in configuring, provisioning, collaborating, and building a multi-environment architecture. Unlike other books, you’ll also be able to explore recipes with real-world examples to provision your Azure infrastructure with Terraform. Once you’ve covered topics such as Azure Template, Azure CLI, Terraform configuration, and Terragrunt, you’ll delve into manual and automated testing with Terraform configurations. The next set of chapters will show you how to manage a balanced and efficient infrastructure and create reusable infrastructure with Terraform modules. Finally, you’ll explore the latest DevOps trends such as continuous integration and continuous delivery (CI/CD) and zero-downtime deployments. By the end of this book, you’ll have developed the skills you need to get the most value out of Terraform and manage your infrastructure effectively.
Table of Contents (10 chapters)

Provisioning infrastructure in multiple environments

In the same way that we deploy an application to several environments (dev, test, QA, and production), we also need to provision infrastructure on these different environments.

The question that often arises is how to write a maintainable and scalable Terraform configuration that would allow us to provision infrastructure for multiple environments.

To answer this question, it is important to know that there are several solutions for organizing Terraform configuration topologies that will allow for this provisioning.

In this recipe, we will look at two Terraform configuration structure topologies that will allow us to deploy an Azure infrastructure to multiple environments.

Getting ready

To fully understand this recipe, you will need to have a good understanding of the notion of variables, as discussed in the Manipulating variables recipe of this chapter.

The goal of the Terraform configuration that we are going to write is to deploy an Azure App Service for a single environment. Its code is distributed in the following files:

In the preceding diagram, we can see the following:

  • The main.tf file contains the Terraform configuration of the resources to be provisioned.
  • The variables.tf file contains the declaration of the variables.
  • The terraform.tfvars file contains the values of the variables.

The Terraform source code for this basic example is available at https://github.com/PacktPublishing/Terraform-Cookbook/tree/master/CHAP02/myApp/simple-env.

What is important in this recipe is not the content of the code, but the folder structure and the Terraform commands to be executed.

How to do it…

Follow these steps to implement the first Terraform configuration folder topology:

  1. In an empty folder, create a separate directory per environment: one for dev, one for test, one for QA, and one for production.
  2. Copy the Terraform base configuration into each of these directories identically.
  1. Then, in each of these directories, modify the values of the terraform.tfvars file with the information that is specific to the environment. Here is an extract of each of these terraform.tfvars files:
resource_group_name = "RG-App"
service_plan_name = "Plan-App"
environment = "DEV" #name of the environment to change
  1. Finally, to provision each of these environments, inside each of these directories, execute the classical Terraform execution workflow by running the terraform init, terraform plan, and terraform apply commands.

Follow these steps to implement the second topology of the Terraform configuration folder:

  1. In the folder that contains our basic Terraform configuration, create three subdirectories: dev, test, and production.
  2. Then, in each of these subdirectories, copy only the terraform.tfvars base file, in which we modify the variables with the correct values of the target environments. The following is an extract from each terraform.tfvars file:
resource_group_name = "RG-App"
service_plan_name = "Plan-App"
environment = "DEV" #name of the environment to change
  1. Finally, to provision each of these environments, go to the root folder of the Terraform configuration and execute the following commands:
terraform init
terraform plan -var-file="<environment folder>/terraform.tfvars"
terraform apply -var-file="<environment folder>/terraform.tfvars"

How it works…

In the first topology, we duplicate the same Terraform configuration for each environment and just change the values of the variables in the terraform.tfvars file of each folder.

By doing this, we get the following folder structure:

Terraform is then executed with the basic Terraform commands. This structure can be used if the infrastructure does not contain the same resources for each environment. This is because duplicating all the Terraform configuration in each environment folder offers us the advantage of being able to easily add or remove resources for one environment without affecting the other environments.

However, this is duplicate code, which implies that this code must be maintained several times (we must modify the infrastructure for all environments, make changes to the Terraform configuration, and so on).

In the second topology, we kept the Terraform configuration in the common base for all environments and have just one terraform.tfvars file per environment. By doing this, we get the following folder structure:

As for the execution of the Terraform configuration, we have added the -var-file option to the plan and apply commands. This structure can be used if the infrastructure is the same for all environments but only the configuration changes.

The advantage of this topology is that we have only one common piece of Terraform resource code (in the main.tf and variables.tf files), and just one terraform.tfvars file to fill in, so we will have to make a few changes in case of code evolution or a new environment.

On the other hand, the changes that were made to the Terraform main.tf code will apply to all the environments, which in this case requires more testing and verification.

See also

  • There are other solutions to Terraform configuration folder structure topologies, as we will discuss in Chapter 5, Sharing Terraform Configuration with Modules.
  • Documentation regarding the -var-file option of the plan and apply commands is available at https://www.terraform.io/docs/commands/plan.html.
  • An article explaining the best practices surrounding Terraform configuration can be found at https://www.terraform-best-practices.com/code-structure.
  • The following blog post explains the folder structure for production Terraform configuration: https://www.hashicorp.com/blog/structuring-hashicorp-terraform-configuration-for-production