IaCLineage
Explore Terraform declarations and trace their source references from a local checkout. IaCLineage provides a Python CLI and a self-contained HTML report with searchable declarations, field-level lineage, and source locations.
No Terraform execution, cloud credentials, server, or network access is required to analyze source or open a report. The current version is 0.1.0.
Installation
Requires Python 3.12 or newer. Install from PyPI:
pip install iaclineage
iaclineage --version
To upgrade an existing installation, run pip install --upgrade iaclineage.
To explicitly select the latest beta, add --pre to the upgrade command.
Cloning this repository is only needed for source development.
See the tester guide for TestPyPI installation and the platform guide for Windows, Linux, and macOS setup.
Quick start
Point the CLI at a Terraform root module. Replace these paths with directories on your machine; the output directory must already exist.
If the project uses registry or remote modules, download their source before running IaCLineage. Run this inside each Terraform project root:
cd /path/to/terraform
terraform get
terraform get
requires Terraform and any credentials needed to download private modules.
Keep the default .terraform/modules cache. If the required modules are already
downloaded, this step is unnecessary. Projects using only local modules can skip it.
Then inspect the project:
iaclineage scan /path/to/terraform
iaclineage find /path/to/terraform aws_vpc.main
iaclineage report /path/to/terraform --format interactive-html --output /path/to/reports/lineage.html
Open lineage.html locally in Chrome or Edge. Select a declaration, choose a
field, then trace Upstream, Downstream, or Both. References include
the consuming field, target, resolution status, and source range. The report
works offline and can be shared as a single file.
Local module calls are followed automatically, including relative paths outside
the scanned directory. IaCLineage reads downloaded modules through
.terraform/modules/modules.json; it never runs Terraform or downloads modules.
Missing remote-module source produces IAC103 diagnostics and leaves references
into those modules unresolved. The available local source can still be inspected.
Find declarations
find accepts a full IaCLineage address, a standard Terraform resource address,
var.NAME for a variable, or a declaration's final name. Exact full addresses
take precedence.
iaclineage find . aws_vpc.main
iaclineage find . resource.aws_vpc.main
iaclineage find . main
iaclineage find . var.region
iaclineage find . provider.aws.west
iaclineage find . aws --format json
iaclineage find . aws_vpc.main --format json --output /path/to/results.json
Provider aliases have distinct addresses: provider.aws and
provider.aws.west. Searching aws lists matching provider configurations.
Explicit provider = aws.west bindings on resources, data sources, and imports
link to the declared provider. Duplicate target addresses remain ambiguous.
Child-module addresses include the call path, such as
module.network.resource.aws_vpc.main; module.network.aws_vpc.main also works
with find. Scanning a directory with no root .tf files discovers independent
projects beneath it, each with a prefix such as production::.
Text and JSON use the same search exit codes:
| Result | Exit code | JSON shape |
|---|---|---|
| One match | 0 |
{ "query": "...", "match": { ... } } |
| Multiple matches | 1 |
{ "query": "...", "matches": [ ... ] } |
| No match | 1 |
{ "error": "no match", "query": "..." } |
Multiple matches include every declaration and its location. Refine the query
when possible. Progress and diagnostics go to stderr, leaving stdout suitable
for JSON consumers. Use --color never before the command to disable color.
Trace lineage
trace follows references from one declaration across files and modules. It
accepts the same queries as find.
iaclineage trace . output.app_id --direction up
iaclineage trace . variable.region --direction down --depth 2
iaclineage trace . aws_vpc.main --format json --output /path/to/trace.json
--direction up follows what the declaration uses, down follows what uses
it, and both (the default) prints both lists. Each hop shows its depth, the
two declarations, the edge kind, the resolution state, the source range of the
reference, and the field or module argument that holds it. A -> B always means A uses B. --depth N stops after N hops;
without it the trace continues until nothing new is reachable, and a cycle is
listed once instead of being followed again.
When a trace passes through a module call, it continues only through the
argument it arrived by and to readers of the whole module, so tracing one input
does not pull in the module's other inputs. A reference to the whole module
object, such as module.app, module.app[*].id, or depends_on = [module.app], connects the call to its outputs with a module-output hop. A
trace stops at unresolved targets. It works on whole declarations; to narrow a
trace to one field, use the interactive report. Like find, trace exits 1
when the query does not match exactly one declaration.
Reports
# Interactive explorer
iaclineage report . --format interactive-html --output /path/to/reports/lineage.html
# Static HTML summary (the default format)
iaclineage report . --output /path/to/reports/summary.html
# Structural JSON
iaclineage report . --format json --output /path/to/reports/lineage.json
Reports exclude raw source values by default. To inspect source in a trusted
local interactive report, use --include-source-values:
# Interactive report with raw source values
iaclineage report . --format interactive-html --include-source-values --output /path/to/reports/lineage-with-source.html
This option is available only with --format interactive-html. The resulting
file can contain secrets, comments, and literal values; review it before sharing.
Keep report files outside scanned repositories and followed modules.
The interactive report includes declaration and field search, project and kind filters, module input/output connections, conditional evidence, and a resizable lineage workspace. See the interactive report guide for controls and tracing behavior.
Unused declarations
unused lists variables, locals, and child-module outputs that no expression
references:
iaclineage unused /path/to/terraform
Each line gives the address, kind, and source location. The command exits 1
when it finds anything and 0 when it finds nothing, so it can run in CI.
A variable counts as unused when a module call sets it but nothing inside the
module reads it. References from a variable's own validation block do not
count. A reference to a whole module object, such as module.app or
module.app[*].id, uses all of that module's outputs; depends_on and moved
blocks do not. When several calls share one module source, a declaration in it
is reported only if no call uses it. Root module outputs are skipped because
they are read from outside the configuration, and so are declarations inside
downloaded modules under .terraform. IaCLineage only sees static references,
so check each result before deleting it.
CI checks
report --fail-on writes the report as usual, then exits 1 if any reference
has one of the listed resolution states:
iaclineage report . --format json --output /path/to/reports/lineage.json --fail-on unresolved,ambiguous
Accepted states are unresolved and ambiguous. References into remote modules
whose source has not been downloaded stay unresolved, so run terraform get
first when the configuration uses them. Provider aliases that a child module
receives through a providers map also stay unresolved, because IaCLineage does
not follow those mappings. Attribute names in lifecycle { ignore_changes = [...] } and the old address in a moved block's from are reported as
unresolved too.
Use with coding agents
The skills/iaclineage folder is an agent skill. It tells coding agents such as
Claude Code and Codex when to run IaCLineage, which commands answer which
questions, and how to read the results. Install it with the
skills CLI:
npx skills add mayurmhjn/iaclineage
The skill does not install IaCLineage itself. Install the CLI as described in Installation.
Analysis scope
- Analyzes
.tfsource using a parser; does not read plan/state JSON or evaluate Terraform. - Resolves declarations and static references across local and installed modules.
- Treats dynamic-block and comprehension iterators as local symbols. Built-ins
such as
terraform.workspace,path.module,each, andcountdo not create entity edges. - Keeps references in iterator collections and other external expressions. Iterator values themselves are not evaluated or expanded into infrastructure instances.
- Reports missing module sources and parse recovery as diagnostics. Unresolved references remain visible; source resolution does not verify provider-computed values.
- Does not resolve implicit provider inheritance or module
providersmappings. CustomTF_DATA_DIRand remote state resolution are unsupported.
A missing source reference does not prove runtime independence. Tracing stops at expression and instance-selection boundaries. Installed module snapshots also do not prove cache freshness or version-constraint satisfaction.
Development
uv sync --locked --group dev
uv run --no-sync pytest
node --test tests/test_lineage_ui.cjs
npm ci --ignore-scripts
npm run test:browser
Node and Playwright are developer tools only. Browser setup and native-platform checks are documented in the platform guide. See CONTRIBUTING.md for contribution guidelines and CHANGELOG.md for release notes.
Report bugs through GitHub Issues with the installed version and a synthetic example. Report security issues privately as described in SECURITY.md.
Licensed under Apache License 2.0.
Metadata
Release files for iaclineage 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| iaclineage-0.1.0.tar.gz | 126.4 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| iaclineage-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 186.3 kB
Release files / iaclineage-0.1.0.tar.gz
| Download URL | iaclineage-0.1.0.tar.gz |
|---|---|
| Size | 126.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
936983713652e3fc747da12403b15f190dfd291955c6f15ec3e8415a3baf13bf
|
|
BLAKE2b-256 checksum How to use checksums |
df508076dc4733d26ff7803934efc7feb6e003cd120fb531e794cad24e2e86d6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logRelease files / iaclineage-0.1.0-py3-none-any.whl
| Download URL | iaclineage-0.1.0-py3-none-any.whl |
|---|---|
| Size | 59.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aec938ef347b6f6a2f132ccc2a2376aa75bf11d9a37260291c61834171c646e6
|
|
BLAKE2b-256 checksum How to use checksums |
799180a79ff0ddce64e4d9b974429e32d195e3bddbeb5ee6ec555b1d76686209
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logSecurity for iaclineage 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for iaclineage-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.