Friday, February 24, 2023

Hashicorp Terraform

 

Lab Information and How Tos

Reference: GitHub - terraform-azure-2453108

Cloning to VScode

To clone the lab information and how-tos repository to VScode, follow these steps:

  • Open VScode and navigate to the terminal.
  • Run the command git clone https://github.com/LinkedInLearning/terraform-azure-2453108.git.

Installing Azure CLI on PShell 7.2 and VS Terminal for PShell

Reference: Install Azure CLI on Windows

  1. To install the Azure CLI module, run the command Install-module Azurecli in PShell or VS Terminal for PShell.
  2. Also, add the Azure CLI extension from VS by running the command $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'; rm .\AzureCLI.msi.
  3. Verify the installation by running the command Get-installedmodule.

Installing Chocolatey

Reference: Installing Chocolatey

To install Chocolaty, follow these steps:

  • Open the PShell or VS Terminal for PShell.
  • Run the command Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')).

Installing Terraform

To install Terraform using Chocolatey, follow these steps:

  • Quit and restart VS before proceeding.
  • Run the command choco install terraform.

Cloning GitHub Lab for Terraform

Reference: GitHub - terraform-azure-2453108

To clone the GitHub lab for Terraform, follow these steps:

  • Run the command Az login.
  • If the git clone command does not work, install the git packages using the command Choco install git.
  • Run the command git clone https://github.com/LinkedInLearning/terraform-azure-2453108.git.

Terraform Initialization

To prepare the working directory, run the following commands:

  • Terraform initialization
  • Terraform validate
  • Terraform plan
  • Terraform apply (also runs plan at the same time)
  • Terraform destroy

These commands check whether the configuration is valid, shows changes required by the current configuration, deploys the Infrastructure as Code (IAC), and destroys the previously created IAC.

Terraform CLI Workspace

A Terraform CLI workspace is a way to create separate instances of state data. To create a new workspace, run the following commands:

  • Terraform workspace list
  • Terraform workspace new dev
  • Terraform workspace select anotherworkspace (e.g., test)

Terraform State

The Terraform state maps real-world resources to your configuration, keeps track of your metadata, and improves performance for large infrastructures. It is highly discouraged to modify the state file JSON directly. By default, the state file is stored on a local file.

You can also store the state file remotely using Azure Storage, Terraform Cloud, or any other storage. The state file refreshes to update

TF Output Variable

To create a subfolder named "02_02_var," make a copy of the tf.tvars.backup file and rename it as tf.tfvars. After that, update the aws_Access_kays and aws_Sectret_key. Then, change to the subfolder on the terminal.

Initialize Terraform using TF INIT. Check the state using TF show. Plan the infrastructure using TF plan s1.tfplan. Finally, apply the plan using TF apply s1.tfplan.

Add the following code to the main.tf file:

terraform
Output "instance-dns" { value = aws_instance.nodejs1.public_dns } Output "private-dns { value = aws_instance.nodejs1.provate_dns }

Variables' output can be repurposed as input for other automation using Jenkins.

In the Terraform console (TF console (repl)), you can evaluate, print, and loop. It supports basic operator evaluation and ternary operator, such as 5 != 120 ? "foo" : "bar".

Terraform has several functions, including string functions like length("terraform"), upper(), split (",","one","two","three"), and join(",","one","two","three").

Terraform supports various authentication methods, such as Az CLI, Managed Service Identity, Service Principal with Client Secret, and SP with Client Cert.

There are two new variable types to review. The managed_disk_type variable is of type map and stores key-value pairs of disk types. The os variable uses an object type to combine several values of different types. In this example, the os attributes are used to configure the VM image.

terraform
variable "location" { type = string description = "Azure location of Terraform server environment" default = "westus2" } variable "vnet_address_space" { type = list description = "Address space for Virtual Network" default = ["10.0.0.0/16"] } variable "snet_address_space" { type = list description = "Address space for Virtual Network" default = ["10.0.0.0/24"] } variable "servername" { type = string description = "Server name of the virtual machine" } variable "admin_username" { type = string description = "Administrator username for server" } variable "admin_password" { type = string description = "Administrator password for server" } variable "managed_disk_type" { type = map description = "Disk type Premium in Primary location Standard in DR location" default = { westus2 = "Premium_LRS" southcentralus = "Standard_LRS" } } variable "vm_size" { type = string description = "Size of VM" default = "Standard_B1s" } variable "os" ({ description = "OS image to deploy" type = object({ publisher = string offer = string sku = string version = string }) }

The following code can be added to main.tf:

terraform
# Terraform terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "2.40.0" } } } #Azure provider provider "azurerm" { features {} } #Create virtual network resource

Azure Terraform configurations can include conditional logic using the if-else statement. The below code shows an example of a storage account module with variables.tf defining the variables, including saname, rgname, and location. The main.tf file includes the azurerm_storage_account resource block which creates a storage account. In the block, the default location is set to southcentralus.

csharp
Terrafromlab\Modules\storage-account Variables.tf variable "saname" { type = string description = "Name of storage account" } variable "rgname" { type = string description = "Name of resource group" } variable "location" { type = string description = "Azure location of storage account environment" default = "" } Terrafromlab\Modules\storage-account Main.tf # Terraform terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "2.40.0" } } } # Storage Account resource "azurerm_storage_account" "sa" { name = var.saname resource_group_name = var.rgname location = var.location != "" ? var.location : "southcentralus" account_tier = "Standard" account_replication_type = "GRS" } Terrafromlab\main.tf # Terraform terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "2.40.0" } } } # Azure provider provider "azurerm" { features {} } # Create Storage Account module "storage_account" { source = "./modules/storage-account" saname = "sacal539521" rgname = "cal-539-52" } # Create Storage Account module "storage_account2" { source = "./modules/storage-account" saname = "sacal539522" rgname = "cal-539-52" location = "westus" }

Looping in Terraform configurations can be done using dynamic blocks with for_each loops. The code below shows an example of this with the NSG module. The variables.tf file defines the nsg_rule, nsgname, rgname, and location variables. The main.tf file includes the azurerm_network_security_group resource block, which creates a network security group. In this block, a dynamic block is used with a for_each loop iterating through the list of the nsg_rule variable. The nsgname argument includes the count.index variable, which represents the index value of the resource being created.

typescript
TERRAFRMLAB\modules\NSG\varibles.tf variable "nsg_rule" { description = "OS image to deploy" type = list(object({ name = string priority = number direction = string access = string protocol = string source_port_range = string destination_port_range = string source_address_prefix = string destination_address_prefix = string })) } variable "nsgname" { type = string description = "Name of NSG" } variable "rgname" { type = string description = "Name of resource group" } variable "location" { type = string description = "Azure location of NSG environment" default = "westus2" } \terraformlab\modules\nsgmain.tf