TERRAFORM / PLATFORM ENGINEERING

Terraform a AI agenti: kdy moduly pomáhají a kdy škodí

Změřili jsme pět produkčních Terraform repozitářů napříč AWS a Azure. Výsledek: 169 odkazů na sdílené moduly, ani jeden připnutý na neměnnou verzi, nula testů. A jeden repozitář se třemi voláními modulu na každý skutečný resource.

Červenec 2026 · 16 min čtení · Pro platform inženýry a architekty

TL;DR

  • AI agenti moduly nepotřebují. Nemají vyhodnocovací engine - hledají text. Modul mění doslovnou hodnotu na výpočet, který v repozitáři nelze najít.
  • Změřeno: v modulární variantě vrátil grep na hledanou hodnotu 0 výsledků, přestože plán ji vypočítá správně. Ve ploché variantě 1 výsledek.
  • Cena abstrakce je bimodální. Komunitní moduly jsou obří (VPC modul ~36 tisíc tokenů), "entity" moduly jsou drobné - ale generují tři vrstvy propojení na jeden resource.
  • Nejhorší nález: 169 odkazů na git moduly napříč repozitáři, 0 připnutých na tag nebo SHA. Sdílené moduly měly zajišťovat konzistenci - místo toho ji znemožňují.
  • Nula terraform test souborů v pěti produkčních repozitářích. Standard nebyl nikde vynutitelný, jen doporučený.
  • Řešení: konzistenci nevynucujte dědičností modulů, ale kontrakty nad výstupem plánu. Ty fungují bez ohledu na strukturu a přežijí i kód psaný AI.

Otázka, kterou je potřeba položit znovu

Pravidla pro strukturu Terraform kódu vznikla v době, kdy ho psali výhradně lidé. Moduly, rozdělení do souborů, vrstvy abstrakce - to všechno optimalizuje pro lidskou znovupoužitelnost a pro oddělení stavu.

Dnes významnou část infrastrukturního kódu píše a čte AI. Průzkum Sonar z roku 2026 uvádí, že 42 % commitovaného kódu je psáno nebo asistováno AI agentem. Otázka tedy zní: platí ta pravidla pořád, když hlavním čtenářem kódu přestává být člověk?

Neptali jsme se na to teoreticky. Postavili jsme kontrolovaný experiment a pak změřili pět reálných produkčních repozitářů napříč dvěma cloudy.

Metodika

Analyzovali jsme pět produkčních Terraform kódových bází ve správě jednoho týmu: statický web na AWS, AWS landing zone s organizacemi, aplikační platformu na AWS EKS, aplikační platformu na Azure AKS a globální síťovou infrastrukturu na Azure. Měření probíhalo staticky nad zdrojovým kódem a nad uloženými plány - žádné volání do cloudu, žádná změna infrastruktury.

Anonymizace: repozitáře označujeme A-E. Neuvádíme názvy organizací, domény, IP adresy, identifikátory předplatných ani účtů. Všechny ukázky kódu v článku jsou syntetické.

Jak AI agent doopravdy čte Terraform

Agent nemá jazykový server, nemá index symbolů a nedokáže spolehlivě vyhodnotit HCL výraz v hlavě. Má tři operace: najdi soubory podle vzoru, najdi řetězec v textu, přečti rozsah řádků.

To má jeden zásadní důsledek, který se v diskusích o struktuře kódu nikdy neobjevuje: hledaná hodnota často v repozitáři vůbec neexistuje jako text.

A u Terraformu je to horší než u jiných jazyků. Recenzované benchmarky se shodují:

  • IaC-Eval (NeurIPS 2024): GPT-4 dosáhl 19,4 % úspěšnosti na 458 AWS Terraform úlohách oproti 86,6 % na srovnatelných Python úlohách - zhruba čtyřikrát horší výsledek.
  • DPIaC-Eval (FSE 2026): šest špičkových modelů dosáhlo 20,8-30,2 % úspěšného nasazení na první pokus u 153 reálných úloh; po zapnutí compliance kontrol kleslo číslo na 8,4 %.
  • TerraFormer (ICSE 2026, 17 modelů): příčinou je, že HCL je v trénovacích datech zastoupen podstatně méně než YAML a JSON z Kubernetes, CloudFormation a Ansible.

