Quickstart: Configure Terraform using Azure PowerShell

Terraform enables the definition, preview, and deployment of cloud infrastructure. Using Terraform, you create configuration files using HCL syntax. The HCL syntax allows you to specify the cloud provider - such as Azure - and the elements that make up your cloud infrastructure. After you create your configuration files, you create an execution plan that allows you to preview your infrastructure changes before they're deployed. Once you verify the changes, you apply the execution plan to deploy the infrastructure.

This article describes how to get started with Terraform on Azure using PowerShell.

In this article, you learn how to:

  • Install the latest version of PowerShell
  • Install the new PowerShell Az Module
  • Install the Azure CLI
  • Install Terraform
  • Create an Azure service principal for authentication purposes
  • Log in to Azure using the service principal
  • Set environment variables so that Terraform correctly authenticates to your Azure subscription
  • Create a base Terraform configuration file
  • Create and apply a Terraform execution plan
  • Reverse an execution plan

Prerequisites

  • Azure subscription: If you don't have an Azure subscription, create a free account before you begin.

Configure your environment

  1. The latest PowerShell module that allows interaction with Azure resources is called the Azure PowerShell Az module. When using the Azure PowerShell Az module, PowerShell 7 (or later) is the recommended version on all platforms. If you have PowerShell installed, you can verify the version by entering the following command at a PowerShell prompt.

    $PSVersionTable.PSVersion
    
  2. Install PowerShell. This demo was tested using PowerShell 7.0.2 on Windows 10.

  3. For Terraform to authenticate to Azure, you need to install the Azure CLI. This demo was tested using Azure CLI version 2.9.1.

  4. Download Terraform.

  5. From the download, extract the executable to a directory of your choosing.

  6. Update your system's global path to the executable.

  7. Verify the global path configuration with the terraform command.

    terraform
    

    Notes:

    • If the Terraform executable is found, it will list the syntax and available commands.

Authenticate to Azure

When using PowerShell and Terraform, you must log in using a service principal. The next two sections will illustrate the following tasks:

Create an Azure service principal

To log into an Azure subscription using a service principal, you first need access to a service principal. If you already have a service principal, you can skip this section.

There are many options when creating a service principal with PowerShell. For this article, we'll create a service principal with a Contributor role. The Contributor role (the default role) has full permissions to read and write to an Azure account. For more information about Role-Based Access Control (RBAC) and roles, see RBAC: Built-in roles.

Calling New-AzADServicePrincipal creates a service principal for the specified subscription. Upon successful completion, the service principal's information - such as its service principal names and display name - are displayed. When you call New-AzADServicePrincipal without specifying any authentication credentials, a password is automatically generated. However, this password isn't displayed as it's returned in a type SecureString. As such, you need to call New-AzADServicePrincipal with the results going to a variable. You can then convert the variable to plain text to display it.

  1. Get the subscription ID for the Azure subscription you want to use. If you don't know the subscription ID, you can get the value from the Azure portal.

    1. Log into the Azure portal.
    2. Under Azure services, select Subscriptions.
    3. The table listing of subscriptions contains a column with each subscription's ID.
  2. Start PowerShell.

  3. Create a new service principal using New-AzADServicePrincipal. Replace <azure_subscription_id> with the ID of the Azure subscription you want to use.

    $sp = New-AzADServicePrincipal -Scope /subscriptions/<azure_subscription_id>
    
  4. Display the names of the service principal.

    $sp.ServicePrincipalNames
    
  5. Display the autogenerated password as text, ConvertFrom-SecureString.

    $UnsecureSecret = ConvertFrom-SecureString -SecureString $sp.Secret -AsPlainText
    

Notes:

  • The service principal names and password values are needed to log into the subscription using your service principal.
  • The password can't be retrieved if lost. As such, you should store your password in a safe place. If you forget your password, you'll need to reset the service principal credentials.

Log in to Azure using a service principal

