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
-
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
-
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:
- created a resource group name sharedstate
- create a storage account in this resourcegroup with name tfforqtsharedstate
- 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 .
-
Now execute
terraform apply .
-
Navigate to azure storage account and see the contents of the container
-
When other user tries to execute, terraform will not allow the other user
-
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
-
Terraform has introduced workspaces Refer Here
-
Terraform always a default workspace
terraform workspace --help
terraform workspace list
terraform workspace new
terraform workspace select
- Now navigate to the azurerm backend container
- 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
- Refer Here
- Add a variable
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:
- Write a Terraform template to deploy nop Commerce on azure or aws
- People aware of AWS and Azure try creating a VMSS/ASG using terraform