Overview
Introduction
HCL is the syntax behind Terraform, Nomad, Packer, and other HashiCorp tooling, readable block-and-attribute config that's great for infrastructure-as-code but not always what a downstream tool expects. This tool parses a practical subset of HCL and re-expresses it as nested YAML.
It's a hand-written recursive-descent parser covering the structural features most real HCL config actually uses, blocks, labels, and typed attributes, deliberately leaving HCL's expression language (functions, interpolation, for expressions) out of scope in favor of predictable, honest results.
What Is HCL to YAML?
An HCL-to-YAML converter tokenizes HCL source (identifiers, quoted strings, numbers, booleans, and punctuation) and then parses it recursively: an identifier followed by = is an attribute assignment, while an identifier followed by zero or more quoted labels and a { starts a nested block.
Blocks become nested JavaScript objects keyed by their type and then each label in turn, and that object tree is serialized as YAML with the same stringifier every other tool in this category uses.
How HCL to YAML Works
Attributes are simple: key = value, where value is a string, number, boolean, or [ ]-delimited array of those. Blocks are structural: the block type and any quoted labels form a path (resource, aws_instance, web), and the { ... } body is parsed recursively (allowing attributes and further nested blocks) into an object placed at that path.
If two blocks resolve to the same path (the same type and labels appearing twice), their bodies are shallow-merged rather than one replacing the other. # and // both start a line comment and are skipped during tokenizing, before parsing sees them.
When To Use HCL to YAML
Use it to preview a Terraform resource block, a Nomad job spec, or a Packer template's structure as YAML, useful when writing documentation or feeding the structure into a YAML-based tool.
It's also a quick way to sanity-check how HCL's label-based nesting would flatten into an object tree, without spinning up an actual Terraform parser.
Often used alongside HOCON to YAML, TOML to YAML Converter and YAML Formatter & Prettifier.
Features
Advantages
- Correctly reconstructs labeled blocks into the nested object shape their labels imply, matching how Terraform itself interprets them.
- Handles zero-label blocks, multi-label blocks, arrays, and nested blocks-within-blocks.
- Reports clear, line-numbered syntax errors rather than silently producing a wrong structure for unsupported syntax.
- Runs entirely client-side with no added dependency, so infrastructure config never leaves your browser.
Limitations
- HCL's expression language, function calls, for expressions, conditionals, and references between resources, is entirely out of scope; a ${...} interpolation sequence is kept as a literal string rather than evaluated.
- Heredoc strings (<<EOT ... EOT) and maps used as attribute values (as opposed to blocks) are not supported and produce a parse error.
- Numbers are parsed with a simple digits-and-decimal-point pattern; HCL's more exotic numeric literals (hex, exponents) aren't recognized.
Examples
Best Practices & Notes
Best Practices
- Expect ${...} interpolation to appear unresolved in the YAML output, treat it as a reminder of where a real value would need to be substituted, not an error.
- Check the error message's line number directly against your HCL source when parsing fails, it names the exact unsupported construct.
- Run the result through the YAML Formatter afterward if you want to double-check indentation consistency.
Developer Notes
The implementation is a small tokenizer (producing ident/string/number/bool/punctuation tokens with line/column tracking) feeding a recursive-descent parser with two entry points: parseItem, which distinguishes an attribute (identifier followed by =) from a block (identifier followed by zero or more string labels and {), and parseValue, which handles scalars and [ ]-delimited arrays. Repeated blocks at the same path are shallow-merged via object spread.
HCL to YAML Use Cases
- Previewing a Terraform resource or module block's structure as YAML for documentation
- Converting a Nomad job spec or Packer template into YAML for a tool that expects that format
- Sanity-checking how HCL's label-based block nesting translates into a plain object tree
- Generating YAML fixtures for tests from an existing HCL source file
Common Mistakes
- Expecting ${...} interpolation to be evaluated to an actual value, it's passed through as a literal string instead.
- Using a heredoc string or a map as an attribute value and expecting it to parse, neither is supported in this subset.
- Forgetting that repeated blocks at the same type-and-labels path merge their attributes rather than each becoming a separate list entry.
Tips
- If parsing fails, check whether the offending construct is a heredoc, a map-as-value, or an expression, features called out as unsupported.
- Use YAML Sorter afterward if you want the converted mapping's keys in alphabetical order rather than source-file order.
- For deeply nested HCL (blocks within blocks), converting to YAML often makes the overall structure easier to scan than HCL's brace-based nesting.