Poctivá poznámka k číslům

Údaj o GPT-4 pochází z roku 2024 a dnešní modely jsou v absolutních číslech lepší. Robustní zjištění není absolutní hodnota, ale relativní propast mezi infrastrukturním a aplikačním kódem. Ta je strukturální: méně trénovacích dat, žádný typový systém a nemožnost ověřit správnost spuštěním kódu.

Experiment: co stojí jedna vrstva abstrakce

Postavili jsme dvě konfigurace, které vytvářejí bajt po bajtu identickou infrastrukturu. Jedna je plochá, druhá má dvě úrovně modulů s výchozími hodnotami v variables.tf. Pak jsme položili otázku, kterou agent v praxi dostává: "jaký CIDR dostane produkční privátní podsíť a je zapnutá ochrana proti smazání databáze?"

Metrika Plochá konfigurace Modulární (2 úrovně)
grep na hledaný CIDR 1 výsledek 0 výsledků
Souborů k přečtení 1 8
Bajtů k přečtení 557 2 265
Jak se získá odpověď přečtení literálu výpočet přes 3 výchozí hodnoty

Obě varianty vytvoří 10.20.16.0/20 a deletion_protection = true. Jen v jedné z nich to lze najít.

Modulární varianta je podle konvenčních měřítek lepší inženýrství. Je to zároveň varianta, ve které agent hledající text nenajde nic a musí hodnotu dopočítat přes cidrsubnet(), coalesce() a contains() - tedy operací, ve které jsou jazykové modely nejméně spolehlivé.

Dvě konstrukce, které z abstrakce dělají past

1. Výchozí hodnoty v variables.tf modulu. Efektivní hodnota leží v souboru, který u volání modulu nikdo nečte. 2. Počítaná jména a rozsahy (cidrsubnet, format, skládané identifikátory). Výsledek není dohledatelný - doslova nula výskytů, jak jsme naměřili.

Terénní měření: pět produkčních repozitářů

Experiment je jedna věc, realita druhá. Tady je pět skutečných kódových bází, které běží v produkci:

Repozitář Cloud Velikost Resources Volání modulů Volání / resource
A - statický web AWS ~8 tis. tokenů 43 0 0,0
B - landing zone AWS ~22 tis. 52 26 0,5
C - aplikační platforma AWS ~48 tis. 113 11 0,1
D - aplikační platforma Azure ~39 tis. 44 73 1,7
E - globální síť Azure ~38 tis. 32 99 3,1

Velikost je odhad v tokenech (bajty ÷ 4). Resources = přímo deklarované resource bloky.

Nález 1: poměr propojení k obsahu

Sloupec "volání na resource" je nejužitečnější číslo v celé tabulce. Říká, kolik z konfigurace je instalatérství a kolik podstata.

Repozitář E má 99 volání modulů a 32 přímo deklarovaných resources - tedy tři vrstvy propojení na každý skutečný kus infrastruktury. Ne proto, že by to někdo pokazil; vznikl tak logickým dovedením myšlenky "všechno je znovupoužitelný modul" do důsledku. Přesně tohle lidé myslí, když mluví o špagetovém kódu v Terraformu - jenže obvyklá diagnóza ("málo modularizace") je tady přesně opačná.

Nález 2: cena modulu je bimodální

Tady nás data překvapila a stojí za to to říct nahlas, protože to vyvrací zjednodušené "moduly jsou drahé". Změřili jsme skutečnou velikost modulů, které se používají:

~36 tis.
tokenů má samotný kořen komunitního VPC modulu pro AWS
~14 tis.
tokenů má jen jeho variables.tf, tedy rozhraní
0,3×
poměr kódu modulů ke kořenové konfiguraci v repozitáři E

Komunitní moduly typu VPC nebo EKS jsou obří - rozhraní jednoho takového modulu je větší než celá infrastruktura menšího projektu. Naproti tomu drobné "entity" moduly v repozitáři E jsou dohromady jen 0,3násobek kořenové konfigurace; tam nebolí velikost, ale počet skoků.

