LetsDevOps: Terraform on Azure Tutorial for Beginner's, Deploy IAC using GitHub Actions.

Introduction


Terraform is Open Source Infrastructure as code which allow to Automate and Manage Infrastructure, Services and platform.


It is declarative language.

# Create the resource group
resource "azurerm_resource_group" "rg" {
  name     = "myResourceGroup-${random_integer.ri.result}"
  location = "eastus"
}

Where to Use Terraform:





Use Cases:

  • Create Infrastructure

  • Update Infrastructure

  • Replicate the Infrastructure

Architecture



Terraform Configurations Files

Lets assume we are going to create Azure Web App service.


providers.tf

Provider configuration file consist of

  • Cloud Provider Declaration like Azure, AWS, Google Cloud

  • backend Remote state file configuration

terraform {

  required_version = ">=0.12"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>2.0"
    }
  }
  backend "azurerm" {
    resource_group_name  = "<storage_account_resource_group>"
    storage_account_name = "<storage_account_name>"
    container_name       = "tfstate"
    key                  = "codelab.microsoft.tfstate"
  }
}

provider "azurerm" {
  features {}
}

main.tf

It contains the main configuration module of infrastructure.



# Create the resource group
resource "azurerm_resource_group" "rg" {
  name     = var.resource_group_name
  location = var.resource_group_location
}
# Create the Linux App Service Plan
resource "azurerm_app_service_plan" "appserviceplan" {
  name                = var.app_service_plan_name
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  sku {
    tier = "Free"
    size = "F1"
  }
}
# Create the web app, pass in the App Service Plan ID

resource "azurerm_app_service" "webapp" {
  name                = var.webapp_service_name
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  app_service_plan_id = azurerm_app_service_plan.appserviceplan.id
}
variables.tf

This helps to declare all the required variables used in main.tf file.


variable "resource_group_name" {
  default       = "webapp-rg"
  description   = "Name of the resource group."
}

variable "resource_group_location" {
  default       = "eastus"
  description   = "Location of the resource group."
}

variable "app_service_plan_name" {
  default       = "webapp-asp"
  description   = "Location of the resource group."
}
 
variable "webapp_service_name" {
  default       = "webapp-demo"
  description   = "Location of the resource group."
}
output.tf

This helps to extract the Resource detail and display.

output "resource_group_name" {
  value = azurerm_resource_group.rg.name
}

output "webapp_service_name" {
    value = azurerm_app_service.webapp.name
}

dev.tfvars

This is used for the defining the variables specific to the environment or service.

resource_group_name ="devops_dev_rg"
resource_group_location="eastus"
app_service_plan_name="asp-webapp"
webapp_service_name="devops-demo-dev"

preprod.tfvars
resource_group_name ="devops_dev_rg"
resource_group_location="eastus"
app_service_plan_name="asp-webapp-prd"
webapp_service_name="devops-demo-dev"
prod.tfvars
resource_group_name ="devops_dev_rg"
resource_group_location="eastus"
app_service_plan_name="name"
webapp_service_name="devops-demo-dev"

Manage Backends

Backend helps to setup the terraform state file. As per best practice we will learn to setup the remote backend using Azure Storage Account.


1. Create Storage Account

2. Create Container and update the providers.tf


 backend "azurerm" {
    resource_group_name  = "<storage_account_resource_group>"
    storage_account_name = "<storage_account_name>"
    container_name       = "tfstate"
    key                  = "terraform.tfstate"
  }


Workspaces


Workspace helps to manager multiple environment. Like dev,uat,prod.

Assume we are having three different infra setup under the same configuration file.


So for that we can create three workspace and run the terraform command. In Backend it will create three different state file instance per workspace.




Terraform Important Commands

  • terraform init

  • terraform refresh

  • terraform validate

  • terraform plan

  • terraform apply

  • terraform destroy --> Destroy Previously created Infrastructure


Terraform Execution flow



Setup Remote Backend

Create Azure Storage Account & Container which will be used as backend to store the terraform state file.



Update Provider.tf File

Once the Storage Create update the providers.tf with Details Like


https://github.com/sumitraj0103/Letsdevops/blob/main/TerraformIAC/providers.tf


terraform {

  required_version = ">=0.12"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>2.0"
    }
  }
  backend "azurerm" {
    resource_group_name  = "devops-terraform-iac"
    storage_account_name = "iacterrafromstate"
    container_name       = "tfstate"
    key                  = "terraform.tfstate"
  }
}

provider "azurerm" {
  features {}
}


Setup Workflow File

For Demo we have created the Source Repo to create the azure web app.

Project is available at:


https://github.com/sumitraj0103/Letsdevops/tree/main/TerraformIAC


Workflow File:

https://github.com/sumitraj0103/Letsdevops/blob/main/.github/workflows/TerraformIAC.yml


Workflow YAML to Run the Terraform Project file.


Input Parameters
  • ENVIRONMENT --> Select Environment to deploy the Terraform Project

  • CreateWorkspace --> Yes if for First time run the Create workspace for Dev/Uat/Prod

on:
  workflow_dispatch:
    inputs:
      #Name of your Environment
      ENVIRONMENT:
        description: 'Deployment Environment (Non-Prod/Pre-Prod/Prod)'
        required: true
        default: 'Non-Prod'
      CreateWorkspace:
        description: 'First Time Run -->Choose Yes'
        required: true
        default: 'no'

Service Principal Secret for Deploy Infrastructure as Code

This can be also manage through KeyVault.

  • TF_ARM_CLIENT_ID

  • TF_ARM_CLIENT_SECRET

  • TF_ARM_SUBSCRIPTION_ID

  • TF_ARM_TENANT_ID



How to Run the Workflow

Once the setup is completed now we can run the workflow and see the result.


Create Workspace

Since we are assuming we have three environment we are going to create below workspace.

  1. dev

  2. uat

  3. prod

This can be updated as per your requirement as well.


Run below Workflow:

https://github.com/sumitraj0103/Letsdevops/actions/workflows/TerraformIAC.yml


On Successful Execution.
Result in Remote Backend Storage Account.




Run the Infrastructure Deployment



Result