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.

Please turn AdBlock off
Floating Social Media Icons by Acurax Wordpress Designers

Discover more from Direct DevOps from Quality Thought

Subscribe now to keep reading and get access to the full archive.

Continue reading

Visit Us On FacebookVisit Us On LinkedinVisit Us On Youtube