Wzorce infrastruktury jako kod
Wzorce infrastruktury jako kod dla agentów AI to cztery receptury (podział monolitu Terraform, bramka na planie, przejęcie dryfu, utwardzenie CloudFormation lub Pulumi) wykonywane przez Claude Code, Codex albo Cursor z poświadczeniami chmurowymi tylko do planu. Maszynowo sprawdzana bramka planu, a nie człowiek czytający HCL, blokuje każde usunięcie lub zastąpienie do zgody wskazanego właściciela.
Ta strona jest dla programistów, którzy odpowiadają za infrastrukturę swojej usługi, i dla liderów technicznych, którzy decydują, czego agent może dotknąć na koncie chmurowym. Dziedziczysz repozytorium Terraform z jednym 900-liniowym main.tf, zaszytymi na sztywno blokami CIDR, providerem przypiętym dwie wersje główne wstecz i terraform plan, który chce zastąpić produkcyjną instancję RDS. Agent podzieli ten plik w kilka minut. Pytanie brzmi: skąd wiesz, że podział niczego nie niszczy, skoro plan ma 400 linii i nikt nie chce go czytać?
Co dają ci te receptury infrastrukturalne
Dział zatytułowany „Co dają ci te receptury infrastrukturalne”- Konfigurację uprawnień, w której agent może uruchomić
terraform plan, ale nie ma poświadczeń, którymi dałoby się zrobić apply - Krótki
plan-gate.sh, który kończy się błędem przy każdym usunięciu lub zastąpieniu, więc przegląd zaczyna się od krótkiej listy, a nie od całego planu - Prompty do skopiowania: podział na moduły z blokami
moved, przegląd planu, przejęcie dryfu blokamiimporti utwardzenie szablonu CloudFormation - Tabelę bramek (format, lint, polityki, testy, plan), które dowodzą poprawności zmiany bez czytania każdej linii
- Kroki naprawcze dla blokady stanu, która nie chce się zwolnić, dryfu, przypadkowych zastąpień, podbicia wersji głównej providera i utkniętego wycofania CloudFormation
Ogranicz agenta przed pierwszym promptem
Dział zatytułowany „Ogranicz agenta przed pierwszym promptem”Zabezpieczeniem, które naprawdę trzyma, jest poświadczenie, nie prompt. Agent, który ma tylko rolę do planu, nie zrobi apply, cokolwiek postanowi uruchomić. Skonfiguruj to raz na repozytorium, w tej kolejności.
-
Utwórz tożsamość tylko do planu. W AWS dołącz
ReadOnlyAccessoraz dostęp do bucketu ze stanem: odczyt klucza stanu tego stosu is3:PutObject/s3:DeleteObjectwyłącznie na kluczu*.tflock. To wystarcza doterraform planz natywnym blokowaniem w S3.ReadOnlyAccessdaje teżs3:GetObjectna każdym buckecie w koncie, łącznie z plikami stanu innych stosów, więc dodaj jawnyDenynas3:GetObjectdla każdego klucza stanu, który nie należy do tego stosu. Apply działa w CI na innej roli, której agent nigdy nie widzi. Ten sam podział działa w Azure (Reader plus konto magazynu ze stanem) i w Google Cloud (Viewer plus bucket ze stanem). Tożsamości tylko do odczytu dla każdej chmury opisuje strona serwery MCP dla chmur. -
Zablokuj destrukcyjne polecenia w narzędziu. To tylko siatka na pomyłki, nie zamiennik poświadczenia.
W
.claude/settings.json(w repozytorium, więc dostaje go cały zespół):{"permissions": {"allow": ["Bash(terraform fmt *)", "Bash(terraform validate *)","Bash(terraform plan *)", "Bash(terraform show *)", "Bash(tflint *)"],"ask": ["Bash(terraform state *)", "Bash(terraform import *)"],"deny": ["Bash(terraform apply *)", "Bash(terraform destroy *)","Bash(terraform force-unlock *)", "Bash(terraform state rm *)"]}}Reguły deny są sprawdzane przed ask i allow. Dopasowują tekst polecenia, więc
sh -c 'terraform apply'to inna pisownia: dlaczego prawdziwą granicą są piaskownica i poświadczenie, wyjaśnia strona uprawnienia i piaskownica.Okno terminala # Terminal, katalog główny repozytorium: zgody na żądanie, zapis tylko w workspacecodex -a on-request -c default_permissions=":workspace"Profile uprawnień są w Codex 0.157.1 w wersji beta i to je OpenAI preferuje zamiast
--sandbox; nie łącz obu mechanizmów. Codex przekazuje poleceniom zmienne środowiskowe, których nazwy zawierająKEY,SECRETlubTOKEN, chyba żeshell_environment_policystanowi inaczej, więc uruchamiaj Codex z powłoki, w której jest wyłącznie rola do planu.Trzymaj agenta Cursora w trybie uruchamiania, który pyta przed poleceniami terminala (strona Run modes w sekcji Agent security dokumentacji Cursora), i uruchamiaj Cursor z powłoki lub profilu, w którym jest wyłącznie rola do planu. Niezależnie od wybranego trybu granicą jest poświadczenie tylko do planu; tryb uruchamiania łapie jedynie pomyłki.
-
Spisz konwencje raz. Umieść je w
AGENTS.md(Codex go czyta; Claude Code czyta go, gdy w repozytorium nie maCLAUDE.md, od wersji 2.1.277 w kanalelatest) albo wCLAUDE.md, oraz w regule projektu Cursora:## Infrastructure rules- Terraform >= 1.11. S3 backend with `use_lockfile = true`. No new DynamoDB lock tables.- Pin providers to the current major (`~> 6.0` for hashicorp/aws) and commit .terraform.lock.hcl.- Renames and module moves use `moved` blocks. Never `terraform state mv` in a PR.- Adopt existing resources with `import` blocks, not `terraform import`.- No hardcoded CIDRs, regions, account IDs or secrets: variables and a secrets manager.- You may run fmt, validate, tflint, plan and show. You never run apply or destroy.
Receptura 1: podziel monolit Terraform, niczego nie niszcząc
Dział zatytułowany „Receptura 1: podziel monolit Terraform, niczego nie niszcząc”Podział na moduły zmienia adres każdego zasobu. Bez bloków moved Terraform czyta to jako „usuń stary adres, utwórz nowy”, co w przypadku bazy danych oznacza utratę danych. Z nimi poprawny plan czystej refaktoryzacji to zero zmian: ta jedna liczba jest twoim kryterium akceptacji.
# Terminal, katalog główny repozytorium. Tryb Manual, żeby każda edycja była pokazana przed zapisemclaude --permission-mode manualWklej prompt poniżej. Claude Code edytuje pliki, uruchamia terraform plan i czyta jego wynik w tej samej sesji, więc pętla „zero zmian” domyka się bez kopiowania czegokolwiek.
Zapisz prompt poniżej jako prompts/split-monolith.txt, a potem uruchom:
codex -a on-request -c default_permissions=":workspace" "$(cat prompts/split-monolith.txt)"Trzymaj prompt w repozytorium, żeby następny podział używał tych samych słów. Jeśli piaskownica blokuje sieć, Codex zapyta, zanim uruchomi terraform plan poza nią; zatwierdzaj plan, nigdy apply.
Otwórz agenta w Plan Mode, wklej prompt i zatwierdź granice modułów, zanim zapisze pliki. Przełącz się na Agent, żeby wykonać plan, i uruchom terraform plan w zintegrowanym terminalu, gdy o to poprosi.
Jeśli plan nadal pokazuje zmiany, przyczyna to prawie zawsze jedna z trzech rzeczy: brakujący blok moved, wartość domyślna inna niż stary literał albo zamiana count na for_each (indeks zmienia się z [0] na ["name"] i to też wymaga bloku moved). Poproś agenta, żeby dla każdego zasobu wskazał, która to z nich.
Receptura 2: zamień plan w bramkę, której nie czytasz linia po linii
Dział zatytułowany „Receptura 2: zamień plan w bramkę, której nie czytasz linia po linii”Plan na 400 linii to miejsce, w którym przegląd zawodzi, bo jedno -/+ na bazie danych ginie wśród 60 zmian tagów. Odwróć kolejność: skrypt wyciąga destrukcyjne akcje z planu w formacie maszynowym, a człowiek przegląda tylko tę listę.
#!/usr/bin/env bash# scripts/plan-gate.sh: exit 2 when the plan deletes or replaces anythingset -euo pipefailterraform plan -out=tfplan -input=false -lock-timeout=60sterraform show -json tfplan > plan.jsonjq -r '.resource_changes[]? | select(.change.actions | index("delete")) | "\(.change.actions | join("/"))\t\(.address)"' plan.json > destructive.txtjq '[.resource_changes[]? | {address, actions: .change.actions, replace_paths: .change.replace_paths}]' plan.json > plan-summary.jsonjq -r '[.resource_changes[]?.change.actions | join("/")] | group_by(.) | map("\(.[0]): \(length)") | .[]' plan.jsonif [ -s destructive.txt ]; then echo "Delete or replace needs a named approver:"; cat destructive.txt; exit 2fiW terraform show -json zastąpienie pojawia się jako ["delete","create"] albo ["create","delete"], więc dopasowanie do delete łapie oba przypadki. Uruchamiaj skrypt w sesji agenta i ponownie w CI. W CI zapisz destructive.txt jako wynik zadania (job output); gdy nie jest pusty, zadanie apply trafia do chronionego środowiska, którego wymaganym recenzentem jest właściciel usługi, a apply działa wyłącznie z zapisanego i przejrzanego tfplan.
W ramach receptury 1 dodaj lifecycle { prevent_destroy = true } do zasobów stanowych (bazy danych, buckety z danymi, klucze KMS). Terraform odrzuci wtedy każdy plan, który je usuwa, więc najdroższy błąd staje się błędem planu.
Receptura 3: przejmij dryf z konsoli blokami import
Dział zatytułowany „Receptura 3: przejmij dryf z konsoli blokami import”Ktoś w trakcie incydentu dodał w konsoli regułę grupy zabezpieczeń i teraz każdy plan chce ją usunąć. Nie pozwól agentowi nadpisać dryfu przez apply: ta reguła może być tym, co powstrzymuje incydent.
Uruchom terraform plan -refresh-only, żeby zobaczyć dokładnie, co zmieniło się poza Terraformem. Potem zdecyduj dla każdego zasobu: przejąć go, cofnąć zmianę w konsoli czy dopasować konfigurację. Przy przejmowaniu Terraform 1.5 i nowszy zapisuje import jako kod, więc przechodzi on przegląd jak każda inna zmiana.
Serwer MCP chmury przyspiesza tę pracę: z dostępem do odczytu agent sam wylistuje prawdziwe zasoby, zamiast prosić cię o wklejenie wyników z konsoli. Podłącz go tylko do odczytu, tak jak pokazuje strona serwery MCP dla chmur.
Receptura 4: utwardź szablon CloudFormation lub stos Pulumi
Dział zatytułowany „Receptura 4: utwardź szablon CloudFormation lub stos Pulumi”Ta sama dyscyplina działa z innym poleceniem podglądu. W CloudFormation aws cloudformation deploy --no-execute-changeset tworzy zestaw zmian (change set), który agent może przeczytać bez jego wykonania. W Pulumi planem dla człowieka jest pulumi preview --diff, a dla bramki pulumi preview --json: kroki, których op to delete, replace, create-replacement lub delete-replaced, odfiltruj do destructive.txt, tak samo jak robi to plan-gate.sh. Bramka jest ta sama: wypisz zastąpienia i blokuj do zgody właściciela.
Jak zweryfikować infrastrukturę napisaną przez agenta bez czytania każdej linii?
Dział zatytułowany „Jak zweryfikować infrastrukturę napisaną przez agenta bez czytania każdej linii?”Ułóż kontrole tak, żeby każda mechanicznie łapała jedną klasę błędów, a człowiek patrzył tylko na to, co przez nie przejdzie. Uruchamiaj je w tej kolejności, od najtańszej, w sesji agenta i ponownie w CI.
| Bramka | Polecenie | Łapie | Blokuje build, gdy |
|---|---|---|---|
| Format i składnia | terraform fmt -check -recursive i terraform validate | Wymyślone argumenty, błędy typów, złe referencje | jest jakikolwiek błąd |
| Lint | tflint --recursive | Nieistniejące typy instancji, przestarzałą składnię, nieużywane deklaracje | jest jakikolwiek błąd |
| Polityki statyczne | checkov -d . | Publiczne buckety, niezaszyfrowane magazyny, otwarte grupy zabezpieczeń | kontrola nie przechodzi i nie ma jej na przejrzanej liście wyjątków |
| Zachowanie | terraform test | Moduł, który przestał spełniać swój kontrakt | którykolwiek przebieg testu się nie powiedzie |
| Polityki planu | conftest test plan.json | Twoje własne reguły zastosowane do faktycznie planowanych wartości | pojawi się jakikolwiek deny |
| Destrukcja | scripts/plan-gate.sh | Usunięcia i zastąpienia | destructive.txt ma choć jedną linię |
Wersje sprawdzone 26 września 2026: Terraform 1.16.4, provider hashicorp/aws 6.66.0, tflint 0.64.0, checkov 3.3.19, conftest 0.70.1. Polityka planu dla conftest to kilka linii Rego nad plan.json:
package mainimport rego.v1
deny contains msg if { some rc in input.resource_changes rc.type == "aws_security_group_rule" rc.change.after.type == "ingress" "0.0.0.0/0" in rc.change.after.cidr_blocks rc.change.after.from_port <= 22 rc.change.after.to_port >= 22 msg := sprintf("%s opens SSH to the internet", [rc.address])}Kto zatwierdza. Agent może stwierdzić, że kontrole są zielone. Nie może zatwierdzać. Pull request, który przechodzi wszystkie bramki i ma pusty destructive.txt, potrzebuje jednego recenzenta diffu. Pull request z jakąkolwiek destrukcyjną linią wymaga, żeby właściciel usługi zatwierdził tę listę imiennie, a apply rusza w CI z przejrzanego tfplan. Dołącz wynik bramek do pull requesta jako jego pakiet dowodów, żeby recenzent czytał sześć wyników i krótką listę zamiast HCL.
Niech agent korzysta z rejestru, a nie z pamięci
Dział zatytułowany „Niech agent korzysta z rejestru, a nie z pamięci”Częstym źródłem zepsutego HCL są argumenty providera, które agent pamięta ze starszej wersji głównej. Naprawiają to dwa dodatki, a pełną konfigurację opisuje strona serwery MCP dla infrastruktury.
Serwer Terraform MCP od HashiCorp bez tokenu rejestruje tylko narzędzia rejestru, które sprawdzają aktualną dokumentację providerów i modułów. Z samej konstrukcji działa więc tylko do odczytu:
claude mcp add terraform -s project -- docker run -i --rm hashicorp/terraform-mcp-server:1.3.0codex mcp add terraform -- docker run -i --rm hashicorp/terraform-mcp-server:1.3.0W .cursor/mcp.json:
{ "mcpServers": { "terraform": { "command": "docker", "args": ["run", "-i", "--rm", "hashicorp/terraform-mcp-server:1.3.0"] } } }Umiejętności agentowe HashiCorp (hashicorp/agent-skills, MPL-2.0) zawierają konwencje: refactor-module do receptury 1, terraform-search-import do receptury 3, terraform-test i terraform-style-guide do bramek. W Claude Code zainstaluj plugin, a w Codex i Cursorze pojedyncze umiejętności przez CLI skills (1.7.0):
# Claude Codeclaude plugin marketplace add hashicorp/agent-skillsclaude plugin install terraform@hashicorp# Codex, Cursor i inni agenci: wybieraj umiejętności pojedynczonpx skills add hashicorp/agent-skills/plugins/terraform/skills/refactor-moduleCały plugin ładuje 16 umiejętności i kosztuje około 2150 tokenów stale obecnych w każdej sesji (claude plugin details terraform@hashicorp, 26 września 2026); każda umiejętność dokłada 0,5k–7k, gdy się uruchomi. Szerszy przegląd znajdziesz na stronie serwery MCP dla infrastruktury. Nie instaluj dodatkowo terraform@claude-plugins-official: rejestruje drugi serwer MCP terraform przypięty do starszego obrazu 0.4.0. Sięgaj po umiejętność, gdy chcesz konwencji, a po serwer MCP, gdy agent potrzebuje aktualnych danych z rejestru.
Kiedy Terraform prowadzony przez agenta się psuje
Dział zatytułowany „Kiedy Terraform prowadzony przez agenta się psuje”Co dalej z infrastrukturą jako kodem
Dział zatytułowany „Co dalej z infrastrukturą jako kodem”Warunkiem wstępnym tych receptur jest środowisko pracy agenta, które trzyma granice: uprawnienia i piaskownica. Następny krok to umieszczenie bramek i apply w potoku.