See it as a diagram
Everything below, as a diagram you can edit. Describe yours and see it in seconds.
No account needed · Editable canvas, not a picture
What tofu graph is good at, and what it is not for
tofu graph writes the dependency graph in DOT format for Graphviz. Its -type flag selects plan, plan-refresh-only, plan-destroy, or apply; -draw-cycles colours the edges forming a cycle; -plan renders from a saved plan file instead of the configuration. For its actual job, debugging a cycle or checking that a depends_on landed where you meant it, nothing beats it.
As documentation it fails for three reasons that have nothing to do with OpenTofu. It graphs the resolver, so providers, data sources, and meta-nodes all become boxes; Terraform's own documentation for the equivalent command says the richer graph types expose implementation details of the language runtime. It weighs every node the same, so a random_id sits at the size of your GKE cluster. And it runs against one working directory with its root variables supplied, so a repository holding nineteen root modules is nineteen separate runs and nineteen DOT files that nobody assembles.
The fork changed the binary, not the parse surface
OpenTofu kept HCL2 and the block grammar it inherited: resource, data, module, variable, output, locals, terraform, provider. Directory layout, module sources, tfvars, the meaning of count and for_each, all the same. A parser that reads the source therefore does not need to know which binary you run.
Datadef parses every file ending in .tf and .tfvars in the connected repository: stacks, module tree, resources with their multiplicity, data lookups, variables followed through call sites and locals to literal values, references resolved through module outputs to the resources they actually reach. Modules become zones, major resources keep their provider icons, repeated minor types roll up with counts, and role assignments and grants are counted in a note rather than drawn.
Two OpenTofu specifics are worth stating plainly. The first is the .tofu extension: OpenTofu reads both .tf and .tofu, and where both exist with the same base name in a directory it prioritises the .tofu file and ignores the .tf one. Datadef fetches .tf and .tfvars, so in that override case it parses the file OpenTofu is ignoring. Keep shared configuration on .tf and the two readings agree.
The second is early variable evaluation, which lets an OpenTofu module source be built from a variable; the tofu graph documentation flags the same feature when it notes that variables in module sources need root variable values supplied on the command line. A source that is not a literal string cannot be resolved by a parser either, so pin registry sources as plain literals if you want the source and version printed on the box.
State encryption is a non-event here
Migrating from Terraform without churning the diagram
A migration commit is loud in the diff and silent in the architecture. It swaps required_version, points required_providers at a different registry host, sometimes renames a lock file. None of that changes what the platform is.
Datadef hashes the parsed draw plan rather than the commit sha, so a sync whose structure fingerprint is unchanged skips generation entirely. The migration commit lands, the diagram does not move, and the first regeneration happens when somebody actually adds a module. For a mixed estate mid-migration, the generated architecture doc lists the providers in play and the state backend per stack, which is usually the fastest way to see which repositories have already been converted.
Connect from GitHub, GitLab, or Azure DevOps with read-only access, pick a branch or a tag, and the diagram regenerates daily and on demand. It embeds in a README or a wiki page as a live image and exports as PNG or JPEG.
FAQ
Does Datadef work with OpenTofu repositories?
How is this different from running tofu graph?
Are files with the .tofu extension parsed?
We are migrating from Terraform to OpenTofu. Will the diagram change?
Does OpenTofu state encryption prevent the analysis?