Před rokem jsme infrastrukturu stavěli ručně. Klikání v AWS konzoli, poznámky v Confluence, a modlení, aby nikdo nesmazal ten security group. Dnes máme vše v Terraformu — verzované, reviewované, automaticky nasazované. Tady je náš příběh.
Problém: snowflake servery¶
Každý server byl unikát. Vývojové prostředí se lišilo od stagingu, staging od produkce. Nikdo přesně nevěděl, jaká konfigurace na kterém serveru běží. Dokumentace byla zastaralá den po napsání. Když spadl server, obnova trvala hodiny — protože nikdo si nepamatoval všechny kroky.
Tohle je klasický anti-pattern známý jako „snowflake server.” Každý je speciální, každý je jiný, a žádný nejde jednoduše reprodukovat. V době, kdy spravujete tři servery, to ještě jde. Při třiceti je to noční můra. Při třech stech je to nemožné.
Proč Terraform a ne CloudFormation nebo Ansible¶
CloudFormation je AWS-only. My provozujeme infrastrukturu na AWS i v on-premise prostředí (VMware). Potřebovali jsme nástroj, který zvládne obojí. Terraform má providery pro AWS, Azure, GCP, VMware, Consul, a desítky dalších služeb.
Ansible je konfigurační management, ne provisioning nástroj. Skvělý na konfiguraci existujících serverů, ale pro vytváření infrastruktury (VPC, subnety, load balancery, RDS instance) je Terraform lepší volba. V praxi používáme oba — Terraform vytvoří infrastrukturu, Ansible ji nakonfiguruje.
Terraform používá deklarativní přístup: popíšete, jak má infrastruktura vypadat, a Terraform zjistí, co je potřeba změnit. Oproti imperativnímu přístupu (udělej krok 1, pak krok 2, pak krok 3) je to fundamentálně jednodušší na údržbu.
Struktura projektu¶
Po několika iteracích jsme se ustálili na následující struktuře:
infrastructure/
├── modules/
│ ├── vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── ecs-cluster/
│ ├── rds/
│ └── monitoring/
├── environments/
│ ├── dev/
│ │ ├── main.tf
│ │ ├── terraform.tfvars
│ │ └── backend.tf
│ ├── staging/
│ └── production/
└── README.md
Modules definují znovupoužitelné komponenty. VPC modul vytvoří síťovou topologii, ECS modul nakonfiguruje kontejnerový cluster, RDS modul databázi. Každý modul má jasně definované vstupy (variables) a výstupy (outputs).
Environments jsou konkrétní nasazení modulů s různými parametry. Dev má menší instance, staging kopíruje produkci v menším měřítku, produkce má multi-AZ setup a vyšší redundanci.
State management — klíčový koncept¶
Terraform si ukládá stav infrastruktury v souboru terraform.tfstate. Tento soubor je kriticky důležitý — ztratíte ho a Terraform neví, co spravuje. Proto nikdy neukládejte state lokálně.
# backend.tf
terraform {
backend "s3" {
bucket = "core-terraform-state"
key = "production/terraform.tfstate"
region = "eu-central-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
S3 backend s DynamoDB locking zajistí, že dva lidé nemohou současně měnit infrastrukturu. Encryption at rest pro state file, protože obsahuje citlivé informace (RDS hesla, API klíče). Verzování S3 bucketu jako pojistka proti nechtěnému přepsání.
Code review pro infrastrukturu¶
Tady se Infrastructure as Code skutečně vyplatí. Každá změna infrastruktury prochází pull requestem. Před merge spustíme terraform plan a výstup přiložíme k PR. Reviewer vidí přesně, co se změní:
$ terraform plan
~ aws_instance.api_server
instance_type: "t2.medium" => "t2.large"
+ aws_cloudwatch_metric_alarm.cpu_high
alarm_name: "api-cpu-high"
comparison_operator: "GreaterThanThreshold"
threshold: "80"
Plan: 1 to add, 1 to change, 0 to destroy.
Žádné překvapení. Žádné „kdo změnil ten security group v pátek večer.” Vše je trackovatelné v git historii — kdo, kdy, proč. Pro audit a compliance je to zlato.
Moduly — DRY princip pro infrastrukturu¶
Náš VPC modul používáme napříč všemi projekty. Definuje standardní síťovou topologii: veřejné a privátní subnety ve třech availability zones, NAT gateway, route tables, flow logs. Parametrizovaný CIDR block a tagging.
# environments/production/main.tf
module "vpc" {
source = "../../modules/vpc"
environment = "production"
cidr_block = "10.0.0.0/16"
azs = ["eu-central-1a", "eu-central-1b", "eu-central-1c"]
tags = {
Project = "client-x"
ManagedBy = "terraform"
}
}
Když najdeme bug nebo vylepšení v modulu, opravíme ho jednou a propagujeme do všech prostředí. Verzujeme moduly pomocí git tagů — produkce používá ověřenou verzi, dev může testovat nejnovější.
Úskalí a poučení¶
Drift detection. Někdo změní něco ručně v konzoli — a Terraform o tom neví. Při dalším terraform apply to přepíše. Řešení: pravidelný terraform plan v CI pipeline, který detekuje drift a upozorní tým.
Destruktivní změny. Některé změny v Terraformu vyžadují destroy + recreate. Změna AMI u EC2 instance znamená nový server. Změna engine_version u RDS může znamenat downtime. Vždy čtěte plan pozorně — červené řádky s mínusem jsou varovný signál.
Secrets management. Nikdy nevkládejte hesla do .tf souborů. Používáme AWS Secrets Manager a reference přes data source. Alternativně Vault od HashiCorpu — ale to je téma na samostatný článek.
Import existující infrastruktury. terraform import existuje, ale není bezbolestný. Pro každý resource musíte ručně napsat konfiguraci a pak ji importovat. U větší infrastruktury to jsou týdny práce. Poučení: začněte s Terraformem co nejdříve.
IaC není volba, je nutnost¶
Infrastructure as Code není jen módní slovo. Je to fundamentální změna v tom, jak přistupujeme k infrastruktuře — od ruční řemeslné práce k inženýrskému procesu. Terraform nám dal reprodukovatelnost, auditovatelnost a rychlost. Dnes vytvoříme kompletní produkční prostředí za 20 minut jedním příkazem. Před rokem to trvalo dva dny a tři lidi.