{"slug":"terraform-ops","title":"terraform-ops","summary":"Terraform and OpenTofu infrastructure-as-code operations - project layout, state management, module design, plan/apply safety, CI/CD pipelines, and secrets. Use for: terraform, opentofu, infrastructure as code, IaC, tfstate, terraform state, terraform module, remote backend, terr","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-09-30T19:36:58.233011Z","repo":{"url":"https://github.com/0xDarkMatter/claude-mods","stars":43,"forks":7,"license":"MIT","updatedAt":"2026-09-30T15:18:48Z"},"bodyHtml":"<hr>\n<h2>name: terraform-ops\ndescription: \"Terraform and OpenTofu infrastructure-as-code operations - project layout, state management, module design, plan/apply safety, CI/CD pipelines, and secrets. Use for: terraform, opentofu, infrastructure as code, IaC, tfstate, terraform state, terraform module, remote backend, terraform plan, terraform apply, for_each, moved block, terraform import, drift detection, tflint, checkov, HCL.\"\nlicense: MIT\nallowed-tools: \"Read Write Bash\"\nmetadata:\nauthor: claude-mods\nrelated-skills: ci-cd-ops, docker-ops, container-orchestration</h2>\n<h1>Terraform Operations</h1>\n<p>Terraform / OpenTofu infrastructure-as-code: layout, state, modules, safety, CI/CD, secrets.</p>\n<p><strong>Version context (verified 2026-06):</strong> Terraform <strong>1.15.x</strong> (BUSL-1.1 licence since 1.6) · OpenTofu <strong>1.12.x</strong> (MPL-2.0 fork of Terraform 1.5.x). Commands below are interchangeable (<code>terraform</code> ↔ <code>tofu</code>) unless flagged. See <a href=\"#terraform-vs-opentofu\">Terraform vs OpenTofu</a> for the decision note.</p>\n<h2>Reference Files</h2>\n<table>\n<thead>\n<tr>\n<th>File</th>\n<th>Covers</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><a href=\"references/state-management.md\">references/state-management.md</a></td>\n<td>Remote backends, locking, moved/import/removed blocks, state surgery, drift detection</td>\n</tr>\n<tr>\n<td><a href=\"references/module-patterns.md\">references/module-patterns.md</a></td>\n<td>Module composition, variable validation, optional/nullable, output contracts, versioning</td>\n</tr>\n<tr>\n<td><a href=\"references/cicd-pipelines.md\">references/cicd-pipelines.md</a></td>\n<td>GitHub Actions plan/apply, OIDC auth, policy gates (tflint/trivy/checkov/OPA), Atlantis/HCP</td>\n</tr>\n<tr>\n<td><a href=\"references/security-and-secrets.md\">references/security-and-secrets.md</a></td>\n<td>Secrets in state, ephemeral resources, write-only arguments, SOPS/Vault, sensitive limits</td>\n</tr>\n<tr>\n<td><a href=\"assets/github-actions-terraform.yml\">assets/github-actions-terraform.yml</a></td>\n<td>Ready-to-adapt PR-plan + OIDC-apply workflow</td>\n</tr>\n<tr>\n<td><a href=\"scripts/check-action-refs.sh\">scripts/check-action-refs.sh</a></td>\n<td>Staleness verifier for any workflow's <code>uses:</code> action refs (offline structural / live API resolve)</td>\n</tr>\n</tbody>\n</table>\n<blockquote>\n<p>The action versions pinned in <code>github-actions-terraform.yml</code> are <strong>point-in-time</strong> (verified 2026-06). Run <code>scripts/check-action-refs.sh --live</code> before adopting — a tag that was valid at write time may have been retracted or never existed (e.g. <code>trivy-action@0.33.1</code> vs the real <code>v0.33.1</code>).</p>\n</blockquote>\n<h2>Project Layout Decision Tree</h2>\n<pre><code>How many environments / accounts?\n│\n├─ One environment, one team\n│  └─ Single root module + tfvars. Don't over-engineer.\n│\n├─ Multiple environments (dev/staging/prod)\n│  ├─ Need different backend/account/region per env? (usually YES for prod isolation)\n│  │  └─ DIRECTORY PER ENVIRONMENT (recommended default)\n│  │     environments/{dev,staging,prod}/ each a thin root calling shared modules\n│  │\n│  └─ Environments truly identical except a few variables, same backend account?\n│     └─ Workspaces are *acceptable* — but see the workspace caveats below\n│\n└─ Many teams / many state files / platform engineering\n   └─ Directory-per-env + per-component state split (network / data / app)\n      Consider Terragrunt, Terraform Stacks (HCP), or OpenTofu + CI orchestration\n</code></pre>\n<h3>Canonical multi-env layout</h3>\n<pre><code>infra/\n├── modules/                  # Reusable child modules (no provider/backend blocks)\n│   ├── network/\n│   │   ├── main.tf\n│   │   ├── variables.tf\n│   │   ├── outputs.tf\n│   │   └── versions.tf       # required_providers ONLY (no provider config)\n│   └── app-service/\n├── environments/             # Root modules — one state file each\n│   ├── dev/\n│   │   ├── main.tf           # module \"network\" { source = \"../../modules/network\" ... }\n│   │   ├── backend.tf        # remote backend, env-specific key\n│   │   ├── providers.tf      # provider config lives in ROOT only\n│   │   ├── terraform.tfvars  # committed, non-secret env values\n│   │   └── versions.tf       # required_version + required_providers pins\n│   └── prod/\n└── .tflint.hcl\n</code></pre>\n<h3>Why directories usually beat workspaces</h3>\n<table>\n<thead>\n<tr>\n<th>Concern</th>\n<th>Directories</th>\n<th>Workspaces</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Separate backend/account per env</td>\n<td>Yes — each root has its own <code>backend.tf</code></td>\n<td>No — one backend, envs differ only by state key</td>\n</tr>\n<tr>\n<td>Blast radius of wrong-env apply</td>\n<td>Low — you're physically in <code>prod/</code></td>\n<td>High — invisible <code>terraform workspace select</code> state</td>\n</tr>\n<tr>\n<td>Env-specific config divergence</td>\n<td>Natural (different main.tf if needed)</td>\n<td><code>terraform.workspace</code> conditionals creep everywhere</td>\n</tr>\n<tr>\n<td>Prod IAM isolation</td>\n<td>Per-dir CI role</td>\n<td>Same credentials see all envs</td>\n</tr>\n<tr>\n<td>Visibility in code review</td>\n<td>Diff shows which env changed</td>\n<td>Workspace is runtime state, not in the diff</td>\n</tr>\n</tbody>\n</table>\n<p>Workspaces fit short-lived ephemeral copies (PR preview envs) — not the dev/prod boundary. HashiCorp's own docs say workspaces are \"not suitable for strong separation.\"</p>\n<h3>tfvars conventions</h3>\n<pre><code>terraform.tfvars            # auto-loaded — per-root committed defaults (non-secret)\n*.auto.tfvars               # auto-loaded — generated/local overrides\nprod.tfvars                 # explicit only: terraform plan -var-file=prod.tfvars\nTF_VAR_db_password=...      # env var injection — secrets in CI, never in files\n</code></pre>\n<p>Gotcha: <code>-var-file</code> + directories-per-env is belt-and-braces; with workspaces it's load-bearing and one forgotten flag applies dev values to prod.</p>\n<h2>State Quick Reference</h2>\n<p>Full detail: <a href=\"references/state-management.md\">references/state-management.md</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Task</th>\n<th>Command / block</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Remote backend (AWS)</td>\n<td><code>backend \"s3\" { bucket, key, region, use_lockfile = true }</code></td>\n<td>S3-native locking (TF ≥1.10) — DynamoDB table no longer required</td>\n</tr>\n<tr>\n<td>Rename resource in code</td>\n<td><code>moved { from = aws_x.a, to = aws_x.b }</code></td>\n<td>Declarative, reviewable, no CLI surgery</td>\n</tr>\n<tr>\n<td>Adopt existing infra</td>\n<td><code>import { to = aws_x.a, id = \"i-123\" }</code> + <code>plan -generate-config-out=gen.tf</code></td>\n<td>Config-driven import (TF ≥1.5) beats <code>terraform import</code> CLI</td>\n</tr>\n<tr>\n<td>Forget without destroy</td>\n<td><code>removed { from = aws_x.a, lifecycle { destroy = false } }</code></td>\n<td>TF ≥1.7; OpenTofu 1.12 also has <code>lifecycle { destroy = false }</code> on resources</td>\n</tr>\n<tr>\n<td>Drift detection</td>\n<td><code>terraform plan -detailed-exitcode</code></td>\n<td>Exit 0 = clean, 1 = error, <strong>2 = drift</strong> — cron it</td>\n</tr>\n<tr>\n<td>Inspect state</td>\n<td><code>terraform state list</code> / <code>state show ADDR</code></td>\n<td>Read-only, always safe</td>\n</tr>\n<tr>\n<td>Move state (last resort)</td>\n<td><code>terraform state mv SRC DST</code></td>\n<td>Prefer <code>moved</code> blocks — see \"when NOT to\" below</td>\n</tr>\n<tr>\n<td>Pull/push (emergency)</td>\n<td><code>terraform state pull &gt; backup.tfstate</code></td>\n<td>ALWAYS pull a backup before any surgery</td>\n</tr>\n</tbody>\n</table>\n<p><strong>State surgery — when NOT to:</strong> if a <code>moved</code>/<code>removed</code>/<code>import</code> block can express it, use the block. CLI <code>state mv</code>/<code>rm</code> is immediate, unreviewed, unversioned, and a typo orphans real infrastructure. Legit uses: splitting state between roots, unwedging a failed migration. Always <code>state pull</code> a backup first.</p>\n<h2>Module Quick Reference</h2>\n<p>Full detail: <a href=\"references/module-patterns.md\">references/module-patterns.md</a>.</p>\n<pre><code>module \"network\" {\n  source  = \"terraform-aws-modules/vpc/aws\"\n  version = \"~&gt; 6.0\"          # pin minor-float for registry modules; exact pin in prod roots\n  # ...\n}\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>Rule</th>\n<th>Why</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Composition over inheritance</td>\n<td>Roots compose flat modules; never module-wraps-module-wraps-module</td>\n</tr>\n<tr>\n<td>No provider blocks in child modules</td>\n<td>Providers configured in root only; child declares <code>required_providers</code></td>\n</tr>\n<tr>\n<td><code>validation</code> blocks on variables</td>\n<td>Fail at plan with a real message, not mid-apply</td>\n</tr>\n<tr>\n<td><code>optional(type, default)</code> in object attrs</td>\n<td>Callers omit fields; <code>nullable = false</code> rejects explicit null</td>\n</tr>\n<tr>\n<td>Outputs are the contract</td>\n<td>Output IDs/ARNs consumers need; document with <code>description</code></td>\n</tr>\n<tr>\n<td><strong>Anti-pattern: thin wrappers</strong></td>\n<td>A module that just renames variables of another module adds a version-lag layer and zero value — call the upstream module directly</td>\n</tr>\n</tbody>\n</table>\n<h2>Safety Checklist (before every apply)</h2>\n<pre><code>□ plan output READ, not skimmed — every destroy/replace explained\n□ \"Plan: X to add, Y to change, Z to destroy\" — does Z surprise you?\n□ -/+ (replace) lines: check the \"forces replacement\" attribute\n□ Applying the SAME saved plan that was reviewed: plan -out=tfplan → apply tfplan\n□ prevent_destroy on stateful resources (db, state bucket, KMS keys)\n□ Cloud-side deletion protection too (RDS deletion_protection, S3 versioning+MFA-delete)\n□ No -target unless this is a declared emergency (see below)\n□ for_each (stable keys), not count, for any collection that can reorder\n</code></pre>\n<h3>Footguns</h3>\n<table>\n<thead>\n<tr>\n<th>Footgun</th>\n<th>Detail</th>\n<th>Fix</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>count</code> index shift</td>\n<td>Removing item 0 of a <code>count</code> list re-addresses every later item → destroy/recreate cascade</td>\n<td><code>for_each</code> with stable string keys</td>\n</tr>\n<tr>\n<td><code>-target</code> habit</td>\n<td>Skips dependency graph; state diverges from config; hides drift</td>\n<td>Emergency-only (broken dependency cycle, partial outage). Follow with a full clean plan</td>\n</tr>\n<tr>\n<td><code>prevent_destroy</code> false comfort</td>\n<td>Doesn't survive the block being deleted, and doesn't stop <code>state rm</code> + console delete</td>\n<td>Pair with cloud-native deletion protection</td>\n</tr>\n<tr>\n<td>Dynamic blocks everywhere</td>\n<td><code>dynamic</code> for 2 static blocks is obfuscation</td>\n<td>Use <code>dynamic</code> only over genuinely variable collections</td>\n</tr>\n<tr>\n<td>Unpinned providers</td>\n<td><code>aws = \"&gt;= 5.0\"</code> in prod pulls a breaking major the day it ships</td>\n<td><code>~&gt; 6.12</code> + commit <code>.terraform.lock.hcl</code></td>\n</tr>\n<tr>\n<td>Apply ≠ reviewed plan</td>\n<td>Plan on PR, apply on merge re-plans — drift in between applies unreviewed changes</td>\n<td>Save the plan artifact, or accept + re-review the merge plan</td>\n</tr>\n</tbody>\n</table>\n<pre><code>resource \"aws_db_instance\" \"main\" {\n  deletion_protection = true            # cloud-side\n  lifecycle {\n    prevent_destroy = true              # terraform-side\n    ignore_changes  = [password]        # if rotated outside TF\n  }\n}\n</code></pre>\n<h2>CI/CD Quick Reference</h2>\n<p>Full detail: <a href=\"references/cicd-pipelines.md\">references/cicd-pipelines.md</a> · template: <a href=\"assets/github-actions-terraform.yml\">assets/github-actions-terraform.yml</a>.</p>\n<pre><code>PR opened   → fmt -check → validate → tflint → trivy/checkov → plan → plan posted as PR comment\nPR merged   → plan (fresh) → apply, authenticated via OIDC — no long-lived cloud keys\nNightly     → plan -detailed-exitcode → exit 2 ⇒ drift alert\n</code></pre>\n<ul>\n<li><strong>OIDC everywhere</strong> — <code>aws-actions/configure-aws-credentials</code> with <code>role-to-assume</code>, never <code>AWS_ACCESS_KEY_ID</code> secrets. Same supply-chain doctrine as this repo's rules: short-lived tokens, no standing credentials.</li>\n<li><strong>Pin action SHAs</strong> in workflows (<code>uses: actions/checkout@&lt;sha&gt;</code>), not floating tags.</li>\n<li>Policy gates: <code>tflint</code> (provider-aware lint), <code>trivy config</code> / <code>checkov</code> (misconfig scan), OPA/<code>conftest</code> for org policy (\"no public buckets\").</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Orchestrator</th>\n<th>Fit</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Plain GitHub Actions</td>\n<td>Default — full control, free, template in assets/</td>\n</tr>\n<tr>\n<td>Atlantis</td>\n<td>Self-hosted PR automation, <code>atlantis plan/apply</code> comments, locking per dir</td>\n</tr>\n<tr>\n<td>HCP Terraform / Terraform Cloud</td>\n<td>Managed runs, Sentinel policy, state hosting; free ≤500 resources</td>\n</tr>\n<tr>\n<td>Spacelift / env0 / Digger / Scalr</td>\n<td>Commercial Atlantis-likes; Digger runs inside your Actions</td>\n</tr>\n</tbody>\n</table>\n<h3>Verification — <code>uses:</code> ref staleness</h3>\n<p>GitHub Action versions rot: a tag gets retracted, or a workflow pins one that never existed. <a href=\"scripts/check-action-refs.sh\">scripts/check-action-refs.sh</a> lints every <code>uses: owner/repo@ref</code> line. It's <strong>general</strong> — pass any workflow file(s) as positionals (default: this skill's own <code>assets/github-actions-terraform.yml</code>).</p>\n<pre><code># Structural only, no network — well-formedness of every uses: ref (CI-safe gate).\n# Floating @main/@master → WARN (exit 0; use --strict to fail). Malformed → exit 4.\nscripts/check-action-refs.sh --offline .github/workflows/ci.yml\n\n# Live — resolve each ref against the GitHub API. A 404 (ref doesn't exist) → exit 10\n# DRIFT; API unreachable/rate-limited → exit 7 (advisory, never fails the build, §7).\n# Set GITHUB_TOKEN to dodge the unauthenticated rate limit.\nGITHUB_TOKEN=$GH_PAT scripts/check-action-refs.sh --live .github/workflows/*.yml\n\nscripts/check-action-refs.sh --json --offline | jq '.data[] | select(.status!=\"ok\")'\n</code></pre>\n<p><code>--live</code> is the check that catches the classic <code>aquasecurity/trivy-action@0.33.1</code> mistake — that tag 404s; the real one is <code>v0.33.1</code>. Run live on a schedule (never as a blocking PR gate), offline in PR CI.</p>\n<h2>Testing Quick Reference</h2>\n<pre><code># tests/network.tftest.hcl  — native test framework (TF ≥1.6 / OpenTofu ≥1.6)\nvariables { cidr = \"10.0.0.0/16\" }\n\nrun \"valid_cidr_plan\" {\n  command = plan                          # plan = fast unit-ish; apply = real integration\n  assert {\n    condition     = aws_vpc.main.cidr_block == \"10.0.0.0/16\"\n    error_message = \"VPC CIDR did not match input\"\n  }\n}\n\nrun \"rejects_tiny_cidr\" {\n  command = plan\n  variables { cidr = \"10.0.0.0/30\" }\n  expect_failures = [var.cidr]            # asserts the validation block fires\n}\n</code></pre>\n<p><code>terraform test</code> runs every <code>*.tftest.hcl</code> under <code>tests/</code>; <code>command = apply</code> runs create real (then auto-destroyed) infra — use a sandbox account. Mock providers (<code>mock_provider</code> blocks, TF ≥1.7) fake apply without credentials. For multi-tool/Go-level orchestration (retry, real HTTP probes), Terratest is the heavyweight alternative — native <code>terraform test</code> covers most module CI needs first.</p>\n<h2>Secrets Quick Reference</h2>\n<p>Full detail: <a href=\"references/security-and-secrets.md\">references/security-and-secrets.md</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Mechanism</th>\n<th>Version</th>\n<th>What it does</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>sensitive = true</code></td>\n<td>all</td>\n<td>Redacts from CLI output <strong>only</strong> — value still plaintext in state</td>\n</tr>\n<tr>\n<td>Ephemeral resources (<code>ephemeral \"...\"</code>)</td>\n<td>TF ≥1.10 / OpenTofu ≥1.11</td>\n<td>Fetch secret at run time; never persisted to state or plan</td>\n</tr>\n<tr>\n<td>Write-only arguments (<code>password_wo</code>)</td>\n<td>TF ≥1.11 / OpenTofu ≥1.11</td>\n<td>Send secret to provider; never stored in state; rotate via <code>_wo_version</code></td>\n</tr>\n<tr>\n<td>SOPS-encrypted tfvars</td>\n<td>tool</td>\n<td>Secrets encrypted at rest in git; decrypted at plan time</td>\n</tr>\n<tr>\n<td>Vault / cloud secret manager</td>\n<td>tool</td>\n<td>Reference by ID; resource reads secret at boot, TF never sees it</td>\n</tr>\n<tr>\n<td>OpenTofu state encryption</td>\n<td>OpenTofu ≥1.7</td>\n<td>Client-side AES-GCM encryption of state/plan — <strong>no Terraform equivalent</strong></td>\n</tr>\n</tbody>\n</table>\n<p><strong>Rule zero: treat state as secret regardless.</strong> Encrypt the backend (SSE-KMS), restrict IAM on the bucket, never commit <code>*.tfstate</code> (gitignore it).</p>\n<h2>Terraform vs OpenTofu</h2>\n<table>\n<thead>\n<tr>\n<th></th>\n<th>Terraform</th>\n<th>OpenTofu</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Licence</td>\n<td><strong>BUSL-1.1</strong> since 1.6 (no production use <em>competing with HashiCorp</em>; fine for normal internal use)</td>\n<td><strong>MPL-2.0</strong> — genuinely open source, Linux Foundation</td>\n</tr>\n<tr>\n<td>Current</td>\n<td>1.15.x</td>\n<td>1.12.x</td>\n</tr>\n<tr>\n<td>Exclusive features</td>\n<td>Stacks (HCP-tied), Terraform Cloud agents, <code>terraform query</code></td>\n<td>State/plan <strong>encryption</strong>, provider <code>for_each</code> iteration, <code>-exclude</code> flag, early variable eval in backend/module blocks, OCI registry distribution, <code>.tofu</code> file extension</td>\n</tr>\n<tr>\n<td>Registry</td>\n<td>registry.terraform.io</td>\n<td>registry.opentofu.org (mirrors most providers)</td>\n</tr>\n<tr>\n<td>Compatibility</td>\n<td>—</td>\n<td>Forked at 1.5.x; HCL/state compatible for mainstream use, diverging feature-by-feature since</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Decision:</strong> vendors and anyone redistributing IaC tooling commercially → OpenTofu (licence risk). Teams on HCP Terraform/Sentinel → Terraform. Everyone else: either works; OpenTofu's state encryption is the single biggest technical differentiator. Migration <code>terraform → tofu</code> is <code>tofu init</code> + state-compatible up to ~1.8-era features; the gap widens each release — migrate early or commit.</p>\n<h2>Command Quick Reference</h2>\n<pre><code>terraform init -upgrade               # init / upgrade providers within constraints\nterraform fmt -recursive -check       # CI: fail on unformatted\nterraform validate                    # syntax + internal consistency (no creds needed after init)\nterraform plan -out=tfplan            # save plan for exact-apply\nterraform show -json tfplan | jq      # machine-readable plan (policy tools eat this)\nterraform apply tfplan                # apply EXACTLY the reviewed plan\nterraform plan -detailed-exitcode     # 0 clean / 2 drift — for cron drift checks\nterraform plan -refresh-only          # show drift without proposing config changes\nterraform apply -replace=aws_x.a      # force recreate one resource (replaces old taint)\nterraform state pull &gt; backup.json    # ALWAYS before surgery\nterraform output -json                # consume outputs in scripts\nterraform graph | dot -Tsvg &gt; g.svg   # dependency graph\ntofu init                             # OpenTofu: same verbs throughout\n</code></pre>\n","files":[{"path":"assets/github-actions-terraform.yml","sizeBytes":8867,"isText":true},{"path":"references/cicd-pipelines.md","sizeBytes":9757,"isText":true},{"path":"references/module-patterns.md","sizeBytes":9496,"isText":true},{"path":"references/security-and-secrets.md","sizeBytes":8502,"isText":true},{"path":"references/state-management.md","sizeBytes":9493,"isText":true},{"path":"scripts/check-action-refs.sh","sizeBytes":12084,"isText":true},{"path":"scripts/.gitkeep","sizeBytes":0,"isText":false},{"path":"SKILL.md","sizeBytes":16597,"isText":true},{"path":"tests/run.sh","sizeBytes":3573,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-30T19:39:18.100073Z","sha256":"0E400595A008C88B09FEF489797EE8D25E91C73250DABF4483E3B67F5A7E87AC","sizeBytes":34366},"review":null,"source":{"repositoryUrl":"https://github.com/0xDarkMatter/claude-mods","path":"skills/terraform-ops","license":"MIT","commit":"3dfaf0ba5753026a99ee13f9d9ed56b9793bb6e8","subtreeSha":"8877070ED662A98FF7652F2F0B7472CFEF234A4127C707C2AA0B4A4BE3832620","lastSyncedAt":"2026-09-30T19:37:28.226022Z"},"reviewedAt":"2026-09-30T19:43:37.945083Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/0xDarkMatter/claude-mods/tree/main/skills/terraform-ops"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install 0xdarkmatter-claude-mods@llmmart"},{"target":"git","command":"git clone https://github.com/0xDarkMatter/claude-mods.git"}]}