Azure Infrastructure Automation with Terraform ( Part 3 )

Infrastructure as Code (IaC)

Azure Infrastructure Automation with Terraform ( Part 3 )

We are going to create Azure Standard Load Balancer Resources as part of this blog.

  1. azurerm_public_ip

  2. azurerm_lb

  3. azurerm_lb_backend_address_pool

  4. azurerm_lb_probe

  5. azurerm_lb_rule

  6. azurerm_network_interface_backend_address_pool_association

  7. Comment Azure Bastion Service as we are already using Azure Bastion Host approach with Linux VM

Steps:

  1. Create file 9_01_web_loadbalancer_input_variables .

     # Placeholder file for Load Balancer Input Variables
    
  2. Create file 9_02_web_loadbalancer_resource.tf

     # Resource-1: Create Public IP Address for Azure Load Balancer
    
     resource "azurerm_public_ip" "web_lbpublicip" {
         name = "${local.resource_name_prefix}-lbpublicip" 
         resource_group_name = azurerm_resource_group.rg.name
         location = azurerm_resource_group.rg.location
         allocation_method = "Static"
         sku = "Standard"
         tags = local.comman_tags
     }
    
     # Resource-2: Create Azure Standard Load Balancer
    
     resource "azurerm_lb" "web_lb" {
       name = "${local.resource_name_prefix}-web-lb"
       resource_group_name = azurerm_resource_group.rg.name
       location = azurerm_resource_group.rg.location
       sku = "Standard"
       frontend_ip_configuration {
         name = "web-web-publicip-1"
         public_ip_address_id = azurerm_public_ip.web_lbpublicip.id
       }
     }
    
     # Resource-3: Create LB Backend Pool
    
     resource "azurerm_lb_backend_address_pool" "web_lb_backend_address_pool" {
    
       name = "web-backend"
       loadbalancer_id = azurerm_lb.web_lb.id
    
     }
    
     # Resource-4: Create LB Probe
     resource "azurerm_lb_probe" "web_lb_probe" {
       name = "tcp_probe"
       protocol = "Tcp"
       port = 80
       loadbalancer_id = azurerm_lb.web_lb.id
    
     }
    
     # Resource-5: Create LB Rule
     resource "azurerm_lb_rule" "web_lb_rule_app1" {
       name = "web-app1-rule"
       protocol = "Tcp"
       frontend_port = 80
       backend_port = 80
       frontend_ip_configuration_name = azurerm_lb.web_lb.frontend_ip_configuration[0].name
       backend_address_pool_ids = [azurerm_lb_backend_address_pool.web_lb_backend_address_pool.id]
       probe_id = azurerm_lb_probe.web_lb_probe.id
       loadbalancer_id = azurerm_lb.web_lb.id
     }
    
     # Resource-6: Associate Network Interface and Standard Load Balancer
     resource "azurerm_network_interface_backend_address_pool_association" "web_nic_lb_associate" {
       network_interface_id = azurerm_network_interface.web_linuxvm_nic.id
       ip_configuration_name = azurerm_network_interface.web_linuxvm_nic.ip_configuration[0].name
       backend_address_pool_id = azurerm_lb_backend_address_pool.web_lb_backend_address_pool.id
     }
    
  3. Create file 9_03_web_loadbalancer_outputs.tf

     # LB Public IP
     output "web_lb_public_ip_address" {
       description = "Web Load Balancer Public Address"
       value = azurerm_public_ip.web_lbpublicip.ip_address
     }
    
     # Load Balancer ID
     output "web_lb_id" {
       description = "Web Load Balancer ID."
       value = azurerm_lb.web_lb.id 
     }
    
     # Load Balancer Frontend IP Configuration Block
     output "web_lb_frontend_ip_configuration" {
       description = "Web LB frontend_ip_configuration Block"
       value = [azurerm_lb.web_lb.frontend_ip_configuration]
     }
    
  4. Comment Azure Bastion Service which takes a longer time to create Resources.
    Also we have the Azure Bastion Host Linux VM for us if required to login to Private VMs.
    (file: 8_04_AzureBastionService.tf )

     /*
     # Azure Bastion Service - Resources
     ## Resource -1 : Azure Bastion Subnet
    
     resource "azurerm_subnet" "bastion_service_subnet" {
       name = var.bastion_service_subenet_name
       resource_group_name = azurerm_resource_group.rg.name
       virtual_network_name = azurerm_virtual_network.vnet.name
       address_prefixes = var.bastion_service_address_prefixs
     }
    
     ## Resource - 2: Azure Bastion Public IP
    
     resource "azurerm_public_ip" "bastion_service_publicip" {
       name = "${local.resource_name_prefix}-bastion_service_publicip"
       location = azurerm_resource_group.rg.location
       resource_group_name = azurerm_resource_group.rg.name
       allocation_method = "Static"
       sku = "Standard"
     }
    
     ## Resource -3: Azure Bastion Service Host
    
     resource "azurerm_bastion_host" "bastion_host" {
       name = "${local.resource_name_prefix}-bastion_service"
       location = azurerm_resource_group.rg.location
       resource_group_name = azurerm_resource_group.rg.name
    
       ip_configuration {
         name = "configuration"
         subnet_id = azurerm_subnet.bastion_service_subnet.id
         public_ip_address_id = azurerm_public_ip.bastion_service_publicip.id
       }
    
     }
     */
    
  5. Execute Terraform Commands

     # Terraform Initialize
     terraform init
    
     # Terraform Validate
     terraform validate
    
     # Terraform Plan
     terraform plan
    
     # Terraform Apply
     terraform apply -auto-approve
    

  6. Verify Resources

     # Verify Resources - Virtual Network
     1. Azure Resource Group
     2. Azure Virtual Network
     3. Azure Subnets (Web, App, DB, Bastion)
     4. Azure Network Security Groups (Web, App, DB, Bastion)
     5. View the topology
     6. Verify Terraform Outputs in Terraform CLI
    
     # Verify Resources - Web Linux VM 
     1. Verify Network Interface created for Web Linux VM
     2. Verify Web Linux VM
     3. Verify Network Security Groups associated with VM (web Subnet NSG)
     4. View Topology at Web Linux VM -> Networking
     5. Verify if only private IP associated with Web Linux VM
    
     # Verify Resources - Bastion Host
     1. Verify Bastion Host VM Public IP
     2. Verify Bastion Host VM Network Interface
     3. Verify Bastion VM
     4. Verify Bastion VM -> Networking -> NSG Rules
     5. Verify Bastion VM Topology
    
     # Connect to Bastion Host VM
     1. Connect to Bastion Host Linux VM
     ssh -i ssh-keys/terraform-azure.pem azureuser@<Bastion-Host-LinuxVM-PublicIP>
     sudo su - 
     cd /tmp
     ls 
     2. terraform-azure.pem file should be present in /tmp directory
    
     # Connect to Web Linux VM using Bastion Host VM
     1. Connect to Web Linux VM
     ssh -i ssh-keys/terraform-azure.pem azureuser@<Web-LinuxVM-PrivateIP>
     sudo su - 
     cd /var/log
     tail -100f cloud-init-output.log
     cd /var/www/html
     ls -lrt
     cd /var/www/html/app1
     ls -lrt
     exit
     exit
    
     # Verify Standard Load Balancer Resources
     1. Verify Public IP Address for Standard Load Balancer
     2. Verify Standard Load Balancer (SLB) Resource
     3. Verify SLB - Frontend IP Configuration
     4. Verify SLB - Backend Pools
     5. Verify SLB - Health Probes
     6. Verify SLB - Load Balancing Rules
     7. Verify SLB - Insights
     8. Verify SLB - Diagnose and Solve Problems
    
     # Access Application
     http://<LB-Public-IP>
     http://<LB-Public-IP>/app1/index.html
     http://<LB-Public-IP>/app1/metadata.html
    

    -- Resource Group

    -- Vnet (hr-dev-vnet)

    -- Subnets

    -- Virtual machines

    -- Load Balancer (hr-dev-web-lb)

  7. Delete Resources

     # Delete Resources
     terraform destroy 
     [or]
     terraform apply -destroy -auto-approve
    
     # Clean-Up Files
     rm -rf .terraform* 
     rm -rf terraform.tfstate*
    

    Load balancer implementation has been done and in next blog we will create Inbound NAT Rule for Standard Load Balancer.

Github Repo Link: https://github.com/DeoreRohit4/Azure-Infrastructure-Automation-with-Terraform-

Blogs:
Part 1: https://rohitexplainstech.hashnode.dev/azure-infrastructure-automation-with-terraform
Part 2: https://rohitexplainstech.hashnode.dev/azure-infrastructure-automation-with-terraform-part-2


Keep Exploring...