Terraform reprezintă un instrument open-source folosit pentru Infrastructure as Code, dezvoltat de HashiCorp, prin care, mai exact, se automatizează procese de infrastructură / devops.
Un use-case principal al Terraform îl reprezintă conectarea la cloud providers, precum Google Cloud Platform (GCP) și Amazon Web Services (AWS), și gestionarea resurselor oferite de către cloud providers.
Folosim site-ul oficial al Terraform pentru a instala tool-ul. Găsiți toate detaliile necesare aici: https://www.terraform.io/downloads
Pentru a instala Terraform pe o mașinp cu un sistem de operare Ubuntu / Debian, folosim următoarele comenzi:
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list sudo apt update && sudo apt install terraform
Pentru a verifica dacă instalarea fost efectuată cu succes, încercăm să obținem versiunea de Terraform instalată: terraform -version
Pentru a putea utiliza funcția de autocomplete cu Terraform: terraform -install-autocomplete
În laboratorul curent o să folosim Terraform împreună cu Docker, cu care suntem deja familiari. Începem prin a crea un director nou pentru configuratia noastră:
mkdir lab4cc cd lab4cc
Creăm un fișier cu numele main.tf și introducem următorul cod:
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 2.13.0"
}
}
}
provider "docker" {}
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.latest
name = "tutorial"
ports {
internal = 80
external = 8000
}
}
Să analizăm pe rând fiecare bloc de cod introdus:
terraform {} - conține setarile de Terraform, inclusiv provider-ul pe care urmează să îl folosim. Pentru fiecare provider, câmpul source definește numele provider-ului. By default, Terraform folosește Terraform Registry pentru a instala un provider. Astfel, în exemplul nostru, kreuzwerker/docker este un provider care se găsește în registrul Terraform la path-ul registry.terraform.io/kreuzwerker/docker. Câmpul version este opțional, dacă nu îl folosim, Terraform o să descarce by default ultima versiune disponibilă.provider {} - un block de tipul provider conține configurările necesare pentru ca acel provider să poată fi folosit. În cazul nostru, am folosit docker. Un provider este doar un plugin pe care Terraform îl folosește pentru a crea și pentru a gestiona resursele.resource “docker_image” “nginx”. În acest exemplu, docker_image este tipul de resursă, iar nginx este numele resursei. Fiecare astfel de bloc are mai multe proprietăți, acestea diferă de la resursă la resursă. Exemplu: în laboratorul viitor o sa configurăm o mașină virtuală într-un provider de cloud unde o să folosim parametrii ca tipul de masină, hard disk, dimensiune hard disk, regiunea în care să fie deployed masina, etc.Recapitulare cod:
terraform cu config-ul unde am specificat providerul docker și versiunea dorită.docker.docker_image cu numele nginx (numele variabilei).docker_container cu numele nginx. În această resursă, pentru imagine am folosit imaginea definită mai sus, iar numele container-ului este dat de câmpul name.Pentru a pune in picioare infrastructura:
terraform init. Urmăriți output-ul comenzii pentru a înțelege ce face această comandă.terraform fmtterraform validateterraform plan. Această comandă este un dry-run, deci putem observa cum o să arate infrastructura noastră după ce o să aplicăm configurarea creată anterior. Atenție, această comandă nu modifică infrastructura.terraform apply
Pentru a observa state-ul: terraform show
Rulați comanda pentru a vedea planul. Modificarea este facută in-place?
Ștergere infrastructură - rulați comanda terraform destroy
Avem următorul fișier outputs.tf, unde avem acest bloc:
output "Lab" {
value="lab4 first output"
}
Am creat primul output în Terraform. Pentru a observa comportamentul, urmați pașii din exercițiul anterior pentru a “aplica” infrastructura.
Avem acest bloc cu următorul cod:
variable "LabCCTerraform" {
description = "primul lab in terraform"
default = "valoare default a primului lab in terraform"
}
Aplicați planul și observați comportamentul.
Un alt mod de a seta variabile în Terraform este prin variabile de mediu. By default, Terraform caută variabilele de mediu care încep cu F_VAR_. De exemplu, o variabilă de mediu cu numele TF_VAR_MYTESTVAR=myvalue o să atribuie valoarea myvalue unei variabile cu numele MYTESTVAR. Variabila cu numele MYTESTVAR trebuie sa fie totuși declarată in configurația noastră de Terraform.
export TF_VAR_LabCCTerraform=“Value from environment”terraform apply pentru a observa comportamentul.
LabCCTerraform=“Value from tfvars file”. Acest fișier, deși are extensia diferită față de cele anterioare foloseste exact aceeași sintaxă.
Un alt mod prin care putem atribui o valoare unei variabile este prin linia de comandă.
Rulați următoarea comandă: terraform apply -var LabCCTerraform=valueFromCommandLine
In urma acestui exercițiu, am aflat ca ordinea de prioritizare a variabilelor este următoarea:
Un alt tip de variabilă pe care îl putem folosi este lista:
variable "mylist" {
default = ["ana", "are", "mere"]
}
Pentru a accesa un element dintr-o listă avem 2 variante.
output "getelement" {
value = element(var.mylist,1)
}
output "useindex" {
value = var.mylist[1]
}
Liste nested:
variable "nestedlist" {
type = list
default = [
["item1", "item2"],
["item3", "item4"]
]
}
Pentru a accesa elementele dintr-o listă nested, folosim sintaxa asemănătoare:
output "nestedlist" {
value = var.nestedlist[1][1]
}
Maps:
variable mymap {
default = {
us = "United States"
eu = "Europe"
apac = "Asia/Pacific"
}
}
output "my_region_map" {
value = var.mymap
}
Pentru a accesa elementele dintr-un map, folosim functia lookup, mai multe detalii gasiți în link-ul: https://developer.hashicorp.com/terraform/language/functions/lookup
output "oneMapElement" {
value = lookup(var.mymap, "us")
}
Având în vedere că deja devine greu de urmărit codul nostru, avem nevoie de o refactorizare.
Best practices Terraform recomandă să avem fișiere separate pentru variabile și outputs. Simplu spus, toate variabilele stau într-un fișier variables.tf, toate output-urile stau într-un fișier outputs.tf.