DevOps Classroom Series – 06/Jun/2020

Linux Virtual Machine in Terraform

  • Template is as shown below

provider "azurerm" {
    features {}
}

locals {
  common_tags = {
        env         = "dev"
        created_by  = "terraform"
        team        = "devops"
    }
  groupname = "terraform"
}

variable "location" {
  default = "eastus"
}


variable "network_name" {
  default = "ntier"
}

variable "networkcidr" {
  description = "cidr of the network"
  default = "192.168.0.0/16"
}

variable "subnetnames" {
    type   = list(string)
    default = ["web", "app", "db", "management"]
}

variable "ipname" {
  default = "myip"
}

variable "username" {
  default = "qtdevops"
}

variable "password" {
  default = "motherindia@123"
}






resource "azurerm_resource_group" "tfgroup" {
    name                    = "terraform"
    location                = var.location
    tags                    = local.common_tags
}

resource "azurerm_virtual_network" "ntier" {
    name                    = var.network_name
    
    address_space           = [var.networkcidr]
    resource_group_name     = local.groupname
    location                = var.location

    tags                    = local.common_tags
    depends_on              = [azurerm_resource_group.tfgroup]
}

resource "azurerm_subnet" "subnets" {
    count                   = length(var.subnetnames)
    name                    = var.subnetnames[count.index]
    resource_group_name     = local.groupname
    virtual_network_name    = var.network_name
    address_prefixes        = [cidrsubnet(var.networkcidr,8,count.index)]      
    depends_on              = [azurerm_resource_group.tfgroup, azurerm_virtual_network.ntier]
  
}


resource "azurerm_public_ip" "myip" {
    resource_group_name     = local.groupname
    location                = var.location
    name                    = var.ipname
    allocation_method       = "Dynamic"
    tags                    = local.common_tags
    depends_on              = [azurerm_resource_group.tfgroup]
  
}


resource "azurerm_network_interface" "mynic" {
    name                    = "mynic"
    location                = var.location
    resource_group_name     = local.groupname

    ip_configuration {
        name                = "mynicconfig"
        subnet_id           = azurerm_subnet.subnets[0].id
        private_ip_address_allocation   = "Dynamic"
        public_ip_address_id    = azurerm_public_ip.myip.id
    }

    tags                    = local.common_tags

    depends_on              = [azurerm_resource_group.tfgroup, azurerm_public_ip.myip]
  
}

resource "azurerm_storage_account" "mystorageaccount" {
    name                        = "qtstoragefortf"
    resource_group_name         = local.groupname
    location                    = var.location
    account_replication_type    = "LRS"
    account_tier                = "Standard"

    tags                        = local.common_tags
    depends_on                  = [azurerm_resource_group.tfgroup]
  
}

resource "azurerm_linux_virtual_machine" "myvm" {
    name                        = "qtdevops"
    location                    = var.location
    resource_group_name         = local.groupname
    tags                        = local.common_tags
    network_interface_ids       = [azurerm_network_interface.mynic.id]
    size                        = "Standard_B1s"
    admin_username              = var.username
    admin_password              = var.password
    disable_password_authentication = false

    os_disk {
        name                    = "myOsDisk"
        caching                 = "ReadWrite"
        storage_account_type    = "Premium_LRS"
    }

    source_image_reference {
        publisher               = "Canonical"
        offer                   = "UbuntuServer"
        sku                     = "18.04-LTS"
        version                 = "latest"
    }

    boot_diagnostics {
        storage_account_uri     = azurerm_storage_account.mystorageaccount.primary_blob_endpoint
    }

    depends_on                  = [azurerm_resource_group.tfgroup, azurerm_storage_account.mystorageaccount ]

    provisioner "remote-exec" {
        inline                  = [
            "sudo apt-get update",
            "sudo apt-get install apache2 -y "
        ]

        connection {
            host                = self.public_ip_address
            user                = self.admin_username
            password            = self.admin_password
        }
    }
  
}


  • Now we know how to write templates (In new cloud environments we will make note of steps)

Multiple Users Executing Terraform templates

  • Multiple Users Executing terraform templates will create the resources multiple times reason for this terraform tries to store the resource in the local machine of the user by default Preview

  • In terraform backend is the location where the state is stored. Now if we try to configure the remote-backend which is shared to both users.

  • Terraform supports various standard backends for state storage remotely Refer Here Preview

  • To ensure users cannot write to the simulataineously state locking is available. Note in the case aws for state locking you need to create dynamodb table Refer Here

  • In this series i will be using azure rm backend Refer Here

  • Steps:

    1. created a resource group name sharedstate
    2. create a storage account in this resourcegroup with name tfforqtsharedstate
    3. create a container in this storage account with name terraformstate
  • Now configure backend in template in a new file backend.tf

terraform {
    backend "azurerm" {
        resource_group_name  = "sharedstate"
        storage_account_name = "tfforqtsharedstate"
        container_name       = "terraformstate"
        key                  = "default.terraform.tfstate"
    }
}
  • Now execute terraform init . Preview

  • Now execute terraform apply . Preview

  • Navigate to azure storage account and see the contents of the container Preview

  • When other user tries to execute, terraform will not allow the other user Preview

  • Try using s3 backend by using modules such as Refer Here

  • Use case: Mike and Richard are execute same template but for different environments and when we use remote backends , only one user is allowed even if the environments are different Preview

  • Terraform has introduced workspaces Refer Here

  • Terraform always a default workspace

terraform workspace --help
terraform workspace list
terraform workspace new 
terraform workspace select

Preview Preview Preview

  • Now navigate to the azurerm backend container Preview
  • Now parallely other user on other machine can use the same code
terraform init
terraform workspace new qa
terraform apply -var-file qa.vars -auto-approve .

Blue-Green Deployments in Terraform

variable "enable_green_env" {
  default = false
  type    = bool
}
  • Now for the resources like vm’s
resource "azurerm_linux_virtual_machine" "bluewebvm" {
    count           = var.enable_green_env ? 0 : 1
    ...
    ...
    ...

}

resource "azurerm_linux_virtual_machine" "greenwebvm" {
    count           = var.enable_green_env ? 1 : 0
    ...
    ...
    ...

}


Next Topic

  • Packer: Ensure you go through json basics

Exercise:

  1. Write a Terraform template to deploy nop Commerce on azure or aws
  2. People aware of AWS and Azure try creating a VMSS/ASG using terraform

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About learningthoughtsadmin