To log into an Azure subscription using a service principal, call Connect-AzAccount specifying an object of type PsCredential.

  1. Start PowerShell.

  2. Get a PsCredential object using one of the following techniques.

    1. Call Get-Credential and enter a service principal name and password when requested:

      $spCredential = Get-Credential
      
    2. Construct a PsCredential object in memory. Replace the placeholders with the appropriate values for your service principal. This pattern is how you would log in from a script.

      $spName = "<service_principal_name>"
      $spPassword = ConvertTo-SecureString "<service_principal_password>" -AsPlainText -Force
      $spCredential = New-Object System.Management.Automation.PSCredential($spName , $spPassword)
      
  3. Call Connect-AzAccount, passing the PsCredential object. Replace the <azure_subscription_tenant_id> placeholder with the Azure subscription tenant ID.

    Connect-AzAccount -Credential $spCredential -Tenant "<azure_subscription_tenant_id>" -ServicePrincipal
    

Set environment variables

In order for Terraform to use the intended Azure subscription, set environment variables. You can set the environment variables at the Windows system level or in within a specific PowerShell session. If you want to set the environment variables for a specific session, use the following code. Replace the placeholders with the appropriate values for your environment.

$env:ARM_CLIENT_ID="<service_principal_app_id>"
$env:ARM_SUBSCRIPTION_ID="<azure_subscription_id>"
$env:ARM_TENANT_ID="<azure_subscription_tenant_id>"

Create a base Terraform configuration file

A Terraform configuration file starts off with the specification of the provider. When using Azure, you'll specify the Azure provider (azurerm) in the provider block.

provider "azurerm" {
  version = "~>2.0"
  features {}
}

resource "azurerm_resource_group" "rg" {
  name = "<your_resource_group_name>"
  location = "<your_resource_group_location>"
}

# Your Terraform code goes here...

Notes:

  • While the version attribute is optional, HashiCorp recommends pinning to a given version of the provider.
  • If you are using Azure provider 1.x, the features block is not allowed.
  • If you are using Azure provider 2.x, the features block is required.
  • The resource declaration of azurerm_resource_group has two arguments: name and location. Set the placeholders to the appropriate values for your environment.
  • The local named value of rg for the resource group is used throughout the how-to and tutorial articles when referencing the resource group. This is independent of the resource group name and only refers to the variable name in your code. If you change this value in the resource group definition, you'll need to also change it in the code that references it.

Create and apply a Terraform execution plan

In this section, you learn how to create an execution plan and apply it to your cloud infrastructure.

  1. To initialize the Terraform deployment, run terraform init. This command downloads the Azure modules required to create an Azure resource group.

    terraform init
    
  2. After initialization, you create an execution plan by running terraform plan.

    terraform plan -out <terraform_plan>.tfplan
    

    Notes:

    • The terraform plan command creates an execution plan, but doesn't execute it. Instead, it determines what actions are necessary to create the configuration specified in your configuration files. This pattern allows you to verify whether the execution plan matches your expectations before making any changes to actual resources.
    • The optional -out parameter allows you to specify an output file for the plan. Using the -out parameter ensures that the plan you reviewed is exactly what is applied.
    • To read more about persisting execution plans and security, see the security warning section.
  3. Once you're ready to apply the execution plan to your cloud infrastructure, you run terraform apply.

    terraform apply <terraform_plan>.tfplan
    

Reverse a Terraform execution plan

  1. To reverse, or undo, the execution plan, you run terraform plan and specify the destroy flag as follows:

    terraform plan -destroy -out <terraform_plan>.destroy.tfplan
    

    Notes:

    • The terraform plan command creates an execution plan, but doesn't execute it. Instead, it determines what actions are necessary to create the configuration specified in your configuration files. This pattern allows you to verify whether the execution plan matches your expectations before making any changes to actual resources.
    • The optional -out parameter allows you to specify an output file for the plan. Using the -out parameter ensures that the plan you reviewed is exactly what is applied.
    • To read more about persisting execution plans and security, see the security warning section.
  2. Run terraform apply to apply the execution plan.

    terraform apply <terraform_plan>.destroy.tfplan
    

Troubleshooting

For Terraform-specific support, use one of HashiCorp's community support channels to Terraform:

Next steps