Menu

Getting started with Terraform Azure – Provision & Manage any Infrastructure

Each organisation is different, some has dedicated teams to manage and provision resources. But if you were to manage them your self as a developer, either you login to Azure Portal and create necessary resources yourself or you CI/CD (Infrastructure as a code) do it as part of the release. You will anyway have to build pipelines for deployments, why not include “Infrastructure as a code” as part of a release. Also, you will have source control for the “Infrastructure as a code”

In the past, I have been using Azure ARM templates, but it has been a bit confusing building JSON file, especially when you have many resources and configurations, you will easily get lost on your own JSON.

This is where Terraform comes handy; it makes not only readable code, but also minimal lines of code.

Let’s see how you can build the code on your PC before you add it to the pipeline. You can run the same code over and over to get it right and test it before you actually create resources in Azure.

Install terraform CLI 

https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/azure-get-started

Install Azure CLI

https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?tabs=azure-cli

Login to your Azure subscription – using PowerShell

  • login to your Azure subscription
    az login

    Once the login is completed on the browser you will see something like below

    {
        "cloudName": "AzureCloud",
        "homeTenantId": "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx",
        "id": "ssssxxx-dddd-eee-ddd-eeeeeee",
        "isDefault": true,
        "managedByTenants": [],
        "name": "Azure PAID Subscription",
        "state": "Enabled",
        "tenantId": "xxxx-xxx-4b29-xxx-ccccc",
        "user": {
          "name": "yor@mail.com",
          "type": "user"
        }
      },

    Copy the subscription id (make sure you don’t share any of these Ids)

  • Set your default subscription id (if you have a single subscription you don’t have to do this)
    az account set --subscription="XXXXX-XXXX-XXXX-XXXX-XXXXXXXX"

You will need to create 2 files main.tf and variables.tf

in the main.tf file, I am going to follow recommended abbreviations for Azure resource types
Full reference to Azure resource types and their configurations can be found here
Below is the main.tf file
# Configure the Azure provider
terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = ">= 2.26"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg" {
  name     = "ml_${var.environment}_rg_${var.appname}"
  location = var.location

  tags     = var.tags
}

resource "azurerm_storage_account" "rg" {
  name                     = "st${var.appname}${var.environment}"
  resource_group_name      = azurerm_resource_group.rg.name
  location                 = azurerm_resource_group.rg.location
  account_tier             = "Standard"
  account_replication_type = "LRS"

  tags                     = var.tags
}

resource "azurerm_application_insights" "rg" {
  name                = "appi-${var.appname}-${var.environment}"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  application_type    = "web"
}

resource "azurerm_sql_server" "rg" {
  name                         = "sql-${var.appname}-${var.environment}"
  resource_group_name          = azurerm_resource_group.rg.name
  location                     = azurerm_resource_group.rg.location
  version                      = "12.0"
  administrator_login          = "sql-${var.appname}-admin-${var.environment}"
  administrator_login_password = var.administrator_login_password

  tags                         = var.tags  
}

resource "azurerm_sql_database" "rg" {
  name                = "sqldb-${var.appname}-${var.environment}" 
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  server_name         = azurerm_sql_server.rg.name
  
  tags  = var.tags
}

resource "azurerm_app_service_plan" "rg" {
  name                = "azapp-${var.appname}-${var.environment}"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  sku {
    tier = "ElasticPremium"
    size = "EP1"
  }

  tags  = var.tags
}

resource "azurerm_function_app" "rg" {
  name                       = "func-${var.appname}-${var.environment}"
  location                   = azurerm_resource_group.rg.location
  resource_group_name        = azurerm_resource_group.rg.name
  app_service_plan_id        = azurerm_app_service_plan.rg.id
  storage_account_name       = azurerm_storage_account.rg.name
  storage_account_access_key = azurerm_storage_account.rg.primary_access_key

  tags  = var.tags
}

output "instrumentation_key" {
  value = azurerm_application_insights.rg.instrumentation_key
}

output "app_id" {
  value = azurerm_application_insights.rg.app_id
}

you can configure your variables in variables.tf, they can be either constants or parameters that get passed in by CI/CD

Below is the variables.tf file, please note that I have not set a default value to “administrator_login_password”, therefore it will ask for value. later I will set it up as a secure variable in Azure DevOps (alternatively in Key Vault)

variable "appname" {
  type    = string
  default = "profile"
}

variable "location" {
  type    = string
  default = "australiasoutheast"
}

variable "environment" {
  type    = string
  default = "dev"
}

variable "administrator_login_password" {
  type    = string
}

variable "tags" {
  type = map

  default = {
    Application = "AppSuperman"
    Department  = "Superman Unit"    
    Environment = "dev"
  }
}

In a Powershell window, if you are running the script for the first time

terraform init
test your script is working (this is not my real password – haha)
terraform plan -var "environment=tst" -var "administrator_login_password=8891c2ce-399c-11eb-adc1-0242ac120002"

Once everything is working as expected you can run the below script to create your resources in Azure

terraform apply -var "environment=tst" -var "administrator_login_password=8891c2ce-399c-11eb-adc1-0242ac120002" -auto-approve

Deleting your resources – DO NOT include this in CI/CD, and be careful with your local as you can’t revert

terraform destroy -var "environment=tst" -var "administrator_login_password=XXXX"

 

 

 

 

 

Leave a comment