Správná metrika tedy není "moduly ano/ne", ale kolik tokenů a kolik skoků stojí zodpovězení jedné otázky. Obě selhání - obří modul i les drobných modulů - vedou ke stejnému výsledku.

Nález 3: sdílené moduly bez neměnné verze

Tohle je nejzávažnější zjištění celé analýzy. Repozitáře D a E čerpají moduly ze sdílených git knihoven - přesně ten mechanismus, který má zajišťovat konzistenci mezi projekty a globální infrastrukturou.

169
odkazů na sdílené git moduly celkem
0
z nich připnutých na tag nebo commit SHA
49
odkazů mířících na rozpracovanou opravnou větev

Všechny reference měly tvar ?ref=master nebo mířily rovnou na vývojovou větev. To znamená, že se infrastruktura může změnit, aniž by se ve vašem repozitáři změnil jediný řádek. Dva plány spuštěné v různý čas z identického commitu mohou vytvořit odlišnou infrastrukturu.

Pro AI agenta je to fatální: přečte volání modulu, přečte modul a odvodí závěr, který může být zítra neplatný. Ale problém není v agentovi - ani člověk nemá jak zjistit, co se skutečně nasadí.

Kontrast, který ukazuje řešení

Repozitář C používá komunitní moduly z registru s omezením verze (version = "~> 5.0"). Není to neměnné připnutí, ale je to o řád lepší než pohyblivá větev - a hlavně je to viditelné v místě volání, takže agent i člověk vědí, s čím pracují.

Nález 4: nula vynutitelných kontraktů

Napříč všemi pěti repozitáři jsme našli nula souborů .tftest.hcl. Nativní testovací framework je v Terraformu od verze 1.6 a umí ověřit plán offline, bez cloudu a bez stavu.

Důsledek: standardy existují jako dohoda a jako code review, ne jako pravidlo. V týmu, kde kód píší lidé, to bolí pomalu. V týmu, kde významnou část kódu generuje AI, to přestává fungovat okamžitě - dokumentované chybové vzorce generovaného IaC jsou totiž přesně ty, které code review přehlíží: chybějící šifrování, příliš široká oprávnění, zastaralé atributy.

Rozhodovací pravidlo pro moduly

Z dat vyplývá pravidlo, které je použitelné a nezávislé na módě:

"Modul musí být ospravedlněný opakováním (použije se třikrát a víc) nebo hranicí stavu. Nikdy estetikou."

Situace Doporučení Proč
Do ~30 resources v jednom stavu Ploché soubory, literální hodnoty Modul přidá skoky a nic nevrátí. Jeden soubor na téma.
Vzor se opakuje 3× a více Modul, ale plochý strom Alternativou je copy-paste drift, který je horší.
Odlišný životní cyklus nebo blast radius Oddělený stav, ne modul Hranice stavu je skutečná hranice, modul je jen syntaxe.
"Aby soubory nebyly dlouhé" Nedělat Přesně tak vzniká poměr 3 volání na resource.
Tenký obal nad jedním resource Nedělat Nezvyšuje úroveň abstrakce, jen přidává soubor navíc.

Je to i oficiální doporučení HashiCorpu: držet strom modulů plochý, preferovat kompozici před hlubokým vnořováním a nepsat moduly, které jen obalují jediný typ resource.

Konzistence bez špagetového kódu

Tady je jádro věci. Většina týmů se snaží držet konzistenci dědičností zdrojového kódu: všechny projekty importují stejný modul. Data ukazují, kam to vede - 169 nepřipnutých odkazů a poměr 3 volání na resource.

Funkční model je jiný: sdílený modul určuje, jak je konfigurace napsaná. Kontrakt určuje, co z ní vznikne. Vynucujte to druhé.

Vrstva 1: kontrakty nad výstupem plánu

terraform test s command = plan běží offline, bez přístupu do cloudu a bez stavu. Projekty pak mohou být strukturované různě, ale nemohou se lišit v tom, na čem záleží:

# tests/guardrails.tftest.hcl
variables {
  environment = "prod"
  vpc_cidr    = "10.20.0.0/16"
}

