April 6 & 7
Learn about Vault, Consul, & more at HashiDays Sydney in Australia Register Now

Getting Started - Azure

Build Infrastructure

In this lesson you will use the configuration created in the previous lesson to build infrastructure on Azure.

There are three steps to build infrastructure with Terraform:

  1. Initialize the Terraform configuration directory using terraform init
  2. Create an execution plan using terraform plan
  3. Create or modify infrastructure using terraform apply

Each of these steps is described in the following sections.


The first command to run for a new configuration is terraform init. Init is run in the configuration directory. Init will create a hidden directory .terraform and download plugins as needed by the configuration. Init also configures the backend for Terraform state, an important detail that we'll come back to later.

Terraform uses a plugin-based architecture to support the numerous infrastructure and service providers available. Each provider is its own encapsulated binary distributed separately from Terraform itself. The terraform init command will automatically download and install any provider binaries required by the providers specified in the configuration.

It isn't always desirable to automatically update provider binaries. As illustrated in the previous lesson, provider blocks allow you to "pin" the version to a specific version or range of versions to prevent automatic updates.

This example initializes a simple Terraform configuration:

$ terraform init

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "azurerm" (terraform-providers/azurerm) 1.32.1...

Terraform has been successfully initialized!


Before you can create infrastructure, Terraform needs to generate an execution plan. The command to create or update the execution plan is terraform plan. The execution plan specifies what actions Terraform will take to achieve the desired state defined in the configuration, and the order in which the actions occur.

The plan step also checks the syntax of the configuration and attempts to connect to Azure to refresh the state prior to checking for differences with the current configuration. (State refresh can be disabled.)

The execution plan is an important artifact. To simplify things, this tutorial does not save the plan, but in practice, you'll usually want to export the plan to a file using the -out argument, review the plan, and then execute that same plan. If you run terraform apply without specifying a plan, Terraform will recalculate the plan. The new plan may vary from the plan you previously created by running terraform plan.


The terraform apply command is used to apply the changes in the configuration.

In the same directory as the main.tf file you created, run terraform apply.

You should see output similar to this:

$ terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_resource_group.rg will be created
  + resource "azurerm_resource_group" "rg" {
      + id       = (known after apply)
      + location = "westus2"
      + name     = "myTFResourceGroup"
      + tags     = (known after apply)

This output shows the execution plan, describing which actions Terraform will take in order to change real infrastructure to match the configuration. The output format is similar to the diff format generated by tools such as Git. The output has a + next to azurerm_resource_group.rg, meaning that Terraform will create this resource. Beneath that, it shows the attributes that will be set. When the value displayed is <computed>, it means that the value won't be known until the resource is created.

If the plan was created successfully, Terraform will pause and wait for approval before proceeding. If anything in the plan seems incorrect or dangerous, it is safe to abort here with no changes made to your infrastructure. In this case the plan looks acceptable. Type yes at the confirmation prompt to proceed.

Executing the plan should only take a few seconds, and then you will see something like this:

$ terraform apply

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azurerm_resource_group.rg: Creating...
azurerm_resource_group.rg: Creation complete after 1s [id=/subscriptions/159f2485-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/myTFResourceGroup]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

You can go to the Azure portal to see the new resource group.

Terraform State

When Terraform created the resource group it also wrote data into the terraform.tfstate file. State keeps track of the all managed resources and their associated properties with current values. This state file is extremely important.

Terraform state is essential for managing changes to infrastructure over time. It is necessary to preserve the state file for the entire life cycle of the resources. For that reason (and others), it is recommended to use a remote backend to save state in centralized, secure storage.

You can inspect the current state using terraform show:

$ terraform show
id       = /subscriptions/<subscription id>/resourceGroups/myTFResourceGroup
location = westus2
name     = myTFResourceGroup
tags.%   = 0

In this example, the subscription id was displayed, but for the purposes of documentation and security, it has been replaced with <subscription id>.

The terraform state command provides advanced tools for working with state.