Przejdź do głównej zawartości

Infrastruktura jako kod z asystentami AI

Dziedziczysz moduł Terraform liczący 2000 linii bez żadnej dokumentacji, poprzedni inżynier platformy odszedł, a Ty masz dwa dni na dodanie wieloregionalnej repliki odczytu bez kładzenia produkcji. Czytanie dokumentacji dostawcy AWS karta po karcie, jednocześnie rekonstruując intencje autora, to dokładnie ta wolna i podatna na błędy praca, którą asystenci AI potrafią dobrze skracać — o ile osadzisz je w prawdziwych schematach dostawców, zamiast pozwalać im zgadywać na podstawie przestarzałych danych treningowych.

Ten przewodnik pokazuje przepływy pracy, które sprawdzają się na produkcji: projektowanie przez rozmowę, generowanie osadzone w MCP, przegląd bezpieczeństwa i naprawa dryfu w Terraform, CloudFormation, Pulumi i CDK — przy użyciu Cursor, Claude Code i Codex.

  • Powtarzalny wzorzec ujmowania żądań infrastrukturalnych jako ograniczeń biznesowych, a nie list zasobów
  • Konfigurację MCP dla serwerów HashiCorp Terraform, Pulumi i AWS we wszystkich trzech narzędziach, dzięki czemu sugestie opierają się na żywych danych z rejestru/konta
  • Trzy gotowe do skopiowania prompty, których możesz użyć już dziś: przegląd według ram bezpieczeństwa, przeczesanie pod kątem dryfu i generator nadzoru kosztów
  • Listę kontrolną „Gdy to się psuje” dla trybów awarii, które naprawdę bolą (blokady stanu, dryf, zerwane przypięcie dostawcy, autoryzacja MCP)

Największą dźwignią jakości wyniku jest prompt otwierający. Inżynierowie, którzy dostają generyczne konfiguracje, proszą o generyczne rzeczy („stwórz klaster EKS z 3 węzłami”). Inżynierowie, którzy dostają konfiguracje gotowe do produkcji, opisują biznes i pozwalają modelowi wyprowadzić topologię.

Klauzula „three riskiest assumptions” to właśnie to, co oddziela użyteczną odpowiedź od ściany HCL. Zmusza model do ujawnienia, gdzie zgaduje (Czy Atlas jest w tym samym regionie? Czy SLA jest per region, czy globalne?), żebyś skorygował kurs, zanim powstanie jakikolwiek kod. Wygląda to identycznie w Cursor, Claude Code i Codex — dyscyplina tkwi w promptcie, nie w narzędziu.

Modele halucynują argumenty zasobów i nie nadążają za wydaniami dostawców. Serwery MCP rozwiązują to, dając asystentowi żywy dostęp do Terraform Registry, Pulumi Registry i Twojego konta AWS. Konfiguracja jest koncepcyjnie taka sama w każdym narzędziu — zarejestruj serwer, a potem promptuj normalnie — ale polecenie rejestracji się różni.

To oficjalny serwer HashiCorp (terraform-mcp-server), zapewniający wyszukiwania w Registry, odkrywanie dostawców/modułów oraz zarządzanie przestrzeniami roboczymi HCP Terraform.

Dodaj do .cursor/mcp.json w swoim projekcie (lub do konfiguracji globalnej przez Settings, MCP):

{
"mcpServers": {
"terraform": {
"command": "npx",
"args": ["-y", "terraform-mcp-server"]
}
}
}

Następnie w trybie agenta: “List the current aws_db_instance arguments for Postgres and flag any that are deprecated in the latest provider.”

AWS Labs publikuje kilka serwerów. Używaj właściwego i omijaj te przestarzałe:

  • awslabs.cfn-mcp-server — CloudFormation i bezpośrednie zarządzanie zasobami przez Cloud Control API. Aktualny i utrzymywany.
  • awslabs.aws-iac-mcp-server — walidacja szablonów CloudFormation, kontrole zgodności i rozwiązywanie problemów z wdrożeniami. To skonsolidowany następca przestarzałego już serwera CDK.

Te serwery dostarczane są jako pakiety Pythona, więc uruchamiają się przez uvx, a nie npx:

{
"mcpServers": {
"aws-cfn": {
"command": "uvx",
"args": ["awslabs.cfn-mcp-server@latest"]
},
"aws-iac": {
"command": "uvx",
"args": ["awslabs.aws-iac-mcp-server@latest"]
}
}
}

