Terraform
Terrform info
References: YouTube / Travis Roberts / Getting Started with Terraform
- Use the resources instead of variables to set a dependency on the creation of the resource.
- Terraforms treats all the divided .tf files as the same file.
Locals
- To assign a name to an expression.
- Update the local to modify all instance of the expression.
- Helps with repeating values.
- Overuse can make code difficult to read.
Modules
- Reusable code.
- Collection of resources.
- Accepts inputs, produces outputs.
- Modules are not a single instance of a resource.
- Modules is a collection of resources.
Example: GitHub / ModuleExample
Count vs For_each
Count Use count if the instances of the resources are almost identical. Using the index to identify the different instances.
For_each Multiple versions of similar versions. Uses areguments where the value is mapped to a set of strings. Map is a key value pair.
Example: GitHub / VNet with Azure Bastion
Import vs Data Source
Import
- Imports infraestructure into Terraform management.
- Added to Terraform state and managed by Terraform going forward.
Data Source**
- Allows Terraform to define and use existing infraestructure.
- Not managed by Terraform.
- Data refreshed during Terraform Plan.
Features Block
Dynamic Blocks
Use for reosurce that have repetable nested blocks in their arguments. For example, servers can hhave multiple disks or NICs.
A for_each loop is used to create multiple similar instances of an object such as a resource. A Dynamic Block uses a for_each loop to create multiple copies of a sub-resource nested inside a resource.
Example: GitHub / Dynamic Network Security Group Example
Override
Avoid using. Useful for automation, it changes settings without modifying source files.
Override file allows to override values in a Terraform deployment. It consists of a set of configurations that replace the values in existing .tf files.
After all the .tf files are processed by Terraform, the override files are merged into the configuration. The merge replaces the values supplied by the configuration files.
The name convention is important. The files are processed or merged in lexicographical order (alphabetic order). Override File Names:
- override.tf, override.tf.json
- test_override.tf, test_override.tf.json
Terrform practice
References:
Install Terraform
- Donwload terraform.exe
- Move to "C:\Program Files\Terraform"
- Edit PATH environment variable
terraform --version
Azure login
Azure CLI
az login --use-device-code
az account show
az account set --subscription <subscription_id>
az group list --query "[?name=='mtc-resources']"
az network vnet subnet list -g rg-mock --vnet-name vnet-mock --query "[?name=='subnet-mock']"
az vm image list --all --publisher="Canonical" > images.json
az vm image list --all --publisher="Canonical" --sku="22_04-lts-gen2"
Azure Storage account
The Storage account name has to be unique.
Do not create the Storage Account with Terraform. Consider that the Terraform state file in the Storage Account is not a stateless resource. Meaning it cannot be destroyed and recreat it as needed. There is state date in the Storage Account needed for deployments.
The ACCOUNT_KEY is not needed if the deployment is don trough a Pipeline.
Code
$SUBCRIPTION_NAME=''
$RESOURCE_GROUP_NAME='rg-tfstate'
$STORAGE_ACCOUNT_NAME="tfstate01$(get-random)"
$CONTAINER_NAME='tfstate'
# Set subscription to be the current active subscription.
az account show
az account set --subscription <subscription_id>
# Create resource group
az group create --name $RESOURCE_GROUP_NAME --location eastus
# Create storage account
az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob
# Create blob container
az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME
#Get the storage access key and store it as an environment variable
$ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)
$env:ARM_ACCESS_KEY=$ACCOUNT_KEY
Docs: azurerm
Terraform commands
terraform init
terraform frmt
terraform plan
terraform apply -help
terraform apply
terraform apply -auto-approve
terraform apply -replace azurerm_linux_virtual_machine.mtc-vm
terraform apply -refresh-only
terraform state list
terraform state show azurerm_resource_group.mtc-rg
terraform state show azurerm_public_ip.mtc-nic
terraform output
terraform output public_ip_address
terraform refresh
terraform plan -destroy
terraform apply -destroy
terraform destroy
Terraform code
State file and its backup, do not modify unless is strictly necessary. More info: Terraform / State
In mtc-test-rule.source_address_prefix, should be your public IP to connect to the Azure resources from local.
Access the VM
Create SSH key to access the VM:
SSH into the VM
Custom data
This will delete and create the VM
Install remote SSH VSC extension to access the remote VM
- Install VSC extension "Remote - SSH"
- Open Command Palette (Ctrl+Shift+P)
- Type "Remote-ssh: Add New SSH Host..."
- Type "ssh adminuser@
" - Chose "~/.ssh/config" directory
- Open config file
- Create "windows-ssh-script.tpl" and "linux-ssh-script.tpl"
- Add the "provisioner" attribute in the "azurerm_linux_virtual_machine"
- Redeploy all
terraform apply -replace azurerm_linux_virtual_machine.mtc-vm - Type "Remote-ssh: Connect to Host..." on the Command Palette
- Select the identifier of the remote machine
- Select Linux
- Click "Continue" on the provided fingerprint
- Wait for docker to be installed and check with
docker -version
Data sources
- Add
data "azurerm_public_ip" "mtc-ip-data"in the code - Run
terraform apply -refresh-only - The data will be at the top of the state file
- Check the data with
terraform state list - Check the value of the data with
terraform state show data.azurerm_public_ip.mtc-ip-data
Outputs
- Add
output "public_ip_adrress"in the code - Check value with
terraform state show data.azurerm_public_ip.mtc-ip-data - Run
terraform apply -refresh-only - Run
terraform outputorterraform output public_ip_address
Variables
- Add
${var.host_os}in the templatefile of the VM provisioner - Create
variables.tfwith thehost_osvariable and plan the deployment - Add the attribute
defaultto thevariables.tffile - Run
terraform consoleand typevar.host_os - Comment the
defaultattribute - Create
terraform.tfvars - Run
terraform consoleand typevar.host_os - Run
terraform console -var="host_os=linux"and typevar.host_os - Create
osx.tfvars - Run
terraform console -var-file="osx.tfvars"and typevar.host_os
Conditionals
- Syntax
condition ? true_val : false_val - Add the conditional in the VM provisioner
- Run
terraform apply -auto-approve