HCL is the HashiCorp Configuration Language.

Max Bowsher 2797f57b05 Reconcile v1.0.1-vault divergent history (#578) 10 months ago
.circleci 3cafe7a045 Add CI config 2 years ago
.github 6aead19b62 Add issue template 7 years ago
hcl cf4c4bf246 Merge pull request #275 from hashicorp/fix-unusedKeys 2 years ago
json 24ca72c351 fix typo 6 years ago
test-fixtures 6e9815dfda VAULT-8519 - Don't erroneously report nested JSON as unused keys (#559) 1 year ago
testhelper 2b0eb1f52c Support multiline string literals in HCL only in HIL fragments 7 years ago
.gitignore e2e76d3e53 fix appveyor build 7 years ago
.travis.yml 42e33e2d55 travis: update go versions 6 years ago
LICENSE 6ae248587a LICENSE 9 years ago
Makefile 88422edf64 Update Makefile with new deps, go1.7 in travis 7 years ago
README.md ef28deed85 Added hcl to json example for nested objects (#36) 7 years ago
appveyor.yml 86950618a5 Don't automatically convert to CRLF in AppVeyor 7 years ago
decoder.go 6e9815dfda VAULT-8519 - Don't erroneously report nested JSON as unused keys (#559) 1 year ago
decoder_test.go 6e9815dfda VAULT-8519 - Don't erroneously report nested JSON as unused keys (#559) 1 year ago
go.mod c0c1aafe29 go.mod update 2 years ago
go.sum 8cb6e5b959 Prepare to be a Go module 5 years ago
hcl.go 6cf355fb61 Use Go convention of docs with "Package" prefix 8 years ago
hcl_test.go 96e92c5213 Decode into flat structures for objects 9 years ago
lex.go 2799afc14b adds std encoding API fixes #4 7 years ago
lex_test.go 2799afc14b adds std encoding API fixes #4 7 years ago
parse.go 2799afc14b adds std encoding API fixes #4 7 years ago



GoDoc Build Status

HCL (HashiCorp Configuration Language) is a configuration language built by HashiCorp. The goal of HCL is to build a structured configuration language that is both human and machine friendly for use with command-line tools, but specifically targeted towards DevOps tools, servers, etc.

HCL is also fully JSON compatible. That is, JSON can be used as completely valid input to a system expecting HCL. This helps makes systems interoperable with other systems.

HCL is heavily inspired by libucl, nginx configuration, and others similar.


A common question when viewing HCL is to ask the question: why not JSON, YAML, etc.?

Prior to HCL, the tools we built at HashiCorp used a variety of configuration languages from full programming languages such as Ruby to complete data structure languages such as JSON. What we learned is that some people wanted human-friendly configuration languages and some people wanted machine-friendly languages.

JSON fits a nice balance in this, but is fairly verbose and most importantly doesn't support comments. With YAML, we found that beginners had a really hard time determining what the actual structure was, and ended up guessing more often than not whether to use a hyphen, colon, etc. in order to represent some configuration key.

Full programming languages such as Ruby enable complex behavior a configuration language shouldn't usually allow, and also forces people to learn some set of Ruby.

Because of this, we decided to create our own configuration language that is JSON-compatible. Our configuration language (HCL) is designed to be written and modified by humans. The API for HCL allows JSON as an input so that it is also machine-friendly (machines can generate JSON instead of trying to generate HCL).

Our goal with HCL is not to alienate other configuration languages. It is instead to provide HCL as a specialized language for our tools, and JSON as the interoperability layer.


For a complete grammar, please see the parser itself. A high-level overview of the syntax and grammar is listed here.

  • Single line comments start with # or //

  • Multi-line comments are wrapped in /* and */. Nested block comments are not allowed. A multi-line comment (also known as a block comment) terminates at the first */ found.

  • Values are assigned with the syntax key = value (whitespace doesn't matter). The value can be any primitive: a string, number, boolean, object, or list.

  • Strings are double-quoted and can contain any UTF-8 characters. Example: "Hello, World"

  • Multi-line strings start with <<EOF at the end of a line, and end with EOF on its own line (here documents). Any text may be used in place of EOF. Example:

  • Numbers are assumed to be base 10. If you prefix a number with 0x, it is treated as a hexadecimal. If it is prefixed with 0, it is treated as an octal. Numbers can be in scientific notation: "1e10".

  • Boolean values: true, false

  • Arrays can be made by wrapping it in []. Example: ["foo", "bar", 42]. Arrays can contain primitives, other arrays, and objects. As an alternative, lists of objects can be created with repeated blocks, using this structure:

    service {
        key = "value"
    service {
        key = "value"

Objects and nested objects are created using the structure shown below:

variable "ami" {
    description = "the AMI to use"

This would be equivalent to the following json:

  "variable": {
      "ami": {
          "description": "the AMI to use"


Thanks to:

  • @vstakhov - The original libucl parser and syntax that HCL was based off of.

  • @fatih - The rewritten HCL parser in pure Go (no goyacc) and support for a printer.