Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Terraform Formatter & Validator (fmt, HCL ⇄ JSON)

Format Terraform and OpenTofu files the fmt way, check the module and see how it connects.

Free preview, no sign-upIncluded in your pass Pro tool Pro pass: ₹179 / $5.99 for 30 days On this device: nothing is sent
+3 +1 more details No uploadWorks offline once opened Developer

Free preview: the first lines of each formatted file and its JSON (up to 20), every count with the first findings (up to 10), and the graph under a MySmartCoPilot mark. Locked until you unlock it: download and copy.

Pro pass ₹179 for 30 days or ₹79 for 1 week, one‑time. Pro pass $5.99 for 30 days or $2.99 for 1 week, one‑time. How to unlock

Try before you buy.

  • Free preview: the first lines of each formatted file and its JSON (up to 20), every count with the first findings (up to 10), and the graph under a MySmartCoPilot mark.
  • Locked until you unlock it: download and copy.
  • Unlock: Pro pass, ₹179 for 30 days or ₹79 for 1 week, a one-time payment that never renews. Unlock: Pro pass, $5.99 for 30 days or $2.99 for 1 week, a one-time payment that never renews.

Ways to unlock shows how to get the full result.

See passes (opens in a new tab)

Printing this result is locked in the free preview.

Configuration

The name tells the kind: .tf, .tfvars, .tftest.hcl, .tf.json or .tfstate. Folders (modules/vpc/main.tf) are child modules.

Checked as you type, in your browser. Ctrl/⌘ + Enter checks now.

Next steps Done. What next?

Start over

A Pro pass unlocks the full result. See passes

All developer tools

About the Terraform Formatter & Validator (fmt, HCL ⇄ JSON)

Paste a .tf file, or open several files or a ZIP of a module (up to 5 MB): every file is laid out in Terraform’s canonical style, the way terraform fmt and tofu fmt write it — two spaces per level, the = signs of neighbouring arguments aligned, one space around operators and inside braces, none inside brackets — with labels quoted, "${var.x}" unwrapped to var.x and legacy types such as "string" turned into string. Syntax errors are reported with their line and column, and the file is left as it is, as fmt does.

The module is then checked as a whole: duplicate blocks, references to variables, locals, modules, resources or data sources it does not declare, a missing required_version, providers without a version constraint, module sources that are not pinned (git without ?ref=, the registry without version), variables without a type or description, secret-looking defaults and keys written into the code, count together with for_each, and pre-0.12 syntax. Each finding says how to fix it. You can also convert files to Terraform’s JSON syntax and back, see the dependency graph of resources, data sources and modules drawn from their references, and open a terraform.tfstate to list its resources and outputs and the secrets it keeps in plain text.

Everything runs in your browser; nothing is uploaded. Without a pass the result is a free preview: the first lines of each formatted file, every count with the first findings, and the graph under a mark. Whole files, every finding, the ZIP of formatted files and every copy and download unlock with a Pro pass.

How to use it

  1. Paste a file, open .tf, .tofu, .tfvars, .tftest.hcl, .tf.json or .tfstate files, or open a .zip of the module (folders become child modules). Load example shows a small module with typical problems.
  2. Read the Formatted tab: the diff of what formatting changes, or the whole file. Choose another file of the module in the file list.
  3. Open Findings for errors, warnings and notes, each with its file, line, the reason and the fix; Show selects the line in the editor.
  4. Open Graph to see what depends on what (arrows point from a resource to the ones that use it); turn on variables, locals and outputs to see them too.
  5. Open JSON for the file in Terraform’s JSON syntax, or open a .tf.json file to get it as native HCL; State lists what a state file holds.
  6. Copies and downloads — the formatted file, a ZIP of every formatted file, the findings report, the graph as PNG, DOT or Mermaid, and the JSON — unlock with a Pro pass; the free preview shows their first lines.

Examples

Aligned arguments and quoted labels
Input
resource aws_instance "web" {
ami = "ami-123"
    instance_type="t3.micro"
}
Result
resource "aws_instance" "web" {
  ami           = "ami-123"
  instance_type = "t3.micro"
}
Interpolation-only strings and legacy types
Input
vpc_id = "${module.vpc.vpc_id}"

variable "name" {
  type = "string"
}
Result
vpc_id = module.vpc.vpc_id

variable "name" {
  type = string
}
A finding with its fix
Input
resource "aws_instance" "web" {
  count    = 2
  for_each = toset(var.zones)
}
Result
Error (count-and-for-each), main.tf:3 — sets both "count" and "for_each"; Terraform accepts only one of them. Fix: keep for_each for one instance per key, or count for N identical instances.

