Create Azure resources using Terraform and Azure CLI – Windows Edition

Let’s have some fun in Azure with terraform. This article you will see how to create some resources in Azure with help from terraform:

  • resource group
  • virtual network

First, we need to install Azure CLI because this will be used for authentication. You can download the MSI installer, run PowerShell command, or use the binary. Check Microsoft documentation for details: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?view=azure-cli-latest

After installation is ready, open CMD and login to Azure CLI by typing:

az login

This will open a tab in browser for you to provide your Microsoft account user and password, after which you can close it and check your command line:

C:\WINDOWS\system32>az login
You have logged in. Now let us find all the subscriptions to which you have access...
[
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "xxxxxxxxxxxxxxxxxxxxxxx",
    "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "isDefault": true,
    "managedByTenants": [],
    "name": "Free Trial",
    "state": "Enabled",
    "tenantId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "user": {
      "name": "[email protected]",
      "type": "user"
    }
  }
]

Configure Terraform to use Azure CLI

Now that we’re logged into the Azure CLI – we can configure Terraform to use these credentials. Create a config file main.tf and add this block:

provider "azurerm" {
  # Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used
  version = "=1.44.0"
}

Configuration files can be in either of two formats: HashiCorp Configuration Language (HCL), or JSON.  I’m using HCL format.

Workflows

A simple workflow for deployment will follow closely to the steps below.

  1. Scope – Confirm what resources need to be created for a given project.
  2. Author – Create the configuration file in HCL based on the scoped parameters
  3. Initialize – Run terraform init in the project directory with the configuration files. This will download the correct provider plug-ins for the project.
  4. Plan & Apply – Run terraform plan to verify the creation process and then terraform apply to create real resources as well as state file that compares future changes in your configuration files to what actually exists in your deployment environment.

At this moment we add the block to make terraform use Azure CLI. Run terraform init and let’s see the output:

D:\terraform>terraform init

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "azurerm" (hashicorp/azurerm) 1.44.0...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Create Azure Resource Group

In order to create a resource group we need to add another block to our main.tf file.

resource "azurerm_resource_group" "helpmedevops" {
  name     = "helpmedevops"
  location = "West Europe"
}

In this block we provide a name for our group and a region where to be created. Run terraform plan to see what is happening:

D:\terraform>terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

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.helpmedevops will be created
  + resource "azurerm_resource_group" "helpmedevops" {
      + id       = (known after apply)
      + location = "westeurope"
      + name     = "helpmedevops"
      + tags     = (known after apply)
    }

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

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

We see in output what resources will be created and with which parameters. Run terraform apply to start creating the group. Type yes when is requested.

D:\terraform>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.helpmedevops will be created
  + resource "azurerm_resource_group" "helpmedevops" {
      + id       = (known after apply)
      + location = "westeurope"
      + name     = "helpmedevops"
      + tags     = (known after 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.helpmedevops: Creating...
azurerm_resource_group.helpmedevops: Creation complete after 1s [id=/subscriptions/xxxxxxxxxxxxxxxxxxx/resourceGroups/helpmedevops]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Check in Azure portal or you can run az group list.

D:\terraform>az group list
[
  {
    "id": "/subscriptions/xxxxxxxxxxxxxxxxxx/resourceGroups/helpmedevops",
    "location": "westeurope",
    "managedBy": null,
    "name": "helpmedevops",
    "properties": {
      "provisioningState": "Succeeded"
    },
    "tags": {},
    "type": "Microsoft.Resources/resourceGroups"
  }
]

Create Azure virtual network

Azure virtual network is like a virtual space to keep virtual machines. We need to add another block for this and this VNET will be created inside the resource group “helpmedevops”

resource "azurerm_virtual_network" "helpmedevops-network" {
  name          = "helpmedevops-network"
  resource_group_name = azurerm_resource_group.helpmedevops.name
  address_space = ["10.1.2.0/24"]
  location      = "West Europe"
  subnet {
    name           = "helpmedevops-subnet"
    address_prefix = "10.1.2.0/25"
  }
}

Check Azure portal or run az network vnet list to see the virtual network created.

You can find more information related to all the modules available for Azure and how to use them on terraform official website: https://www.terraform.io/docs/providers/azurerm/index.html