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)

Configuring Terraform and the provider version to use

The default behavior of Terraform is that, when executing the terraform init command, the version of the Terraform binary (which we will call the Command-Line Interface (CLI), as explained here: https://www.terraform.io/docs/glossary.html#cli) used is the one installed on the local workstation. In addition, this command downloads the latest version of the providers used in the code.

However, for compatibility reasons, it is always advisable to avoid surprises so that you can specify which version of the Terraform binary is going to be used in the Terraform configuration. The following are some examples:

  • A Terraform configuration written with HCL 2 must indicate that it has to be executed with a Terraform version greater than or equal to 0.12.
  • A Terraform configuration that contains new features such as count and for_each in modules must indicate that it has to be executed with a Terraform version greater than or equal to 0.13.
For more details about the HCL syntax, read the documentation at https://www.terraform.io/docs/configuration/syntax.html.

In the same vein and for the same reasons of compatibility, we may want to specify the provider version to be used.

In this recipe, we will learn how to specify the Terraform version, as well as the provider version.

Getting ready

To start this recipe, we will write a basic Terraform configuration file that contains the following code:

variable "resource_group_name" {
default = "rg_test"
}
resource "azurerm_resource_group" "rg" {
name = var.resource_group_name
location = "West Europe"
}
resource "azurerm_public_ip" "pip" {
name = "bookip"
location = "West Europe"
resource_group_name = azurerm_resource_group.rg.name
public_ip_address_allocation = "Dynamic"
domain_name_label = "bookdevops"
}

This example code provides resources in Azure (a Resource Group and a public IP address). For more details, read the following documentation about the Terraform AzureRM provider: https://www.terraform.io/docs/providers/azurerm/index.html

In addition, this code contains the improvements that were made to the HCL 2.0 language since Terraform 0.12. For more details about these HCL enhancements, go to https://www.slideshare.net/mitchp/terraform-012-deep-dive-hcl-20-for-infrastructure-as-code-remote-plan-apply-125837028.

Finally, when executing the terraform plan command inside this code, we get the following warning message:

This means that, currently, this Terraform configuration is still compatible with the latest version of the provider but that in a future version of the provider, this property will be changed and therefore this code will no longer work.

Now, let's discuss the steps we need to follow to make the following compliances:

  • This configuration can only be executed if Terraform 0.13 (at least) is installed on the local computer.
  • Our current configuration can be executed even if the azurerm provider evolves with breaking changes.
Regarding the new features provided by Terraform 0.13, read the change log here – https://github.com/hashicorp/terraform/blob/master/CHANGELOG.md, and the upgrade guide here – https://github.com/hashicorp/terraform/blob/master/website/upgrade-guides/0-13.html.markdown.

We'll take a look at this next.

How to do it…

To specify the Terraform version to be installed on the local workstation, do the following:

  1. In the Terraform configuration, add the following block:
terraform {
required_version = ">= 0.13"
}
  1. To specify the provider source and version to use, we need to add the required_provider block inside the same terraform configuration block:
terraform {
...
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "2.10.0"
}
}
}

How it works…

When executing the terraform init command, Terraform will check that the version of the installed Terraform binary that executes the Terraform configuration file corresponds to the version specified in the required_version property of the terraform block.

If it matches, it won't throw an error as it is greater than version 0.13. Otherwise, it will throw an error:

With regard to the specification of the provider version, when executing the terraform init command, if no version is specified, Terraform downloads the latest version of the provider, otherwise it downloads the specified version, as shown in the following two screenshots.

The following screenshot shows the provider plugin being downloaded from the specified source without us specifying the required version (at the time of writing, the latest version of the provider is 2.20.0):

As we can see, the latest version of the azurerm provider (2.20.0) has been downloaded.

In addition, the following screenshot shows the azurerm provider plugin being downloaded when we specify the required version (2.10.0):

As we can see, the specified version of the azurerm provider (2.10.0) has been downloaded.

For more details about the required_version block and provider versions, go to https://www.terraform.io/docs/configuration/terraform.html#specifying-required-provider-versions.

In this required_version block, we also add the source property, which was introduced in version 0.13 of Terraform and is documented here: https://github.com/hashicorp/terraform/blob/master/website/upgrade-guides/0-13.html.markdown#explicit-provider-source-locations

There's more…

In this recipe, we learned how to download the azurerm provider in various ways. What we did here applies to all providers you may wish to download.

It is also important to mention that the version of the Terraform binary that's used is specified in the Terraform state file. This is to ensure that nobody applies this Terraform configuration with a lower version of the Terraform binary, thus ensuring that the format of the Terraform state file conforms with the correct version of the Terraform binary.

See also

  • For more information about the properties of the Terraform block, go to https://www.terraform.io/docs/configuration/terraform.html.
  • For more information about the properties of the providers, go to https://www.terraform.io/docs/configuration/providers.html.
  • More information about Terraform binary versioning is documented at https://www.terraform.io/docs/extend/best-practices/versioning.html.
  • The upgrade guide for the azurerm provider (to version 2.0) is available at https://www.terraform.io/docs/providers/azurerm/guides/2.0-upgrade-guide.html.