run "prod_database_is_hardened" {
  command = plan

  assert {
    condition     = output.db_settings.deletion_protection == true
    error_message = "produkční databáze musí mít ochranu proti smazání"
  }
  assert {
    condition     = output.db_settings.backup_retention >= 30
    error_message = "produkční databáze musí držet zálohy alespoň 30 dní"
  }
  assert {
    condition     = output.db_settings.storage_encrypted == true
    error_message = "úložiště produkční databáze musí být šifrované"
  }
}

run "dev_is_not_over_provisioned" {
  command = plan
  variables { environment = "dev" }

  assert {
    condition     = output.db_settings.instance_class == "db.t4g.medium"
    error_message = "dev má používat levnou instanci"
  }
}

Ověřeno v praxi: oba testy proběhnou offline za sekundy, bez credentials.

Vrstva 2: policy nad JSON plánem napříč projekty

Jeden policy repozitář aplikovaný na plán každého projektu. Tohle je jediný mechanismus konzistence, který přežije rozdílné struktury, rozdílné verze modulů i kód generovaný AI - protože kontroluje výsledek, ne autorství:

terraform show -json tfplan > plan.json

# příklad kontroly nad rozbaleným plánem
conftest test --policy ./platform-policies plan.json

Ověřili jsme to na reálném plánu: kontrola prošla celou infrastrukturou, aniž by přečetla jediný .tf soubor nebo věděla, jak je projekt strukturovaný. Přesně to je potřeba, když má každý tým jiný layout.

Pokrývá to i zdokumentované chybové vzorce AI generovaného IaC, na které terraform validate ani plan z principu neupozorní: zástupné znaky v IAM politikách, chybějící šifrování, veřejné ACL, 0.0.0.0/0 a natvrdo zapsané hodnoty.

Vrstva 3: neměnné verze modulů

Nejlevnější oprava s nejvyšším dopadem. Sdílený modul bez neměnné reference není konzistence, ale sdílená nestabilita:

# ŠPATNĚ - infrastruktura se mění bez změny ve vašem repozitáři
module "role_assignment" {
  source = "git::ssh://git@example.com/platform/modules.git//authorization/role_assignment?ref=master"
}

# ŠPATNĚ - odkaz na rozpracovanou větev v produkci
module "subnet" {
  source = "git::ssh://git@example.com/platform/modules.git//network/subnet?ref=fix/symlinks"
}

# SPRÁVNĚ - neměnný tag, viditelný v místě volání
module "role_assignment" {
  source = "git::ssh://git@example.com/platform/modules.git//authorization/role_assignment?ref=v2.4.0"
}

Pravidlo do CI: odmítni plán, pokud jakýkoli ref= není tag nebo SHA.

Vrstva 4: dejte agentům orákulum místo zdrojáku

Nenuťte agenta hodnoty odvozovat - nechte ho je zjistit. Tohle patří do AGENTS.md nebo CLAUDE.md v každém infra repozitáři:

# Terraform: NIKDY neodvozuj hodnoty čtením modulů. Zjisti je.

terraform show -json tfplan | jq '.planned_values'    # všechny rozbalené hodnoty
echo 'cidrsubnet("10.20.0.0/16", 4, 1)' | terraform console
terraform console -var-file=prod.tfvars               # ověření výrazu

# NIKDY nesypej celý JSON plánu do kontextu - je 4,5× větší než HCL,
# ze kterého vznikl. Používej jq výřez.
Výřez plánu Velikost Tokenů
Celý JSON plánu150 900 B~37 700
Jen resource_changes47 186 B~11 800
Shrnutí změn (adresa + akce + typ)2 263 B~600

Naměřeno na reálném plánu o 20 resources. Rozdíl mezi celým plánem a shrnutím je 60násobný.

Co s tím udělat tento týden

Pořadí podle poměru přínos/práce

