126 lines
4.2 KiB
Markdown
126 lines
4.2 KiB
Markdown
|
# HCL
|
||
|
|
||
|
[![GoDoc](https://godoc.org/github.com/hashicorp/hcl?status.png)](https://godoc.org/github.com/hashicorp/hcl) [![Build Status](https://travis-ci.org/hashicorp/hcl.svg?branch=master)](https://travis-ci.org/hashicorp/hcl)
|
||
|
|
||
|
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](https://github.com/vstakhov/libucl),
|
||
|
nginx configuration, and others similar.
|
||
|
|
||
|
## Why?
|
||
|
|
||
|
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](http://www.hashicorp.com)
|
||
|
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.
|
||
|
|
||
|
## Syntax
|
||
|
|
||
|
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](https://en.wikipedia.org/wiki/Here_document)).
|
||
|
Any text may be used in place of `EOF`. Example:
|
||
|
```
|
||
|
<<FOO
|
||
|
hello
|
||
|
world
|
||
|
FOO
|
||
|
```
|
||
|
|
||
|
* 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:
|
||
|
|
||
|
```hcl
|
||
|
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:
|
||
|
``` json
|
||
|
{
|
||
|
"variable": {
|
||
|
"ami": {
|
||
|
"description": "the AMI to use"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Thanks
|
||
|
|
||
|
Thanks to:
|
||
|
|
||
|
* [@vstakhov](https://github.com/vstakhov) - The original libucl parser
|
||
|
and syntax that HCL was based off of.
|
||
|
|
||
|
* [@fatih](https://github.com/fatih) - The rewritten HCL parser
|
||
|
in pure Go (no goyacc) and support for a printer.
|