changed 2 years ago
Published Linked with GitHub

DevOps Training Session 7: Terraform

tags: devops research reliable

Hello like i said on the last topic, terraform is way to solving anything problem with cloud ? Easy way to done job > So go far with that && Happy with implementation > :coffee:

Setup the Terraform and init some extension

Reference for full information > LINK

#!/bin/bash

wget https://releases.hashicorp.com/terraform/1.3.7/terraform_1.3.7_linux_amd64.zip
unzip terraform_1.3.7_linux_amd64.zip
sudo cp terraform /usr/local/bin
terraform --version

After install you whill receive and install terraform succesful with version

And some extension for VSCode > Increase productivity like



Do the lab > Run by step by step :coffee:

After install the terraform cli for terminal >
Next step you can read some reference in the document of terraform

> U need to understand which terraform give for us for using to implementation for each script :sandwich:

> After that reach to my script > I will analysis from each part to part to resolve the problem of script

So i will split the bunch of script of terraform to 3 file for easy management and apply

  • So when i want to apply terraform > i think you need split all of part of source into separate file like

    • outputs.tf > Manage output from terraform
    • main.tf > Manage the resource for update or create part on the cloud
    • providers.tf > Manage authentication && storage configurate for terraform to associated with terraform
  • After split that > reach to the scripting
    providers.tf

# Get the resource backend from the Private Storage backend
terraform {
  backend "azurerm" {
      resource_group_name = <resource_group_name>
      storage_account_name = <storage_account_name>
      container_name = <container_name_on_storage_account>
      key = <name_of_tfstate_file>
  }
}

provider "azurerm" {
  features{}
}
  • So on this script, usually if you implement with terraform > u need some kind configuration like a library contain API to association with platform you want, terraform have many options:
    • azurerm > association with azure, bucket will storage it on the container on azure account
    • local > This backend status using tfstate have exist on local you can import this path into that kind and use that
    • remote > This backend will use tfstate on remote env kind your server, your drive, you NAS > Anykind
    • aws > association with AWS
    • blah blah

> Provider, backend depend on your choice, get the suitable for your target

main.tf

# Get data_resource from RG
data "azurerm_resource_group" "current" {
  name = "DevOpsIntern"
}

# Get data_resource from sshkey
data "azurerm_ssh_public_key" "my_vm_public_key" {
  name = "DevOpsIntern"
  resource_group_name = data.azurerm_resource_group.current.name
}

# Create network
resource "azurerm_virtual_network" "my_terraform_network" {
  name = "LinuxVMnet"
  address_space = ["10.0.0.0/16"]
  location = data.azurerm_resource_group.current.location
  resource_group_name = data.azurerm_resource_group.current.name
}

# Create the subnet
resource "azurerm_subnet" "my_terraform_network_subnet" {
  name = "LinuxVMsubnet"
  resource_group_name = data.azurerm_resource_group.current.name
  virtual_network_name = azurerm_virtual_network.my_terraform_network.name
  address_prefixes = ["10.0.1.0/24"]
}

# Create public IP
resource "azurerm_public_ip" "my_terraform_public_ip" {
  name = "LinuxVMpubIP"
  location = data.azurerm_resource_group.current.location
  resource_group_name = data.azurerm_resource_group.current.name
  allocation_method = "Dynamic"
}

# Create a SecurityGroup
resource "azurerm_network_security_group" "my_terraform_nsg" {
  name = "LinuxVMNetworkingSecurityGroup"
  location = data.azurerm_resource_group.current.location
  resource_group_name = data.azurerm_resource_group.current.name

  security_rule {
    name = "SSH"
    priority = 1001
    direction = "Inbound"
    access = "Allow"
    protocol = "Tcp"
    source_port_range = "*"
    destination_port_range = "22"
    source_address_prefix = "*"
    destination_address_prefix = "*"
  }

  security_rule {
    name = "HTTP"
    priority = 1002
    direction = "Inbound"
    access = "Allow"
    protocol = "Tcp"
    source_port_range = "*"
    destination_port_range = "80"
    source_address_prefix = "*"
    destination_address_prefix = "*"
  }

  security_rule {
    name = "HTTPS"
    priority = 1003
    direction = "Inbound"
    access = "Allow"
    protocol = "Tcp"
    source_port_range = "*"
    destination_port_range = "443"
    source_address_prefix = "*"
    destination_address_prefix = "*"
  }
  tags = {
    <Your_choice> = <Your_choice>
    <Your_choice> = <Your_choice>
  }
}