Poświadczenia pochodzą ze standardowego łańcucha profili AWS; ustaw AWS_PROFILE w bloku env serwera, jeśli używasz nazwanych profili.

Dla infrastruktury w języku programowania serwer Pulumi (@pulumi/mcp-server) uruchamia pulumi preview/up, pobiera wyjścia stosu i czyta Pulumi Registry.

{
"mcpServers": {
"pulumi": {
"command": "npx",
"args": ["@pulumi/mcp-server@latest", "stdio"]
}
}
}

Generuj produkcyjny Terraform, potem czytaj go krytycznie

Dział zatytułowany „Generuj produkcyjny Terraform, potem czytaj go krytycznie”

Z podłączonym serwerem Terraform MCP generowanie osadza się w aktualnych schematach. Proś o najnowsze wersje dostawców wprost — a potem weryfikuj wynik, zamiast mu ufać.

Osadzone żądanie produkuje konfigurację główną taką jak ta:

terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
backend "s3" {
bucket = "acme-tf-state-prod"
key = "platform/terraform.tfstate"
region = "us-east-1"
encrypt = true
use_lockfile = true
}
}

Dwie rzeczy do zweryfikowania, zanim zaufasz jakiemukolwiek Terraformowi wygenerowanemu przez AI, bo modele rutynowo się w nich mylą:

  • Przypięcie dostawcy zgadza się z rzeczywistością. Dostawca AWS jest na linii 6.x (6.49.0 w chwili pisania). Jeśli model emituje ~> 5.0, twierdząc, że to „najnowsza wersja”, to sygnał przestarzałego treningu — popraw na ~> 6.0 i uruchom ponownie terraform init -upgrade.
  • Blokowanie stanu jest aktualne. Nowoczesny Terraform blokuje stan S3 przez use_lockfile = true; stara blokada dynamodb_table nie jest już wymagana. Jeśli widzisz tabelę blokad DynamoDB wygenerowaną dla nowego projektu, zapytaj dlaczego.

Gdy model zwróci tę tabelę, spodziewaj się, że będzie nadmiarowo oznaczał (np. upierając się, że wewnętrzny ALB potrzebuje WAF). Potraktuj to jak pierwsze podejście starszego recenzenta: zaakceptuj ustalenia dotyczące szyfrowania w spoczynku i najmniejszych uprawnień, odeprzyj te, które nie pasują do Twojego modelu zagrożeń, i poproś go o uzasadnienie każdego „Critical”, z którym się nie zgadzasz.

Dryf — ktoś klikający w konsoli, hotfix, który nigdy nie wrócił do kodu — to miejsce, gdzie IaC cicho gnije. Z podłączonym serwerem AWS MCP asystent może odczytać faktyczny stan zasobów i porównać go z tym, co deklaruje Twój kod.

Reprezentatywny wycinek tego, co wraca:

URGENT db-cluster-prod / SecurityGroupIngress
expected: 10.0.0.0/16 on 5432
current: 0.0.0.0/0 on 5432 <- opened manually 3 days ago
risk: Postgres exposed to the internet
fix: revert in console now, then re-apply stack to lock it

Zanim na to zareagujesz, zweryfikuj dwie rzeczy, w których raporty o dryfie generowane przez AI się mylą: że wartość „expected” zgadza się z Twoim aktualnym kodem (a nie ze starym planem) oraz że ręczna zmiana nie była celową, nieudokumentowaną awaryjną poprawką typu break-glass. Potwierdź z osobą odpowiedzialną za stos, a potem pozwól asystentowi wygenerować zestaw zmian naprawczych.

Optymalizacja kosztów jest wielowymiarowa — wydajność, niezawodność i wydatki ważone względem siebie — czyli dokładnie taki rodzaj rozumowania, który warto delegować, a potem audytować.

Dla obciążenia wsadowego podaj modelowi kształt zadania i pozwól mu wybrać topologię optymalną kosztowo:

Workload: 100GB/day batch, tolerates 4h delay, needs 16 vCPU / 64GB while running,
only 08:00-18:00 EST. Target under $500/month. Recommend compute (Spot vs. on-demand
vs. Fargate), storage tiering, and the scheduler. Show the trade-off you made to hit budget.