Spočítejte si poměr volání modulů na resource. Nad 1,0 máte instalatérství, ne infrastrukturu.
Projděte všechny ref= ve sdílených modulech a připněte je na tagy. Přidejte CI kontrolu, která pohyblivé reference odmítne.
Napište první tři .tftest.hcl kontrakty na pravidla, na kterých vám opravdu záleží.
Zapněte policy kontrolu nad JSON plánem v CI - jeden policy repozitář pro všechny projekty.
Doplňte do AGENTS.md instrukci, aby agent hodnoty zjišťoval přes plán a konzoli, ne odvozoval.
Přesuňte výchozí hodnoty z variables.tf modulů do místa volání, nebo je zveřejněte jako výstupy.
Nerefaktorujte malé ploché repozitáře do modulů. Pokud máte 20 resources a nula modulů, máte hotovo.

Často kladené otázky

Potřebují AI agenti Terraform moduly?

Ne. Moduly optimalizují znovupoužitelnost pro člověka a oddělení stavu, ne čitelnost pro agenta. Agent hledá text; modul mění doslovnou hodnotu na výpočet rozprostřený přes několik souborů. Vyplatí se při opakování (třikrát a víc) nebo při oddělení stavu - nikdy kvůli estetice.

Máme refaktorovat existující modulární kód?

Většinou ne - přepisování funkční infrastruktury nese vlastní riziko. Prioritou je připnout verze, doplnit kontrakty a policy a zveřejnit počítané hodnoty jako výstupy. Rozpouštění modulů má smysl jen tam, kde poměr volání na resource výrazně přesahuje jedna.

Znamená to, že máme psát jeden obří soubor?

Ne. Rozdělení do souborů podle tématu (network.tf, iam.tf, storage.tf) je pro agenty ideální - dá se cíleně vyhledávat a číst po částech. Problém není počet souborů, ale počet skoků mezi nimi kvůli abstrakci.

Jak držet konzistenci mezi projekty a globální infrastrukturou?

Kontrakty nad výstupem plánu plus policy as code, ne dědičnost modulů. Sdílený modul určuje, jak je konfigurace napsaná; kontrakt určuje, co z ní vznikne. Jen to druhé je vynutitelné napříč týmy s různými layouty.

Nahradí AI potřebu platform týmu?

Naopak. Čím víc infrastrukturního kódu vzniká rychle, tím důležitější je někdo, kdo vlastní kontrakty, policy a verzování. Role se posouvá od psaní konfigurace k definování a vynucování pravidel.

Klíčové poznatky

  • Agenti nepotřebují moduly, potřebují dohledatelné hodnoty. Naměřeno: 1 výsledek versus 0 při hledání téhož údaje.
  • Poměr volání modulů na resource je nejlepší detektor špagetového kódu. Nad 1,0 je konfigurace převážně propojování.
  • Cena abstrakce je bimodální - obří komunitní moduly i les drobných entit vedou ke stejnému problému, jen z opačné strany.
  • Sdílený modul bez neměnné verze není konzistence. 169 odkazů, 0 připnutých - a přitom to měl být hlavní nástroj standardizace.
  • Vynucujte výsledky, ne strukturu. terraform test a policy nad JSON plánem fungují napříč layouty a přežijí AI generovaný kód.
  • Nula testů v pěti produkčních repozitářích je běžný stav, ne výjimka. To je příležitost, ne ostuda.

Související články

Zdroje a metodika

  • Vlastní měření: pět produkčních Terraform kódových bází (AWS a Azure), statická analýza zdrojového kódu a uložených plánů, červenec 2026. Data anonymizována.
  • IaC-Eval (NeurIPS 2024) - benchmark 458 AWS Terraform scénářů.
  • DPIaC-Eval (FSE 2026) - 153 reálných úloh, šest špičkových modelů.
  • TerraFormer (ICSE 2026) - vyhodnocení 17 modelů, analýza zastoupení HCL v trénovacích datech.
  • Sonar, State of Code 2026 - podíl kódu psaného nebo asistovaného AI.
  • Dokumentace HashiCorp: vývoj modulů a kompozice, terraform test, JSON formát plánu.

Chcete vědět, jak na tom je vaše infrastruktura?

Děláme audity Terraform kódových bází - poměr abstrakce, verzování modulů, vynutitelnost standardů a připravenost na práci s AI agenty. Výstupem je konkrétní seznam kroků, ne prezentace.

Domluvit audit