What formatting changes, and what it never touches

The layout follows the conventions of Terraform’s style guide and the behaviour of terraform fmt: indentation by bracket level, aligned = signs for consecutive single-line arguments (a value that opens a bracket or a blank line ends the group), aligned trailing comments, and normalised spaces between tokens. Besides whitespace it makes only Terraform’s own rewrites: quoted block labels, a "${…}" that is the whole value unwrapped (in parentheses when it spans lines), and the legacy variable types "string", "list" and "map" (and a bare list, map or set) written as type expressions. The text of strings, heredocs and comments, blank lines and a missing final newline stay as they are, and // comments are not rewritten to # (that one is reported as a note instead).

The checks

  • Errors Terraform would refuse: duplicate resources, data sources, modules, variables or outputs; a provider configured twice without different aliases; duplicate local values; references to things the module does not declare; count and for_each together; a block in an override file with nothing to override.
  • Warnings: no required_version; providers without a version constraint in required_providers; registry modules without version and git modules without ?ref=; variables without a type; secret-looking variable defaults; keys and tokens written into the code (AWS access keys, private keys, GitHub, Slack, Stripe and Google API keys); quoted references in depends_on and provider.
  • Notes: variables without a description, interpolation-only strings and legacy types (which formatting fixes), // and /* */ comments, names with capitals or dashes.

Each folder is a module of its own, as in Terraform. Override files (override.tf and any *_override.tf) are merged into the blocks of the other files, as Terraform merges them, so their blocks are not duplicates. A single pasted file is checked on its own, so references to things declared in its other files are warnings, not errors.

JSON syntax, the graph and state files

The JSON conversion follows Terraform’s JSON configuration syntax: one nested object per block label, arrays for repeated blocks and provisioners, expressions as "${…}" templates, and the arguments Terraform takes literally written as they are: a variable’s type, default and description, a module’s source, version and providers map. References are plain strings such as "aws_instance.web": depends_on, provider, ignore_changes, replace_triggered_by, and the addresses of moved, removed and import blocks. Going back from JSON, nested blocks of a provider cannot be told from map arguments without the provider’s schema, so lists of objects become blocks and every such guess is listed.

The graph is drawn from the references in each block and from depends_on; a dependency through a local value or a variable shows as an edge between the things it connects. State files (format version 4, written by Terraform 0.12 and later and by OpenTofu) list each resource with its instances, the outputs, and the attributes kept in plain text: those the provider marks sensitive, sensitive outputs, and attributes named like secrets. Their values are shown masked.

Limitations

  • The formatter is MySmartCoPilot’s own implementation of the canonical style, matched against the reference formatter’s published examples; Terraform may add formatting rules in a new version.
  • The checks read the configuration only: providers are not downloaded, so provider arguments, resource types and values are not validated (terraform validate does that with the providers installed).
  • References into child modules (module.x.output) are checked for the module, not for the output; outputs of a remote module are not known.
  • Up to 5 MB of files at a time; the graph is easiest to read with a few hundred resources at most.

Privacy

On this device: nothing is sent

Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.

Frequently asked questions

What do I get without a pass?

Without a pass, Terraform Formatter & Validator (fmt, HCL ⇄ JSON) shows the first lines of each formatted file and its JSON (up to 20), every count with the first findings (up to 10), and the graph under a MySmartCoPilot mark. Until you unlock it, the result can’t be downloaded or copied. A Pro, Premium or Ultimate pass, a one-time payment that never renews, unlocks the full result. The pricing page lists the passes and their prices.

Is the result the same as terraform fmt?

It applies the same rules: the layout of the reference formatter (checked against its published examples) and Terraform’s own rewrites of labels, interpolation-only strings and legacy types. Like fmt, it refuses a file with syntax errors and leaves it unchanged. Run terraform fmt -check in CI if you need the exact version of Terraform you use to be the judge.

Does it work with OpenTofu?

Yes. OpenTofu uses the same language and the same formatting, and .tofu and .tofutest.hcl files are read like .tf and .tftest.hcl files.

Why is a variable reported as undeclared when it exists?

The checks see only the files you give them. Variables usually live in variables.tf: open all the module’s files together, or a ZIP of the folder, so the declarations are found. A single pasted file reports such references as warnings for this reason.

Why does it warn about secrets in my state file?

Terraform stores every attribute of every resource in the state, including passwords and keys, without encrypting them. Keep state in a backend that encrypts it and limits who can read it, mark variables and outputs sensitive, and prefer short-lived credentials. The page lists such values masked; nothing leaves your browser.

Is my configuration uploaded?

No. Files, ZIPs and state files are read and processed in your browser only.

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.