# Create NIC
resource "azurerm_network_interface" "my_terraform_nic" {
  name = "LinuxVMNic"
  location = data.azurerm_resource_group.current.location
  resource_group_name = data.azurerm_resource_group.current.name

  ip_configuration {
    name = "my_nic_configuration"
    subnet_id = azurerm_subnet.my_terraform_network_subnet.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id = azurerm_public_ip.my_terraform_public_ip.id
  }
}

# Get the connect between NIC and security group
resource "azurerm_network_interface_security_group_association" "my_terraform_asNicSG" {
  network_interface_id = azurerm_network_interface.my_terraform_nic.id
  network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id
}

# Create the virtual machine
resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
  name = "LinuxVM"
  computer_name = "LinuxVM"
  resource_group_name = data.azurerm_resource_group.current.name
  location = data.azurerm_resource_group.current.location
  size = "Standard_B1s"
  admin_username = "intern"
  network_interface_ids = [azurerm_network_interface.my_terraform_nic.id]
  os_disk {
    name = "LinuxVM_disk"
    caching = "ReadWrite"
    storage_account_type = "StandardSSD_LRS"
  }

  admin_ssh_key {
    username = "intern"
    public_key = data.azurerm_ssh_public_key.my_vm_public_key.public_key
  }

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

  disable_password_authentication = true
  tags = {
    managed_by = "terraform"
    environment = "dev"
  }
}

It just a bunch of script using for create a VM on Azure > this just basic script refer with syntax from Terraform doc and using azurerm, just this :smile_cat:

output.tf

# Output the public IP address is created from Azure 
output "public_ip_address" {
  value = azurerm_linux_virtual_machine.my_terraform_vm.public_ip_address
}

So after create the vm you want to get ip_address to access so > Get on it

> Well after create all kind that you just need

​​​​terraform init
​​​​terraform plan 
​​​​terraform apply -auto-approve

Just use some command each times to times like

  • terraform init Using for create and get provider for terraform > create 1 folder storage some configuration and api for using with platform > create hcl and tfstate file if you using local
  • terraform plan Using for check the plan before apply into cloud platform mine option or your option :smiley:
  • terraform apply Do the stuff about apply plan configuration to platform you want like github, like azure, like aws,
  • After that just wait to get result :breast-feeding:
  • Quite easy huh

So i have some script about my teammate implement with Nguyen Hoai Bao Nguyen for option to choose do it with terraform

run_terraform.sh

#!/bin/bash

# Get the absolution of path
abs_path_file_execute=$(realpath "$0")
abs_path_folder_script=$(dirname "$abs_path_file_execute")
abs_path_folder_root=$(dirname "$(dirname "$abs_path_file_execute")")
abs_path_folder_terraform="$abs_path_folder_root""/terraform/modules/vm/"


# Bash Menu Script Example
echo "---------MENU------------"
PS3='Please enter your choice: '
options=("Create virtual machine" "Destroy virtual machine" "Quit")
select opt in "${options[@]}"
do
    case $opt in
        "Create virtual machine")
            cd $abs_path_folder_terraform
            terraform init
            terraform plan 
            terraform apply -auto-approve
        ;;
        "Destroy virtual machine")
            cd $abs_path_folder_terraform
            terraform destroy -auto-approve
        ;;
        "Quit")
            break
            ;;
        *) echo "invalid option $REPLY";;
    esac
done
  • Script like i said above about do it with manual, script do it automatic for me for instead of > just add terraform desrtroy it will using to destroy the all configuration you create by terrafrom into platform
  • Just it some basic terrafrom quite easy to understand about infra as code :coffee:

Reference

Select a repo