{"id":"0b5687a7-1cc2-4462-88ef-a03d4fa6777f","shortId":"MWq4Tb","kind":"skill","title":"terraform","tagline":"Use when creating, adopting, refactoring, or operating Terraform configurations, especially on Google Cloud. Applies to `*.tf`, `.terraform.lock.hcl`, `terragrunt.hcl`, and `terraform` workflows involving repo layout, root modules, backends/state, workspaces versus directories, b","description":"# Terraform\n\n## Overview\n\nUse this skill to keep Terraform work small-state, reviewable, and brownfield-safe.\n\nThis repo should treat Terraform as four separate concerns:\n\n1. **Place** Terraform in the right part of the repo.\n2. **Provision** new infrastructure with clear root-module boundaries.\n3. **Adopt** existing infrastructure without taking unsafe shortcuts.\n4. **Operate** Terraform through validated plans, CI, and policy checks.\n\nFor this repo family, default to **brownfield embedding** inside an existing product repo unless the user explicitly wants a dedicated infrastructure repository.\n\n## Quick Reference\n\n| Decision | Default | Avoid |\n|---|---|---|\n| Brownfield placement | `infra/terraform/` inside the existing repo | Mixing Terraform into `src/` or app runtime folders |\n| Environment model | Separate directories and separate state per env/root | Using CLI workspaces for `dev` / `stage` / `prod` |\n| State size | One root module per deployable unit or boundary | Giant multi-service roots |\n| GCP backend | GCS remote state | Local state for shared environments |\n| Local auth | ADC | Long-lived service account keys |\n| CI auth | Attached service account on GCP, otherwise WIF | Downloaded JSON keys when avoidable |\n| Sensitive values | Treat state and plan artifacts as sensitive; prefer Secret Manager plus `sensitive` / `ephemeral` patterns when supported | Hardcoding secrets or committing plan/state artifacts |\n| Brownfield adoption | Export/import, review, then refactor with `moved` blocks | Hand-editing state to “make it fit” |\n\n## Operating Lanes\n\n### Lane 1: Repo and State Design\n\n- Keep Terraform in a clearly scoped infrastructure area.\n- Prefer `infra/terraform/` for brownfield repos.\n- Keep reusable modules separate from live environment roots.\n- Keep each root module small enough that reviewers can understand a plan.\n\n### Lane 2: Greenfield Provisioning\n\n- Start with a small root module and a reusable module boundary only where reuse is real.\n- Pin provider and module versions.\n- Check in `.terraform.lock.hcl`.\n\n### Lane 3: Brownfield Adoption\n\n- Inventory what already exists.\n- Export or import existing resources into Terraform.\n- Normalize the generated or imported configuration.\n- Refactor with `moved` blocks instead of destructive rename/recreate cycles.\n\n### Lane 4: Day-2 Operations\n\n- Run `fmt`, `validate`, saved `plan`, and policy checks before `apply`.\n- Prefer CI-mediated `plan` and `apply`, especially for shared environments.\n- Upgrade versions intentionally and review lockfile drift.\n\n<workflow>\n\n## Workflow\n\n### Step 1: Choose Repo Placement\n\nUse the smallest layout that preserves clear ownership.\n\n- **Brownfield application repo:** put Terraform under `infra/terraform/`.\n- **Dedicated infra repo:** keep the same internal split of `modules/` and live environment roots.\n- **Service-specific IaC:** place service roots under `infra/terraform/environments/<env>/<service>/`.\n\nRead [references/layout.md](references/layout.md) before creating directories.\n\n### Step 2: Define Root-Module Boundaries\n\nA root module is a state boundary. Treat it as an operational boundary too.\n\n- Split by application, shared platform service, or blast-radius boundary.\n- Prefer separate roots for shared networking, project/bootstrap, and app-service stacks.\n- Keep unrelated systems out of the same state even if they deploy together.\n\n### Step 3: Establish Backend and Auth\n\nFor GCP, default to:\n\n- **Local development:** ADC\n- **Privileged local work:** service account impersonation\n- **CI on Google Cloud:** attached service account\n- **CI outside Google Cloud:** Workload Identity Federation\n- **Remote state:** GCS backend per root/environment\n\nRead [references/gcp.md](references/gcp.md) before writing provider or backend configuration.\n\nIf the root spans multiple projects, regions, or beta-only resources, define explicit provider aliases instead of overloading one default `google` provider configuration.\n\n### Step 3.5: Handle Sensitive Values Early\n\nTreat Terraform state files, saved plan files, and plan JSON as sensitive artifacts.\n\n- Keep state and plan artifacts out of Git.\n- Prefer Secret Manager or another external secret source over plaintext secrets in `.tfvars`.\n- Use `sensitive = true` for inputs and outputs that must be redacted.\n- Use `ephemeral = true` or write-only arguments when the provider/resource supports them and the value should stay out of state and plan files entirely.\n\n### Step 4: Pick the Environment Model\n\nUse separate directories and separate state for `dev`, `stage`, and `prod`.\n\nUse Terraform CLI workspaces only when all of the following are true:\n\n- the configuration is the same shape in every instance\n- credentials and approvals are the same\n- the backend is shared intentionally\n- the instances are peers, not separate systems\n\nIf any of those conditions are false, do not use CLI workspaces as the primary environment model.\n\n### Step 5: Implement and Validate\n\nBefore proposing an `apply`, run the low-risk checks first:\n\n1. `terraform fmt`\n2. `terraform init`\n3. `terraform validate`\n4. `terraform plan -out=tfplan`\n5. `terraform show -json tfplan > tfplan.json` when policy tooling or machine review is needed\n6. `terraform test` when the module or root justifies it\n\nUse [references/testing.md](references/testing.md) for the validation pipeline.\n\n### Step 6: Brownfield Adoption Path\n\nWhen a system already exists:\n\n1. Decide the target root-module boundary before importing anything.\n2. Export existing GCP resources if that accelerates discovery.\n3. Add `import` blocks or targeted imports for the selected boundary.\n4. Generate configuration when helpful, but treat it as a scaffold.\n5. Refactor into the desired module shape.\n6. Use `moved` blocks to preserve state history during renames or splits.\n\nUse [references/brownfield.md](references/brownfield.md) for the exact flow.\n\n### Step 7: Connect Service-Specific Patterns\n\nAfter the Terraform structure is sound, pull in service-specific references:\n\n- Cloud Run examples: [../cloud-run/references/terraform.md](../cloud-run/references/terraform.md)\n- GKE examples: [../gke/references/terraform.md](../gke/references/terraform.md)\n\n</workflow>\n\n<guardrails>\n\n## Guardrails\n\n- **Do not use CLI workspaces for system decomposition** or for environments with separate credentials or approvals.\n- **Do not put unrelated services in one state** just because a single PR touches them.\n- **Do not hand-edit Terraform state** unless it is a documented break-glass recovery.\n- **Do not normalize brownfield infrastructure by deleting and recreating it** when import and refactor paths exist.\n- **Do not treat exported or generated HCL as production-ready** until it is cleaned up and reviewed.\n- **Do not rely on service account keys by default on GCP** when ADC, impersonation, or Workload Identity Federation are available.\n- **Do not treat remote state as non-sensitive**. State files and saved plans can contain secrets, tokens, and generated credentials.\n- **Do not skip `.terraform.lock.hcl` in root modules** that will be shared or reviewed.\n- **Do not hide destructive changes inside apply-only workflows**. Save and review the plan first.\n- **Do not introduce Terragrunt as the default architecture** unless the repo already standardized on it. Plain Terraform is the baseline.\n- **Do not let helper scripts become hidden infrastructure dependencies**. Prefer provider resources and documented modules first.\n- **Do not leave stateful resources without lifecycle protection**. Use `prevent_destroy` and provider-specific deletion protection where the platform supports them.\n\n</guardrails>\n\n<validation>\n\n## Validation Checkpoint\n\nBefore claiming a Terraform change is ready, verify:\n\n- [ ] the repo layout keeps Terraform out of application runtime folders\n- [ ] each root module has a clear ownership and state boundary\n- [ ] environment separation uses directories/state, or workspace use is explicitly justified\n- [ ] backend and authentication strategy are documented\n- [ ] sensitive inputs, state, and plan artifacts are handled as secrets\n- [ ] provider aliases or `google-beta` configuration are explicit when multi-project, multi-region, or beta-only resources are involved\n- [ ] provider and module versions are pinned intentionally\n- [ ] `.terraform.lock.hcl` is committed when the root is meant to be versioned\n- [ ] `terraform fmt`, `terraform validate`, and a saved `terraform plan -out=...` were run\n- [ ] stateful resources use lifecycle protection or an explicitly documented exception\n- [ ] brownfield imports, generated config, and `moved` blocks are documented when applicable\n- [ ] policy validation and module tests were considered for shared or sensitive infrastructure\n\n</validation>\n\n<example>\n\n## Example\n\nBrownfield application repo layout:\n\n```text\nrepo/\n├── src/\n├── tests/\n├── .agents/\n└── infra/\n    └── terraform/\n        ├── modules/\n        │   ├── project-services/\n        │   ├── network/\n        │   └── cloud-run-service/\n        └── environments/\n            ├── dev/\n            │   ├── shared-network/\n            │   └── api-service/\n            ├── stage/\n            │   ├── shared-network/\n            │   └── api-service/\n            └── prod/\n                ├── shared-network/\n                └── api-service/\n```\n\nMinimal root files:\n\n```text\napi-service/\n├── backend.tf\n├── main.tf\n├── providers.tf\n├── terraform.tf\n├── terraform.tfvars\n├── variables.tf\n├── outputs.tf\n└── README.md\n```\n\nGCP root skeleton:\n\n```hcl\nterraform {\n  required_version = \">= 1.10.0\"\n\n  required_providers {\n    google = {\n      source  = \"hashicorp/google\"\n      version = \"~> 6.0\" # Pin to a current minor series intentionally.\n    }\n  }\n\n  backend \"gcs\" {}\n}\n\nprovider \"google\" {\n  project = var.project_id\n  region  = var.region\n}\n\nmodule \"service\" {\n  source     = \"../../modules/cloud-run-service\"\n  project_id = var.project_id\n  region     = var.region\n  name       = var.name\n}\n```\n\n</example>\n\n---\n\n## References Index\n\n- **[Layout and Workspaces](references/layout.md)**\n  - Brownfield repo placement, root-module boundaries, directory conventions, and when not to use CLI workspaces.\n- **[GCP Terraform Patterns](references/gcp.md)**\n  - ADC, impersonation, WIF, GCS backends, API enablement, module pinning, and policy validation on Google Cloud.\n- **[Brownfield Adoption](references/brownfield.md)**\n  - Export, import blocks, generated configuration, and refactoring with `moved` blocks.\n- **[Testing and Delivery](references/testing.md)**\n  - `fmt`, `validate`, saved plans, `terraform test`, CI, and policy checks.\n\n## Official References\n\n- <https://docs.cloud.google.com/docs/terraform/best-practices/general-style-structure>\n- <https://docs.cloud.google.com/docs/terraform/best-practices/root-modules>\n- <https://docs.cloud.google.com/docs/terraform/best-practices/operations>\n- <https://docs.cloud.google.com/docs/terraform/best-practices/testing>\n- <https://docs.cloud.google.com/docs/terraform/authentication>\n- <https://docs.cloud.google.com/docs/terraform/resource-management/export>\n- <https://docs.cloud.google.com/docs/terraform/resource-management/import>\n- <https://docs.cloud.google.com/docs/terraform/policy-validation/quickstart>\n- <https://developer.hashicorp.com/terraform/language/style>\n- <https://developer.hashicorp.com/terraform/language/state/workspaces>\n- <https://developer.hashicorp.com/terraform/language/import>\n- <https://developer.hashicorp.com/terraform/language/modules/develop/refactoring>","tags":["terraform","flow","cofin","agent-skills","ai-agents","beads","claude-code","codex","cursor","developer-tools","gemini-cli","opencode"],"capabilities":["skill","source-cofin","skill-terraform","topic-agent-skills","topic-ai-agents","topic-beads","topic-claude-code","topic-codex","topic-cursor","topic-developer-tools","topic-gemini-cli","topic-opencode","topic-plugin","topic-slash-commands","topic-spec-driven-development"],"categories":["flow"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cofin/flow/terraform","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cofin/flow","source_repo":"https://github.com/cofin/flow","install_from":"skills.sh"}},"qualityScore":"0.455","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 11 github stars · SKILL.md body (11,548 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-24T07:03:20.643Z","embedding":null,"createdAt":"2026-04-23T13:04:02.286Z","updatedAt":"2026-04-24T07:03:20.643Z","lastSeenAt":"2026-04-24T07:03:20.643Z","tsv":"'-2':346 '/../modules/cloud-run-service':1315 '/cloud-run/references/terraform.md':865,866 '/docs/terraform/authentication':1408 '/docs/terraform/best-practices/general-style-structure':1396 '/docs/terraform/best-practices/operations':1402 '/docs/terraform/best-practices/root-modules':1399 '/docs/terraform/best-practices/testing':1405 '/docs/terraform/policy-validation/quickstart':1417 '/docs/terraform/resource-management/export':1411 '/docs/terraform/resource-management/import':1414 '/gke/references/terraform.md':869,870 '/terraform/language/import':1426 '/terraform/language/modules/develop/refactoring':1429 '/terraform/language/state/workspaces':1423 '/terraform/language/style':1420 '1':59,247,378,720,775 '1.10.0':1288 '2':69,286,427,723,786 '3':79,314,484,726,795 '3.5':556 '4':87,344,632,729,806 '5':705,734,817 '6':748,766,824 '6.0':1295 '7':844 'acceler':793 'account':187,193,500,508,958 'adc':182,495,965,1350 'add':796 'adopt':5,80,228,316,768,1366 'agent':1232 'alias':546,1138 'alreadi':319,773,1034 'anoth':586 'anyth':785 'api':1250,1257,1264,1271,1355 'api-servic':1249,1256,1263,1270 'app':136,467 'app-servic':466 'appli':15,357,364,712,1014 'applic':391,449,1098,1210,1225 'apply-on':1013 'approv':671,887 'architectur':1030 'area':259 'argument':613 'artifact':209,226,573,578,1132 'attach':191,506 'auth':181,190,488 'authent':1123 'avail':972 'avoid':123,202 'b':32 'backend':171,486,519,529,676,1121,1303,1354 'backend.tf':1273 'backends/state':28 'baselin':1042 'becom':1048 'beta':540,1142,1155 'beta-on':539,1154 'blast':455 'blast-radius':454 'block':235,337,798,827,1206,1370,1377 'boundari':78,164,299,432,439,445,457,782,805,1110,1336 'break':916 'break-glass':915 'brownfield':48,103,124,227,263,315,390,767,922,1200,1224,1330,1365 'brownfield-saf':47 'chang':1011,1087 'check':96,310,355,718,1391 'checkpoint':1082 'choos':379 'ci':93,189,360,502,509,1388 'ci-medi':359 'claim':1084 'clean':949 'clear':74,256,388,1106 'cli':149,650,697,875,1344 'cloud':14,505,512,862,1241,1364 'cloud-run-servic':1240 'commit':224,1169 'concern':58 'condit':691 'config':1203 'configur':10,333,530,554,661,808,1143,1372 'connect':845 'consid':1217 'contain':988 'convent':1338 'creat':4,424 'credenti':669,885,993 'current':1299 'cycl':342 'day':345 'decid':776 'decis':121 'decomposit':879 'dedic':116,397 'default':101,122,491,551,961,1029 'defin':428,543 'delet':925,1074 'deliveri':1380 'depend':1051 'deploy':161,481 'design':251 'desir':821 'destroy':1069 'destruct':340,1010 'dev':152,644,1245 'develop':494 'developer.hashicorp.com':1419,1422,1425,1428 'developer.hashicorp.com/terraform/language/import':1424 'developer.hashicorp.com/terraform/language/modules/develop/refactoring':1427 'developer.hashicorp.com/terraform/language/state/workspaces':1421 'developer.hashicorp.com/terraform/language/style':1418 'directori':31,142,425,639,1337 'directories/state':1114 'discoveri':794 'docs.cloud.google.com':1395,1398,1401,1404,1407,1410,1413,1416 'docs.cloud.google.com/docs/terraform/authentication':1406 'docs.cloud.google.com/docs/terraform/best-practices/general-style-structure':1394 'docs.cloud.google.com/docs/terraform/best-practices/operations':1400 'docs.cloud.google.com/docs/terraform/best-practices/root-modules':1397 'docs.cloud.google.com/docs/terraform/best-practices/testing':1403 'docs.cloud.google.com/docs/terraform/policy-validation/quickstart':1415 'docs.cloud.google.com/docs/terraform/resource-management/export':1409 'docs.cloud.google.com/docs/terraform/resource-management/import':1412 'document':914,1056,1126,1198,1208 'download':198 'drift':375 'earli':560 'edit':238,907 'embed':104 'enabl':1356 'enough':278 'entir':630 'env/root':147 'environ':139,179,271,368,409,635,702,882,1111,1244 'ephemer':217,607 'especi':11,365 'establish':485 'even':478 'everi':667 'exact':841 'exampl':864,868,1223 'except':1199 'exist':81,107,129,320,324,774,788,934 'explicit':113,544,1119,1145,1197 'export':321,787,938,1368 'export/import':229 'extern':587 'fals':693 'famili':100 'feder':515,970 'file':564,567,629,983,1268 'first':719,1022,1058 'fit':243 'flow':842 'fmt':349,722,1179,1382 'folder':138,1100 'follow':657 'four':56 'gcp':170,195,490,789,963,1281,1346 'gcs':172,518,1304,1353 'generat':330,807,940,992,1202,1371 'giant':165 'git':581 'gke':867 'glass':917 'googl':13,504,511,552,1141,1291,1306,1363 'google-beta':1140 'greenfield':287 'guardrail':871 'hand':237,906 'hand-edit':236,905 'handl':557,1134 'hardcod':221 'hashicorp/google':1293 'hcl':941,1284 'help':810 'helper':1046 'hidden':1049 'hide':1009 'histori':831 'iac':414 'id':1309,1317,1319 'ident':514,969 'imperson':501,966,1351 'implement':706 'import':323,332,784,797,801,930,1201,1369 'index':1325 'infra':398,1233 'infra/terraform':126,261,396 'infra/terraform/environments':419 'infrastructur':72,82,117,258,923,1050,1222 'init':725 'input':599,1128 'insid':105,127,1012 'instanc':668,681 'instead':338,547 'intent':371,679,1166,1302 'intern':403 'introduc':1025 'inventori':317 'involv':23,1159 'json':199,570,737 'justifi':756,1120 'keep':39,252,265,273,400,470,574,1094 'key':188,200,959 'lane':245,246,285,313,343 'layout':25,385,1093,1227,1326 'leav':1061 'let':1045 'lifecycl':1065,1193 'live':185,270,408 'local':175,180,493,497 'lockfil':374 'long':184 'long-liv':183 'low':716 'low-risk':715 'machin':744 'main.tf':1274 'make':241 'manag':214,584 'meant':1174 'mediat':361 'minim':1266 'minor':1300 'mix':131 'model':140,636,703 'modul':27,77,159,267,276,294,298,308,406,431,435,753,781,822,1000,1057,1103,1162,1214,1235,1312,1335,1357 'move':234,336,826,1205,1376 'multi':167,1148,1151 'multi-project':1147 'multi-region':1150 'multi-servic':166 'multipl':535 'must':603 'name':1322 'need':747 'network':463,1239,1248,1255,1262 'new':71 'non':980 'non-sensit':979 'normal':328,921 'offici':1392 'one':157,550,894 'oper':8,88,244,347,444 'otherwis':196 'output':601 'outputs.tf':1279 'outsid':510 'overload':549 'overview':34 'ownership':389,1107 'part':65 'path':769,933 'pattern':218,849,1348 'peer':683 'per':146,160,520 'pick':633 'pin':305,1165,1296,1358 'pipelin':764 'place':60,415 'placement':125,381,1332 'plain':1038 'plaintext':591 'plan':92,208,284,352,362,566,569,577,628,731,986,1021,1131,1186,1385 'plan/state':225 'platform':451,1078 'plus':215 'polici':95,354,741,1211,1360,1390 'pr':900 'prefer':212,260,358,458,582,1052 'preserv':387,829 'prevent':1068 'primari':701 'privileg':496 'prod':154,647,1259 'product':108,944 'production-readi':943 'project':536,1149,1237,1307,1316 'project-servic':1236 'project/bootstrap':464 'propos':710 'protect':1066,1075,1194 'provid':306,527,545,553,1053,1072,1137,1160,1290,1305 'provider-specif':1071 'provider/resource':616 'providers.tf':1275 'provis':70,288 'pull':856 'put':393,890 'quick':119 'radius':456 'read':420,522 'readi':945,1089 'readme.md':1280 'real':304 'recoveri':918 'recreat':927 'redact':605 'refactor':6,232,334,818,932,1374 'refer':120,861,1324,1393 'references/brownfield.md':837,838,1367 'references/gcp.md':523,524,1349 'references/layout.md':421,422,1329 'references/testing.md':759,760,1381 'region':537,1152,1310,1320 'reli':955 'remot':173,516,976 'renam':833 'rename/recreate':341 'repo':24,51,68,99,109,130,248,264,380,392,399,1033,1092,1226,1229,1331 'repositori':118 'requir':1286,1289 'resourc':325,542,790,1054,1063,1157,1191 'reus':302 'reusabl':266,297 'review':45,230,280,373,745,952,1006,1019 'right':64 'risk':717 'root':26,76,158,169,272,275,293,410,417,430,434,460,533,755,780,999,1102,1172,1267,1282,1334 'root-modul':75,429,779,1333 'root/environment':521 'run':348,713,863,1189,1242 'runtim':137,1099 'safe':49 'save':351,565,985,1017,1184,1384 'scaffold':816 'scope':257 'script':1047 'secret':213,222,583,588,592,989,1136 'select':804 'sensit':203,211,216,558,572,596,981,1127,1221 'separ':57,141,144,268,459,638,641,685,884,1112 'seri':1301 'servic':168,186,192,412,416,452,468,499,507,847,859,892,957,1238,1243,1251,1258,1265,1272,1313 'service-specif':411,846,858 'shape':665,823 'share':178,367,450,462,678,1004,1219,1247,1254,1261 'shared-network':1246,1253,1260 'shortcut':86 'show':736 'singl':899 'size':156 'skeleton':1283 'skill':37 'skill-terraform' 'skip':996 'small':43,277,292 'small-stat':42 'smallest':384 'sound':855 'sourc':589,1292,1314 'source-cofin' 'span':534 'specif':413,848,860,1073 'split':404,447,835 'src':134,1230 'stack':469 'stage':153,645,1252 'standard':1035 'start':289 'state':44,145,155,174,176,206,239,250,438,477,517,563,575,626,642,830,895,909,977,982,1062,1109,1129,1190 'stay':623 'step':377,426,483,555,631,704,765,843 'strategi':1124 'structur':853 'support':220,617,1079 'system':472,686,772,878 'take':84 'target':778,800 'terraform':1,9,21,33,40,54,61,89,132,253,327,394,562,649,721,724,727,730,735,749,852,908,1039,1086,1095,1178,1180,1185,1234,1285,1347,1386 'terraform.lock.hcl':18,312,997,1167 'terraform.tf':1276 'terraform.tfvars':1277 'terragrunt':1026 'terragrunt.hcl':19 'test':750,1215,1231,1378,1387 'text':1228,1269 'tf':17 'tfplan':733,738 'tfplan.json':739 'tfvar':594 'togeth':482 'token':990 'tool':742 'topic-agent-skills' 'topic-ai-agents' 'topic-beads' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-developer-tools' 'topic-gemini-cli' 'topic-opencode' 'topic-plugin' 'topic-slash-commands' 'topic-spec-driven-development' 'touch':901 'treat':53,205,440,561,812,937,975 'true':597,608,659 'understand':282 'unit':162 'unless':110,910,1031 'unrel':471,891 'unsaf':85 'upgrad':369 'use':2,35,148,382,595,606,637,648,696,758,825,836,874,1067,1113,1117,1192,1343 'user':112 'valid':91,350,708,728,763,1081,1181,1212,1361,1383 'valu':204,559,621 'var.name':1323 'var.project':1308,1318 'var.region':1311,1321 'variables.tf':1278 'verifi':1090 'version':309,370,1163,1177,1287,1294 'versus':30 'want':114 'wif':197,1352 'without':83,1064 'work':41,498 'workflow':22,376,1016 'workload':513,968 'workspac':29,150,651,698,876,1116,1328,1345 'write':526,611 'write-on':610","prices":[{"id":"ef6639dd-0e19-42d2-b46f-8a4154adee8a","listingId":"0b5687a7-1cc2-4462-88ef-a03d4fa6777f","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cofin","category":"flow","install_from":"skills.sh"},"createdAt":"2026-04-23T13:04:02.286Z"}],"sources":[{"listingId":"0b5687a7-1cc2-4462-88ef-a03d4fa6777f","source":"github","sourceId":"cofin/flow/terraform","sourceUrl":"https://github.com/cofin/flow/tree/main/skills/terraform","isPrimary":false,"firstSeenAt":"2026-04-23T13:04:02.286Z","lastSeenAt":"2026-04-24T07:03:20.643Z"}],"details":{"listingId":"0b5687a7-1cc2-4462-88ef-a03d4fa6777f","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cofin","slug":"terraform","github":{"repo":"cofin/flow","stars":11,"topics":["agent-skills","ai-agents","beads","claude-code","codex","context-driven-development","cursor","developer-tools","gemini-cli","opencode","plugin","slash-commands","spec-driven-development","subagents","tdd","workflow"],"license":"apache-2.0","html_url":"https://github.com/cofin/flow","pushed_at":"2026-04-19T23:22:27Z","description":"Context-Driven Development toolkit for AI agents — spec-first planning, TDD workflow, and Beads integration.","skill_md_sha":"b61a5b4648aac8b4c054db993f77304819c38031","skill_md_path":"skills/terraform/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cofin/flow/tree/main/skills/terraform"},"layout":"multi","source":"github","category":"flow","frontmatter":{"name":"terraform","description":"Use when creating, adopting, refactoring, or operating Terraform configurations, especially on Google Cloud. Applies to `*.tf`, `.terraform.lock.hcl`, `terragrunt.hcl`, and `terraform` workflows involving repo layout, root modules, backends/state, workspaces versus directories, brownfield import/export, CI plan/apply pipelines, testing, and policy validation."},"skills_sh_url":"https://skills.sh/cofin/flow/terraform"},"updatedAt":"2026-04-24T07:03:20.643Z"}}