Lekcja 2 · Dzień 3
Terraform, jak u dorosłych
Nie „umiem terraform apply”. Oni chcą: moduły, versioning, kontrakt interfejsu, remote state, lock, drift, migracja state, czytanie planu, orchestrację przez Spacelift.
Moduły, wersjonowanie, kontrakt
Moduł, z którego korzysta 20 zespołów, to produkt. Ma:
- Wejście wąskie.
name,cpu,memory,image,port,healthcheck,env(map),irsa_policies. Nie: surowytask_definition_jsoni „dopisz sobie”. - Wyjście stabilne.
service_arn,security_group_id,log_group,task_role_arn. To kontrakt. Łamiesz go major wersją. - Wersjonowanie semver w registry (Spacelift module registry albo prywatne Git tags). Pin w callerze:
version = "~> 3.2", niemain. - Defaulty bezpieczne: private subnet, nie-public SG, encryption on, deletion protection on w prod, required tags (
owner,pci,env). - Zmienne, których nie ma:
open_ssh,skip_logging. Jeśli product potrzebuje wyjątku — osobny feature flag z expiry, nie parametr „wyłącz security”.
Jedna implementacja pod ECS i EKS? Dwa moduły z tym samym interfejsem (service) albo jeden z runtime = ecs|eks na czas migracji. Drugie jest wygodniejsze dla 20 callerów, pierwsze czystsze. Na rozmowie powiedz trade-off i że przez migrację trzymasz fasadę.
Remote state, lock, drift
- Backend: S3 + DynamoDB lock, albo state zarządzany przez Spacelift. State zawiera sekrety (hasła RDS w plaintext w pliku stanu, jeśli tak zasoby wracają). Szyfrowanie KMS, bucket policy: tylko rola Spacelift/CI, public access block, versioning.
- Lock: bez locka dwa apply w tym samym czasie = uszkodzony state. Spacelift serializuje per stack; to jedna z rzeczy, za które płacisz.
- Drift: rzeczywistość ≠ state. Ktoś kliknął w konsoli, autoscaling zmienił desired count, AWS zmienił default. Wykrywanie:
terraform planna schedule. Spacelift drift detection działa na private workers (dokumentacja Spacelift). Atlantis drift natywnie nie ma. HCP Terraform ma health assessments.
Migracja state
Rozbijanie monolitu, przenoszenie zasobu między modułami, zmiana nazwy. Narzędzia:
moved { from = ... to = ... }w kodzie — najlepsze, recenzowalne w PR, Terraform 1.1+.terraform state mv— chirurgia ręczna, gdymovednie wystarcza. Rób na kopii state, w oknie, z lockiem.removed/terraform state rm— zasób zostaje w AWS, znika ze state. Potem import w nowym stacku.terraform import— odwrotnie: AWS istnieje, state nie.terraform state pull/push— ostatnia deska, łatwo zniszczyć. Backup versioned S3 najpierw.
Plan po migracji musi pokazać 0 to destroy, 0 to replace dla tych zasobów. Jeśli widzisz replace na RDS albo na KMS — stop.
Czytanie planu
JD: „You're comfortable reading a plan output.” Kolory, które mają Cię obudzić:
| W planie | Co robisz |
|---|---|
create | OK, jeśli się spodziewasz. Sprawdź nazwę i konto. |
update in-place | Zwykle OK. Uważaj na SG ingress, IAM policy (może chwilowo otworzyć), parameter group RDS. |
replace (force new) | Czytaj forces replacement. Replace ALB = DNS blip. Replace RDS = dane. Replace KMS = wszystko, co tym kluczem zaszyfowane, staje się problemem. |
destroy | Wymaga uzasadnienia w PR. W Spacelift: policy „destroy w prod wymaga approval + 2 reviewers”. |
zmiana w aws_iam_role_policy na * | Blokuj policy-as-code, nie okiem. |
Spacelift / Atlantis / Terraform Cloud
JD wymaga Spacelift albo analoga. Rzetelne różnice (dokumentacja vendorów, nie marketingowe hasła):
| Spacelift | Atlantis | HCP Terraform | |
|---|---|---|---|
| Model | SaaS + opcjonalnie private workers w Twoim VPC | Self-host, GitOps komentarze w PR | SaaS HashiCorp, workspaces |
| Policy | OPA/Rego na wielu decision points (login, plan, apply…) | Conftest/OPA doklejane | Sentinel + OPA policy sets |
| Drift | Natywny, private workers, opcjonalne reconcile | Nie natywnie | Health assessments (wyższe plany) |
| Concurrency | Stack lock, kolejka | Jedna maszyna łatwo się zapycha | Per workspace |
| PCI | Private workers w PCI VPC, state nie wychodzi na public runner | Sam hostujesz — pełna kontrola, pełna operacja | Agents; pytanie o data residency |
Jeśli nie robiłeś Spacelift: „Robiłem X. Tu bym zaczął: jeden stack = jedno konto + jeden komponent, policy na destroy i na brak tagu pci, private workers dla PCI i prod, apply z merge PR po zielonym planie.”
Historia, którą masz mieć
Twoja: migracja Auth0 Terraform (DEVOPS-4975) — pełny STAR na Doświadczenie. Raport chciał: zepsuty state / drift w shared module. To jest 1:1.
Szkielet, gdybyś musiał opowiedzieć inną:
- Objaw: plan pokazuje replace SG / ubytek z locka /
state is lockedpo zabitym runnerze. - Twój call: stop apply na wszystkich callerach, kopia state,
state pull, diff. - Naprawa:
movedalbo import, nie ręczne edytowanie JSON „bo wiem”. - Guardrail: drift schedule, policy blokująca untagged replace, lock timeout + alerting, wersjonowanie modułu, changelog.
Ćwiczenie
Na kartce narysuj interfejs modułu service (input/output) dla ECS i EKS. Dopisz trzy policy Spacelift, które byś włączył pierwszego dnia. Opowiedz swoją state-horror-story w 90 sekund.