Terraform od nuly: HCL, poskytovatel a cyklus plán-použij-znič
V roce 2026 dosáhl trh Infrastructure as Code takové vyspělosti, že ignorování Terraformu se rovná psát SQL bez znalosti transakcí: technicky možné, ale profesionálně riskantní. Terraform společnosti HashiCorp dnes drží 32,8% podíl na trhu mezi nástroji IaC, s více než 4 miliony instalací poskytovatelů měsíčně na registry.terraform.io. Tento průvodce vás provede od začátku k pracovnímu nastavení na AWS a Azure, se solidním porozuměním cyklu plán-použij-znič což zabrání nákladným chybám ve výrobě.
Otázka, kterou slýchám nejčastěji od vývojářů, kteří přistupují k IaC, je: "Protože já jen nepoužívám." bash skripty nebo konzole AWS?. Odpověď je v konceptu deklarativní infrastruktura: neřekneš Terraformu jako vytvořit zdroje, říkáte který stát chcete dosáhnout. Terraform se zabývá pochopením sledu operací, řízením závislostí mezi zdroji a zajištěním idempotence.
Co se naučíte
- Nainstalujte Terraform a nakonfigurujte tfenv pro práci s více verzemi
- Syntaxe HCL: bloky, atributy, výrazy a vestavěné funkce
- Nakonfigurujte poskytovatele AWS a poskytovatele Azure pomocí zabezpečeného ověřování
- Kompletní životní cyklus:
terraform init,plan,apply,destroy - Pochopení souboru stavu: co to je, kde žije, proč by nikdy neměl být ručně upravován
- Strukturujte projekt Terraform od začátku škálovatelným způsobem
- Proměnné, místní a výstup: zorganizujte konfiguraci profesionálním způsobem
Předpoklady a instalace
Než napíšeme první řádek HCL, nastavme prostředí profesionálně. Nejčastější začátečnickou chybou je globální instalace Terraformu pomocí správce balíčků a pak zjistíte, že jste uvízli na konkrétní verzi. Správné řešení je tfenv, správce verzí pro Terraform (ekvivalent nvm pro Node.js).
# Installa tfenv (macOS/Linux)
git clone https://github.com/tfutils/tfenv.git ~/.tfenv
echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# Installa l'ultima versione stabile di Terraform
tfenv install latest
tfenv use latest
# Verifica installazione
terraform version
# Output: Terraform v1.9.x on linux_amd64
# Installa una versione specifica se il progetto la richiede
tfenv install 1.8.5
tfenv use 1.8.5
# Lista versioni installate
tfenv list
Pro Windows, doporučený přístup v roce 2026 a WSL2 s Ubuntu nebo Chocolatey:
# Windows con Chocolatey
choco install terraform
# Oppure scarica il binario da releases.hashicorp.com
# e aggiungilo al PATH manualmente
Nainstalujte také plugin VS Code HashiCorp Terraform (id: hashicorp.terraform):
nabízí zvýraznění syntaxe, automatické dokončování, přechod na definici pro poskytovatele a integraci
s terraform fmt. Je to nejrobustnější prostředí IDE dostupné pro HCL.
HCL: HashiCorp konfigurační jazyk
HCL (HashiCorp Configuration Language) je speciálně navržený deklarativní jazyk
pro konfiguraci infrastruktur. Nejedná se o univerzální programovací jazyk:
nemá žádnou imperativní smyčku (použijte for_each e count), nemá žádné výjimky,
Nemá žádné asynchronní I/O. Toto je a funkce, není limit: jednoduchost snižuje
náhodná složitost konfigurací.
Základní soubor každého projektu Terraform e main.tf. Společná konvence
a rozdělte konfiguraci do těchto souborů:
progetto-terraform/
├── main.tf # Risorse principali
├── variables.tf # Dichiarazione variabili
├── outputs.tf # Output values
├── versions.tf # Required providers e terraform block
├── locals.tf # Valori locali computati
└── terraform.tfvars # Valori delle variabili (non committare se contiene segreti)
Zde je základní struktura HCL se základními typy bloků:
# versions.tf — blocco terraform: configura il comportamento del core
terraform {
required_version = ">= 1.8.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.100"
}
}
}
# variables.tf — dichiarazione variabili di input
variable "environment" {
description = "Nome dell'ambiente (dev, staging, prod)"
type = string
default = "dev"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "L'ambiente deve essere dev, staging o prod."
}
}
variable "aws_region" {
description = "AWS Region dove deployare le risorse"
type = string
default = "eu-west-1"
}
variable "instance_count" {
description = "Numero di istanze EC2 da creare"
type = number
default = 2
}
variable "tags" {
description = "Tag comuni da applicare a tutte le risorse"
type = map(string)
default = {
ManagedBy = "Terraform"
Project = "demo"
}
}
# locals.tf — valori computati a partire da variabili
locals {
# Naming convention uniforme
name_prefix = "${var.environment}-${var.tags["Project"]}"
# Merge tag comuni con tag specifici per risorsa
common_tags = merge(var.tags, {
Environment = var.environment
CreatedAt = timestamp()
})
}
Nakonfigurujte poskytovatele AWS
I poskytovatel jsou pluginy, které Terraformu umožňují interakci s externími API: AWS, Azure, GCP, Kubernetes, GitHub, Datadog – prakticky každá služba má poskytovatele Terraform. Poskytovatel AWS je nejvyspělejší s více než 1200 podporovanými typy zdrojů.
Pro ověření AWS, nikdy nepoužívejte pevně zakódovaný přístupový klíč v kódu HCL. Poskytovatel AWS podporuje následující režimy v pořadí podle priority:
# main.tf — configurazione provider AWS
provider "aws" {
region = var.aws_region
# NON fare questo in produzione:
# access_key = "AKIA..." # MAI
# secret_key = "..." # MAI
# Metodo consigliato 1: assume role (best practice per CI/CD)
# assume_role {
# role_arn = "arn:aws:iam::123456789:role/TerraformRole"
# }
# I tag di default vengono applicati a tutte le risorse
default_tags {
tags = local.common_tags
}
}
# Configurazione autenticazione (fuori da main.tf)
# La best practice e usare il file ~/.aws/credentials oppure
# variabili di ambiente:
# export AWS_ACCESS_KEY_ID="..."
# export AWS_SECRET_ACCESS_KEY="..."
# export AWS_DEFAULT_REGION="eu-west-1"
#
# In produzione: IAM Instance Profile o OIDC con GitHub Actions
Nyní vytvoříme první prostředky AWS: VPC s veřejnými a soukromými podsítěmi:
# main.tf — prime risorse AWS
# Data source: recupera gli AZ disponibili nella region
data "aws_availability_zones" "available" {
state = "available"
}
# VPC principale
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${local.name_prefix}-vpc"
}
}
# Subnet pubblica (una per AZ)
resource "aws_subnet" "public" {
count = min(length(data.aws_availability_zones.available.names), 2)
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${local.name_prefix}-public-${count.index + 1}"
Tier = "Public"
}
}
# Subnet privata
resource "aws_subnet" "private" {
count = min(length(data.aws_availability_zones.available.names), 2)
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index + 10)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "${local.name_prefix}-private-${count.index + 1}"
Tier = "Private"
}
}
# Internet Gateway per le subnet pubbliche
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.name_prefix}-igw"
}
}
# Route table pubblica
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "${local.name_prefix}-rt-public"
}
}
# Associazione route table - subnet pubblica
resource "aws_route_table_association" "public" {
count = length(aws_subnet.public)
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
# outputs.tf — valori di output
output "vpc_id" {
description = "ID della VPC creata"
value = aws_vpc.main.id
}
output "public_subnet_ids" {
description = "IDs delle subnet pubbliche"
value = aws_subnet.public[*].id
}
output "private_subnet_ids" {
description = "IDs delle subnet private"
value = aws_subnet.private[*].id
}
Cyklus plán-použij-znič
Životní cyklus Terraformu se skládá ze čtyř základních příkazů. Důkladně jim porozumět Je nezbytné vyhnout se nejčastějším nehodám ve výrobě.
terraform init
# Inizializza il working directory:
# - Scarica i provider (plugin binaries)
# - Configura il backend per lo state
# - Installa i moduli referenziati
terraform init
# Output atteso:
# Initializing the backend...
# Initializing provider plugins...
# - Finding hashicorp/aws versions matching "~> 5.0"...
# - Installing hashicorp/aws v5.54.1...
# Terraform has been successfully initialized!
# Upgrade dei provider all'ultima versione compatibile
terraform init -upgrade
# Ricrea il .terraform.lock.hcl (file di lock dei provider)
terraform providers lock -platform=linux_amd64 -platform=darwin_amd64
Soubor .terraform.lock.hcl
Soubor .terraform.lock.hcl musí být odevzdán do úložiště.
Zajišťuje, že všichni členové týmu a kanál CI používají přesně stejný
verzi poskytovatelů, čímž se vyhnete tomu, že infrastruktura „funguje na mém počítači“.
Adresář .terraform/ místo toho jde do .gitignore.
terraformní plán
# Genera il piano di esecuzione (DRY RUN)
terraform plan
# Salva il piano in un file binario (consigliato per CI/CD)
terraform plan -out=tfplan
# Specifica le variabili inline
terraform plan -var="environment=staging" -var="instance_count=3"
# Usa un file di variabili
terraform plan -var-file="staging.tfvars"
# Output tipico di plan:
# Terraform will perform the following actions:
#
# # aws_vpc.main will be created
# + resource "aws_vpc" "main" {
# + arn = (known after apply)
# + cidr_block = "10.0.0.0/16"
# + enable_dns_hostnames = true
# ...
# }
#
# Plan: 8 to add, 0 to change, 0 to destroy.
Symbol + označuje stvoření, ~ úpravy na místě,
-/+ zničit a znovu vytvořit (vynutit si odstávku), - zničení.
Vždy si pozorně přečtěte označené bloky -/+:
znamenají, že zdroj musí být znovu vytvořen, což často způsobuje prostoje nebo ztrátu dat.
platí terraform
# Applica le modifiche (chiede conferma interattiva)
terraform apply
# Applica il piano salvato (NON chiede conferma - usare in CI/CD)
terraform apply tfplan
# Auto-approve per ambienti non critici (attento in prod!)
terraform apply -auto-approve
# Apply con variabili
terraform apply -var="environment=prod" -var-file="prod.tfvars"
# Output dopo apply:
# Apply complete! Resources: 8 added, 0 changed, 0 destroyed.
#
# Outputs:
# vpc_id = "vpc-0123456789abcdef0"
# public_subnet_ids = [
# "subnet-0abc123def456gh78",
# "subnet-0def456abc789ij01",
# ]
terraform zničit
# Distrugge TUTTE le risorse gestite dallo state corrente
terraform destroy
# Destroy con auto-approve (ATTENZIONE: irreversibile)
terraform destroy -auto-approve
# Distrugge solo una risorsa specifica (con grande cautela)
terraform destroy -target=aws_subnet.public[0]
# In produzione, preferisci eliminare le risorse dal codice
# e fare terraform apply: Terraform le distruggerà correttamente
Anti-Pattern: terraform zničit ve výrobě
Nikdy neutíkej terraform destroy bez ozdravného plánu.
Nejlepším postupem je odebrat prostředek z kódu HCL a spustit jej terraform apply:
získáte stejný výsledek, ale s jasným plánem, který si můžete nejprve prohlédnout.
Některé organizace blokují možnost provést zničení na úrovni zásad IAM
na produkční prostředí.
Nakonfigurujte poskytovatele Azure
poskytovatel azurerm spravuje prostředky Azure. Na rozdíl od AWS, Azure k ověřování používá objekt Service Principal nebo Managed Identity.
# versions.tf aggiornato con provider Azure
terraform {
required_version = ">= 1.8.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.100"
}
}
}
# Configurazione provider Azure
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = true
}
key_vault {
purge_soft_delete_on_destroy = false
recover_soft_deleted_key_vaults = true
}
}
# Autenticazione via variabili d'ambiente (consigliato)
# ARM_CLIENT_ID, ARM_CLIENT_SECRET, ARM_TENANT_ID, ARM_SUBSCRIPTION_ID
# oppure Azure CLI: az login
}
# Risorse Azure di base
resource "azurerm_resource_group" "main" {
name = "${local.name_prefix}-rg"
location = "West Europe"
tags = local.common_tags
}
resource "azurerm_virtual_network" "main" {
name = "${local.name_prefix}-vnet"
address_space = ["10.1.0.0/16"]
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
tags = local.common_tags
}
resource "azurerm_subnet" "public" {
name = "public-subnet"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.1.1.0/24"]
}
resource "azurerm_subnet" "private" {
name = "private-subnet"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.1.2.0/24"]
}
Proměnné, místní a datové zdroje
Dobré využití proměnných, místních obyvatel a zdrojů dat odlišuje konfiguraci Terraform profesionál z ad hoc skriptu. Zde jsou základní vzory:
# Tipi di variabili in HCL
# Stringa semplice
variable "app_name" {
type = string
default = "myapp"
}
# Numero con validazione
variable "min_instances" {
type = number
default = 1
validation {
condition = var.min_instances >= 1 && var.min_instances <= 10
error_message = "Il numero di istanze deve essere tra 1 e 10."
}
}
# Lista di stringhe
variable "allowed_cidr_blocks" {
type = list(string)
default = ["10.0.0.0/8"]
}
# Map di stringhe
variable "database_config" {
type = map(string)
default = {
engine = "postgres"
version = "15.4"
size = "db.t3.medium"
}
}
# Oggetto con schema tipizzato
variable "network_config" {
type = object({
vpc_cidr = string
subnet_count = number
enable_nat = bool
})
default = {
vpc_cidr = "10.0.0.0/16"
subnet_count = 2
enable_nat = false
}
}
# Locals: valori computati (non input dall'utente)
locals {
# Concatenazioni
full_name = "${var.environment}-${var.app_name}"
# Condizionale ternario
instance_type = var.environment == "prod" ? "t3.medium" : "t3.micro"
# Ciclo su lista (for expression)
subnet_cidrs = [
for i in range(var.network_config.subnet_count) :
cidrsubnet(var.network_config.vpc_cidr, 8, i)
]
# Map transformation
tag_map = {
for k, v in var.database_config :
"db_${k}" => v
}
}
# Data sources: recuperano informazioni da risorse esistenti
# non gestite da questo state
# AMI Amazon Linux 2023 piu recente
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
# Account ID corrente (utile per ARN)
data "aws_caller_identity" "current" {}
# Uso nei resource:
# ami = data.aws_ami.amazon_linux.id
# account_id = data.aws_caller_identity.current.account_id
Státní spis: Srdce Terraformu
Soubor terraform.tfstate je Terraformův „zdroj pravdy“: zmapujte každé aktivum
definované v HCL svému reálnému protějšku v cloudu. Pochopení toho, jak to funguje, je zásadní
vyhnout se nejvážnějším problémům.
// Struttura semplificata di terraform.tfstate
{
"version": 4,
"terraform_version": "1.9.0",
"serial": 42,
"lineage": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"outputs": {
"vpc_id": {
"value": "vpc-0123456789abcdef0",
"type": "string"
}
},
"resources": [
{
"mode": "managed",
"type": "aws_vpc",
"name": "main",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"id": "vpc-0123456789abcdef0",
"cidr_block": "10.0.0.0/16",
"enable_dns_hostnames": true,
...
}
}
]
}
]
}
Zlatá pravidla pro státní spis
- Nikdy neupravujte
terraform.tfstateručně - Nikdy se nezavazujte uveďte jej ve svém úložišti Git (přidejte jej do
.gitignore) - V týmech použijte vždy vzdálený backend se zamykáním (viz článek 03 série)
- Stát to může obsáhnout tajemství venku (heslo RDS, přihlašovací údaje): S tím zacházejte jako s citlivými údaji
- Před rizikovými operacemi, provést ruční zálohování:
terraform state pull > backup.tfstate
Příkazy státní inspekce
# Lista tutte le risorse gestite dallo state
terraform state list
# Mostra i dettagli di una risorsa specifica
terraform state show aws_vpc.main
# Rinomina una risorsa nello state (senza toccare l'infrastruttura)
terraform state mv aws_subnet.public aws_subnet.public_new
# Rimuove una risorsa dallo state (Terraform non la gestirà piu)
# La risorsa rimane nel cloud ma non è piu "owned" da Terraform
terraform state rm aws_subnet.private[0]
# Importa una risorsa esistente nello state
# (vedi articolo 03 per dettagli)
terraform import aws_vpc.main vpc-0123456789abcdef0
# Mostra l'output senza fare apply
terraform output vpc_id
terraform output -json # tutti gli output in formato JSON
Doporučená struktura projektu
U skutečných projektů se struktura jednoho adresáře rychle stane neovladatelnou. Zde jsou dva běžné vzory pro organizaci infrastruktury Terraform ve výrobě:
# Pattern 1: Organizzazione per ambiente
infra/
├── modules/ # Moduli riusabili
│ ├── networking/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── compute/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── environments/
│ ├── dev/
│ │ ├── main.tf # Usa i moduli
│ │ ├── variables.tf
│ │ ├── terraform.tfvars # Valori specifici per dev
│ │ └── versions.tf
│ ├── staging/
│ │ └── ...
│ └── prod/
│ └── ...
└── .gitignore # Esclude .terraform/, *.tfstate
# Pattern 2: Terragrunt (wrapper per DRY)
infra/
├── terragrunt.hcl # Config globale
├── modules/
│ └── networking/
├── live/
│ ├── dev/
│ │ └── networking/
│ │ └── terragrunt.hcl
│ └── prod/
│ └── networking/
│ └── terragrunt.hcl
Nejlepší postupy pro začátek
Poté, co jste viděli teorii, zde jsou základní pravidla, která odlišují ty, kteří používají Terraform správně těmi, kdo vytvářejí technický dluh od prvního dne:
# 1. Formatta sempre prima di committare
terraform fmt -recursive
# 2. Valida la sintassi
terraform validate
# 3. Usa tflint per linting avanzato (trova deprecazioni, pattern errati)
tflint --init
tflint
# 4. Esegui checkov per security scanning
pip install checkov
checkov -d .
# 5. Pre-commit hooks per automatizzare tutto
# .pre-commit-config.yaml
# repos:
# - repo: https://github.com/antonbabenko/pre-commit-terraform
# hooks:
# - id: terraform_fmt
# - id: terraform_validate
# - id: terraform_tflint
# - id: terraform_checkov
.gitignore pro Terraform
# .gitignore per progetti Terraform
.terraform/
*.tfstate
*.tfstate.backup
*.tfstate.*.backup
.terraform.tfstate.lock.info
*.tfvars # Se contengono segreti (crea terraform.tfvars.example)
override.tf
override.tf.json
*_override.tf
*_override.tf.json
crash.log
.terraformrc
terraform.rc
Úplný příklad: Webová aplikace na AWS
Pojďme si to všechno dát dohromady na reálném příkladu: instance EC2 se skupinou zabezpečení, load balancer a databáze RDS, správně strukturované.
# main.tf — infrastruttura web app completa
# Security Group per le istanze web
resource "aws_security_group" "web" {
name = "${local.name_prefix}-sg-web"
description = "Security group per istanze web"
vpc_id = aws_vpc.main.id
ingress {
description = "HTTP dal load balancer"
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = { Name = "${local.name_prefix}-sg-web" }
}
# Security Group per ALB
resource "aws_security_group" "alb" {
name = "${local.name_prefix}-sg-alb"
description = "Security group per Application Load Balancer"
vpc_id = aws_vpc.main.id
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Launch Template per le istanze EC2
resource "aws_launch_template" "web" {
name_prefix = "${local.name_prefix}-lt-"
image_id = data.aws_ami.amazon_linux.id
instance_type = local.instance_type
network_interfaces {
associate_public_ip_address = false
security_groups = [aws_security_group.web.id]
}
user_data = base64encode(<<-EOF
#!/bin/bash
dnf update -y
dnf install -y nginx
systemctl enable nginx
systemctl start nginx
echo "Deploy Terraform - ${var.environment}
" > /usr/share/nginx/html/index.html
EOF
)
tag_specifications {
resource_type = "instance"
tags = merge(local.common_tags, {
Name = "${local.name_prefix}-web"
})
}
}
# Auto Scaling Group
resource "aws_autoscaling_group" "web" {
name = "${local.name_prefix}-asg"
vpc_zone_identifier = aws_subnet.private[*].id
target_group_arns = [aws_lb_target_group.web.arn]
health_check_type = "ELB"
min_size = var.environment == "prod" ? 2 : 1
max_size = var.environment == "prod" ? 6 : 2
desired_capacity = var.environment == "prod" ? 2 : 1
launch_template {
id = aws_launch_template.web.id
version = "$Latest"
}
tag {
key = "Name"
value = "${local.name_prefix}-web"
propagate_at_launch = true
}
}
# Application Load Balancer
resource "aws_lb" "main" {
name = "${local.name_prefix}-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = aws_subnet.public[*].id
enable_deletion_protection = var.environment == "prod"
tags = local.common_tags
}
resource "aws_lb_target_group" "web" {
name = "${local.name_prefix}-tg-web"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
health_check {
enabled = true
healthy_threshold = 2
unhealthy_threshold = 3
timeout = 5
interval = 30
path = "/health"
}
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.web.arn
}
}
Závěry a další kroky
Nyní máte pevný základ pro profesionální práci s Terraformem: znáte syntaxi HCL, víte, jak konfigurovat poskytovatele AWS a Azure, rozumíte cyklu Plan-Apply-Destroy a pravidlům nezbytné pro bezpečnou správu státního souboru.
Dalším přirozeným krokem ve vašem růstu s Terraformem je naučit se organizovat svůj kód v opakovaně použitelné moduly: Jakmile vaše infrastruktura překročí 200-300 linek HCL se modularizace stává nezbytnou pro udržovatelnost.
Kompletní série: Terraform a IaC
- článek 01 (tento) — Terraform from Scratch: HCL, Provider a Plan-Apply-Destroy
- článek 02 — Návrh opakovaně použitelných modulů Terraform: struktura, I/O a registr
- článek 03 — Terraform State: Vzdálený backend s S3/GCS, zamykání a import
- Článek 04 — Terraform v CI/CD: GitHub Actions, Atlantis a Pull Request Workflow
- Článek 05 – Testování IaC: Terratest, Terraform Native Test a Smluvní testování
- Článek 06 – Zabezpečení IaC: Checkov, Trivy a OPA Policy-as-Code
- Článek 07 – Terraform Multi-Cloud: AWS + Azure + GCP se sdílenými moduly
- Článek 08 — GitOps pro Terraform: Flux TF Controller, Spacelift and Drift Detection
- Článek 09 — Terraform vs Pulumi vs OpenTofu: Konečné srovnání 2026
- Článek 10 — Terraform Enterprise Patterns: Workspace, Sentinel a Team Scaling
Oficiální zdroje
- Oficiální dokumentace Terraform
- Registr Terraform — poskytovatelé, moduly a zásady
- HashiCorp Learn — Interaktivní výukové programy