Dobra odpowiedź sięga po Spot z awaryjnym on-demand, zaplanowane skalowanie do zera poza godzinami pracy oraz S3 Intelligent-Tiering — a potem nazywa kompromis (przerwania Spot dodają zmienność opóźnień w ramach budżetu 4-godzinnego SLA). Jeśli po cichu wybierze zawsze włączony on-demand, odeprzyj to: “Why not Spot, given the 4-hour tolerance?”

Dla zespołów, które wolą prawdziwe języki programowania od HCL czy YAML, Pulumi i CDK pozwalają asystentowi generować typowaną, testowalną infrastrukturę.

Poproś: “Using Pulumi TypeScript, create a ComponentResource for a microservice with a configurable replica count, CPU/memory, and an ingress path. Default to 1 replica in non-prod and 3 in prod.” Osadzony wynik wygląda tak:

import * as pulumi from '@pulumi/pulumi';
interface ServiceArgs {
environment: string;
replicas: number;
cpu: string;
memory: string;
}
class MicroserviceStack extends pulumi.ComponentResource {
constructor(name: string, args: ServiceArgs) {
super('acme:infra:MicroserviceStack', name, {}, {});
// ...service, ingress, and monitoring resources, parented to this
this.registerOutputs();
}
}
for (const svc of ['user-service', 'order-service', 'payment-service']) {
new MicroserviceStack(svc, {
environment: env,
replicas: env === 'production' ? 3 : 1,
cpu: '500m',
memory: '1Gi',
});
}

Następnie: “Generate @pulumi/policy unit tests asserting that every service in production has at least 2 replicas and a CPU limit set.”

Cokolwiek wybierzesz, przypnij wersję silnika do rzeczywistości (Aurora Postgres 16.x jest aktualna i ma najdłuższe okno wsparcia) i nie wysyłaj pierwszego synth — przepuść zsyntetyzowany szablon przez awslabs.aws-iac-mcp-server na przebieg walidacyjny.

Prawdziwe awarie IaC układają się w kilka wzorców. Rozpoznawaj je szybko:

  1. Konflikt blokady stanu. terraform apply zawisa na „Acquiring state lock”. Zwykle przebieg CI i człowiek uruchomili się jednocześnie albo poprzedni przebieg padł w trakcie apply. Prompt: “A terraform apply is blocked on a state lock. Check whether the lock is stale (look at the lock holder and timestamp), tell me whether force-unlock <ID> is safe, and recommend a CI mutex so this stops happening.” Nigdy nie rób force-unlock na ślepo — możesz uszkodzić stan, jeśli apply naprawdę wciąż działa.

  2. Dryf po ręcznej edycji w konsoli. Twój plan pokazuje zmiany, których nie wprowadziłeś. Ktoś coś naprawił ręcznie. Uruchom prompt o dryfie powyżej, a potem zdecyduj per zasób: zaimportuj zmianę albo ją cofnij. Nie cofaj wszystkiego hurtem — możesz wymazać prawdziwą poprawkę.

  3. Zerwane przypięcie dostawcy. terraform init zawodzi albo plan eksploduje po tym, jak model wpisał ~> 6.0, a Twój plik blokady przypina 5.x (lub na odwrót). Wygeneruj plik blokady ponownie przez terraform providers lock i nigdy nie pozwól AI podbić głównej wersji dostawcy bez wcześniejszego przeczytania przewodnika aktualizacji tego dostawcy.

  4. Serwer MCP nie zwraca nic użytecznego. Serwer AWS nie widzi Twojego konta albo serwer Terraform zwraca przestarzałe dane. Niemal zawsze chodzi o autoryzację lub region: potwierdź, że AWS_PROFILE/AWS_REGION są ustawione w env serwera, że profil ma uprawnienia odczytu i że zarejestrowałeś właściwy pakiet (a nie przestarzały). Uruchom ponownie claude mcp list / codex mcp list, aby potwierdzić, że serwer jest faktycznie podłączony.

  5. Zahalucynowane zasoby lub argumenty. Bez osadzenia w MCP modele wymyślają prawdopodobnie wyglądające, lecz fałszywe argumenty. Jeśli terraform validate odrzuci pole, nie kłóć się z modelem — podłącz ponownie serwer Terraform MCP i poproś go o potwierdzenie argumentu względem żywego schematu dostawcy.