Skip to content
Back to skills

Terraform Registry

ASecurity

Search and inspect the Terraform Registry through its JSON API for any provider (AWS, azurerm, google, Kubernetes, GitLab and others): find modules by keyword, read a module's inputs, outputs and versions, or a resource type's attributes, without scraping pages. Use whenever current Terraform module or provider facts are needed for writing or reviewing IaC.

  • 7 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 3, 2026
ai-agentspythongoshellbashkubernetesawsazureterraformgitapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 8 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add kevin-burns/claude-skills --skill terraform-registry --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Terraform Registry?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Terraform Registry
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/kevin-burns-terraform-registry/badge)](https://www.skillsdirectory.com/skills/kevin-burns-terraform-registry)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: terraform-registry
description: >-
  Search and inspect the Terraform Registry through its JSON API for any provider (AWS, azurerm, google, Kubernetes, GitLab and others): find modules by keyword, read a module's inputs, outputs and versions, or a resource type's attributes, without scraping pages. Use whenever current Terraform module or provider facts are needed for writing or reviewing IaC.
license: MIT
---

# terraform-registry

A self-contained CLI (`registry_helper.py`, stdlib-only) that queries the Terraform
Registry's JSON API directly. It exists so an agent can get **accurate, current**
module/provider facts deterministically — fetch the structured payload, filter to the
slice you need, return that. No HTML, no full-text crawl, no page-dump into context.

## Running the helper

Call the script by its **absolute path** — never a bare relative one. It sits next to this
SKILL.md, in the base directory announced when the skill loads (usually
`~/.claude/skills/terraform-registry`, or a plugin path if installed that way). You'll normally
be working inside some *other* repo, so a bare `registry_helper.py` won't resolve and the
script never runs. Define a `tfreg` shell function at the **start of each command block**, then
call it. Two deliberate choices: a function (not a `VAR="…"; $VAR` string) passes arguments
correctly under both bash and zsh — a plain `$VAR` doesn't word-split in zsh — and the name
`tfreg` avoids colliding with the `terraform` CLI. Shell state doesn't persist between separate
tool calls, so re-declare `tfreg` in every block (or write the full `uv run python <path> …`).

```bash
# uv is the preferred runner. Resolve it even when it isn't on a bare PATH — non-interactive
# shells often drop ~/.local/bin or the Homebrew bin, which is the usual cause of
# `uv: command not found`:
UV="$(command -v uv || ls "$HOME/.local/bin/uv" "$HOME/.cargo/bin/uv" /opt/homebrew/bin/uv /usr/local/bin/uv 2>/dev/null | head -1)"
tfreg() { "$UV" run python "$HOME/.claude/skills/terraform-registry/registry_helper.py" "$@"; }   # use the announced base dir
tfreg search vpc --provider aws --limit 5   # confirms the runner + path resolve
```

The script is stdlib-only, so if (and only if) uv is genuinely not installed you can swap the
runner for plain python3 — same arguments:
`tfreg() { python3 "$HOME/.claude/skills/terraform-registry/registry_helper.py" "$@"; }`.

If a call fails with `command not found` (uv unresolved) or `No such file or directory` (wrong
path), fix the runner/path — re-resolve uv as above, or use the announced base directory. Don't
fall back to scraping registry.terraform.io's HTML: this client returns the registry's JSON
directly, which is the entire point.

## Two data planes (important)

| You want | Source | Command |
|---|---|---|
| Find a module / its inputs, outputs, versions | Registry **v1 JSON API** (provider-agnostic) | `search`, `inspect-module` |
| A resource type's attributes (e.g. `aws_s3_bucket`) | **`terraform providers schema -json`** dump (the registry API does **not** serve schemas) | `refresh-schema`, then `inspect-resource` |

The module side works for any provider with no special-casing — the provider is just a
path/query parameter. The resource-schema side needs the `terraform` CLI once to cache a
provider's schema; after that, lookups are offline.

## Commands

`tfreg` is the function defined in *Running the helper* above — re-declare it at the top of the
block if this is a fresh command (shell state doesn't carry over between tool calls).

```bash
# Search modules (any provider). --provider/--namespace narrow it; --limit caps results.
tfreg search vpc --provider aws --limit 5
tfreg search network --provider google
tfreg search keyvault --provider azurerm

# Inspect a module: namespace/name/provider[/version]. Project + filter to stay small.
tfreg inspect-module terraform-aws-modules/vpc/aws --fields inputs --filter name~cidr
tfreg inspect-module Azure/avm-res-keyvault-vault/azurerm --fields meta,outputs

# Resource attributes (needs a cached schema first):
tfreg refresh-schema --provider google --namespace hashicorp
tfreg inspect-resource google_storage_bucket --filter name~location
```

### Token-efficiency levers
- `--fields inputs,outputs,versions,meta` — return only the sections you need.
- `--filter name~<substr>` — keep only inputs/outputs/attributes whose name matches.
- These run **locally on the fetched payload**, so you pay tokens only for the slice.

## Determinism & caching (the source-snapshot pattern)

Every fetch is written to an on-disk snapshot cache (`--cache-dir`, default
`~/.cache/terraform-registry`) and re-read on the next call.

- `--offline` — use the cache only; never touch the network. Errors if a payload isn't cached.
- `--refresh` — bypass the cache and re-fetch (then re-cache).
- Pin behavior by inspecting a specific version (`.../aws/5.8.1`) and committing the cached
  payload — that snapshot becomes a stable, citable fact. See the `source-snapshot` skill.

## Output contract

`--format json` (for agents) emits a stable envelope:

```json
{ "ok": true, "command": "...", "data": {...},
  "provenance": { "source_url": "...", "source_kind": "registry_module_api|terraform_provider_schema",
                  "retrieved_at": "...", "cached": true },
  "warnings": [], "error": null }
```

`--format text` (default) is human-readable. Exit codes: `0` ok · `1` not-found · `2`
usage · `3` network/registry error. On error with `--format json`, `ok` is `false` and
`error` carries `{message, code}`.

## How it fits the fleet

- A concrete **producer** for the `source-snapshot` skill (its cached payloads are the
  snapshots).
- A **tier-1/2 source** for the `fact-verifier` agent: it can cite a module input or a
  resource attribute from a cached payload — deterministically and offline — instead of
  guessing or scraping.
- Keep project-specific logic (catalog audit, scaffolding, org conventions) in your
  project repo and have it call this generic client.

## Scope

This is the generic registry client only. It does not edit code, write Terraform, or
apply anything — it reads the registry and returns facts. Tests: `evals/` (offline,
deterministic, multi-provider) — `cd evals && uv run python grade.py`.

Files in this skill

  • README.md3.5 KB
  • SKILL.md6.5 KB
  • evals/eval.json2.1 KB
  • evals/fixtures/cache/v1_modules_Azure_avm-res-keyvault-vault_azurerm.json1.2 KB
  • evals/fixtures/cache/v1_modules_search__limit=5&provider=aws&q=vpc.json1007 B
  • evals/fixtures/cache/v1_modules_terraform-google-modules_network_google.json1.1 KB
  • evals/grade.py3.3 KB
  • registry_helper.py16.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…