A lightweight, zero-dependency Terraform/HCL parser CLI and library for TypeScript and Python.
Extracts and analyzes Terraform configuration blocks, builds dependency graphs, and outputs structured JSON/YAML — perfect for building IaC tooling, linters, documentation generators, and CI/CD integrations.
Node.js / TypeScript:
# npm
npm install -g parse-hcl
# yarn
yarn global add parse-hcl
# pnpm
pnpm add -g parse-hclPython:
# pip
pip install parse-hcl
# pipx (recommended for CLI)
pipx install parse-hcl
# uv
uv tool install parse-hcl# Parse a single Terraform file
parse-hcl --file main.tf
# Parse with YAML output
parse-hcl --file main.tf --format yaml
# Parse entire directory
parse-hcl --dir ./terraform
# Generate dependency graph
parse-hcl --file main.tf --graph
# Parse tfvars file
parse-hcl --file terraform.tfvars
# Parse Terraform state
parse-hcl --file terraform.tfstate
# Parse Terraform plan
parse-hcl --file plan.jsonparse-hcl --file <path> | --dir <path> [options]
| Option | Description | Default |
|---|---|---|
--file <path> |
Parse a single file (.tf, .tf.json, .tfvars, .tfstate, plan.json) |
- |
--dir <path> |
Parse all Terraform files in directory (recursive) | - |
--format <type> |
Output format: json or yaml |
json |
--graph |
Include dependency graph in output | false |
--no-prune |
Keep empty arrays/objects in output | false |
--out <path> |
Save output to file (or directory for combined output) | ./parse-hcl-output*.{json,yaml} |
--out-dir <dir> |
Save per-file results under this directory (directory mode) | ./parse-hcl-output/files |
--split / --no-split |
Enable/disable per-file saving in directory mode | true |
--stdout / --no-stdout |
Also print to stdout (default off) | false |
- You must provide either
--fileor--dir; when both are present,--fileis used. Missing inputs print usage to stderr and exit with code1. - Default output is files, stdout off.
- Single file: writes
./parse-hcl-output.{json|yaml}. - Directory: writes combined
./parse-hcl-output.combined.{json|yaml}and per-file under./parse-hcl-output/files/<relative-path>.{json|yaml}. - Add
--stdoutto also print.
- Single file: writes
--outoverrides the combined/single output path. If it points to a directory, the tool writesoutput.{json|yaml}(single file) orcombined.{json|yaml}(directory). If no extension is given, one is added based on--format.--out-dirsets the root for per-file outputs (directory mode). If omitted but--outis provided, per-file results go underper-file/next to the--outtarget. Disable per-file writes with--no-split.--fileauto-detects artifacts: paths containingtfvarsuse the tfvars parser,.tfstatefiles use the state parser, andplan.jsonuses the plan parser. Other files are treated as Terraform configs. The--graphflag only applies to Terraform configs; artifact parsers ignore it and return the raw parse.--dirrecursively parses only.tfand.tf.jsonfiles, skipping.terraform,.git, andnode_modules. The default output includescombined(aggregated document) andfiles(per-file results). With--graph, the dependency graph is built from the aggregated document.- When split outputs are written, each
filesentry now includesrelative_path,output_path, andoutput_dir(all relative). Module blocks includesource_raw(as written) and, when local,source_output_dir, pointing to the per-file output directory for that module. - Warnings and usage go to stderr. The CLI exits non-zero on invalid arguments or parsing failures.
--formataffects every output shape;--no-prunekeeps empty arrays/objects that are removed by default for compactness.
- Zero dependencies — No external runtime dependencies in both TypeScript and Python
- CLI-first design — Powerful command-line interface for instant Terraform analysis
- Dual language support — Feature-parity between TypeScript/Node.js and Python implementations
- Multiple file formats — Parses
.tf,.tf.json,.tfvars,.tfstate, andplan.json - Dependency graph — Automatically builds resource dependency graphs with reference tracking
- Flexible output — JSON and YAML serialization with optional pruning
- Expression analysis — Detects variables, locals, resources, data sources, and module references
- TypeScript/Node.js: typescript/README.md
- Python: python/README.md
Parse a Terraform file to JSON:
$ parse-hcl --file main.tf --format jsonOutput:
{
"resource": [
{
"type": "aws_s3_bucket",
"name": "demo",
"properties": {
"bucket": {
"type": "expression",
"kind": "template",
"raw": "${local.name_prefix}-bucket",
"references": [
{ "kind": "local", "name": "name_prefix" }
]
}
},
"meta": {
"count": { "type": "literal", "value": 2, "raw": "2" }
}
}
],
"variable": [...],
"output": [...],
"locals": [...]
}Generate dependency graph:
$ parse-hcl --file main.tf --graph --format jsonOutput:
{
"version": "1.0.0",
"document": { ... },
"graph": {
"nodes": [
{ "id": "resource.aws_s3_bucket.demo", "kind": "resource", "type": "aws_s3_bucket", "name": "demo" },
{ "id": "locals.name_prefix", "kind": "locals", "name": "name_prefix" },
{ "id": "output.bucket_name", "kind": "output", "name": "bucket_name" }
],
"edges": [
{ "from": "resource.aws_s3_bucket.demo", "to": "locals.name_prefix" },
{ "from": "output.bucket_name", "to": "resource.aws_s3_bucket.demo" }
]
}
}Parse tfvars file:
$ parse-hcl --file terraform.tfvarsOutput:
{
"source": "terraform.tfvars",
"assignments": {
"project": { "type": "literal", "value": "demo" },
"env": { "type": "literal", "value": "dev" },
"cidrs": {
"type": "array",
"value": [
{ "type": "literal", "value": "10.0.0.0/16" },
{ "type": "literal", "value": "10.1.0.0/16" }
]
}
}
}Parse entire directory:
$ parse-hcl --dir ./infrastructure --format yamlDefault saved outputs (no flags):
$ ls parse-hcl-output*
parse-hcl-output.combined.json
parse-hcl-output/files/main.tf.json
parse-hcl-output/files/modules/vpc/variables.tf.jsonDirectory output structure (--dir + --stdout):
$ parse-hcl --dir ./infrastructure --stdout | jq 'keys'
# ["combined","files"]{
"combined": { "resource": [...], "variable": [...], "output": [...], "locals": [...] },
"files": [
{
"path": "/abs/path/main.tf",
"document": { "resource": [...], "locals": [...], "output": [...], "terraform": [...] }
}
]
}| Block Type | Description |
|---|---|
resource |
Infrastructure resources with type, name, and properties |
data |
Data sources for querying external information |
variable |
Input variables with type constraints and defaults |
output |
Output values with sensitivity and descriptions |
locals |
Local values for intermediate computations |
module |
Module calls with source and version |
provider |
Provider configurations with aliases |
terraform |
Terraform settings (required_version, backend, etc.) |
moved |
Resource move/rename blocks |
import |
Import existing resources |
check |
Validation check blocks |
The parser automatically detects and classifies references in expressions:
| Reference Kind | Example | Detected As |
|---|---|---|
| Variable | var.region |
{ kind: "variable", name: "region" } |
| Local | local.prefix |
{ kind: "local", name: "prefix" } |
| Resource | aws_s3_bucket.demo.id |
{ kind: "resource", resource_type: "aws_s3_bucket", name: "demo", attribute: "id" } |
| Data | data.aws_ami.latest.id |
{ kind: "data", data_type: "aws_ami", name: "latest", attribute: "id" } |
| Module | module.vpc.subnet_ids |
{ kind: "module_output", module: "vpc", output: "subnet_ids" } |
| Path | path.module |
{ kind: "path", path_type: "module" } |
| Each | each.key |
{ kind: "each", property: "key" } |
| Count | count.index |
{ kind: "count" } |
| Self | self.id |
{ kind: "self", attribute: "id" } |
For detailed programmatic API usage and language-specific features:
- TypeScript/Node.js Documentation — Full TypeScript API, types, and examples
- Python Documentation — Full Python API, type hints, and examples
parse-hcl/
├── typescript/ # TypeScript/Node.js implementation
│ ├── src/
│ │ ├── cli.ts # CLI entry point
│ │ ├── services/ # Core parsers
│ │ ├── utils/ # Lexer, serialization, graph
│ │ └── types/ # Type definitions
│ └── test/
├── python/ # Python implementation
│ ├── src/parse_hcl/
│ │ ├── cli.py # CLI entry point
│ │ ├── services/ # Core parsers
│ │ ├── utils/ # Lexer, serialization, graph
│ │ └── types/ # Type definitions
│ └── tests/
└── docs/ # Internal documentation
- IaC Linters — Build custom Terraform linting rules
- Documentation Generators — Auto-generate docs from Terraform configs
- CI/CD Integration — Validate and analyze Terraform in pipelines
- IDE Extensions — Power code intelligence features
- Drift Detection — Compare configurations with state files
- Cost Estimation — Extract resource configurations for pricing
- Security Scanning — Analyze resource configurations for vulnerabilities
- Dependency Visualization — Generate architecture diagrams
# Clone repository
git clone https://github.com/sigmoid-hq/parse-hcl.git
cd parse-hcl
# TypeScript development
cd typescript
yarn install
yarn build
yarn test
# Python development
cd python
pip install -e .
python -m pytest tests/Apache-2.0 — Copyright 2025 Juan Lee
Contributions are welcome! Please feel free to submit issues and pull requests.