github.com/hashicorp/hcl/v2@v2.20.0/README.md (about) 1 # HCL 2 3 HCL is a toolkit for creating structured configuration languages that are 4 both human- and machine-friendly, for use with command-line tools. 5 Although intended to be generally useful, it is primarily targeted 6 towards devops tools, servers, etc. 7 8 > **NOTE:** This is major version 2 of HCL, whose Go API is incompatible with 9 > major version 1. Both versions are available for selection in Go Modules 10 > projects. HCL 2 _cannot_ be imported from Go projects that are not using Go Modules. For more information, see 11 > [our version selection guide](https://github.com/hashicorp/hcl/wiki/Version-Selection). 12 13 HCL has both a _native syntax_, intended to be pleasant to read and write for 14 humans, and a JSON-based variant that is easier for machines to generate 15 and parse. 16 17 The HCL native syntax is inspired by [libucl](https://github.com/vstakhov/libucl), 18 [nginx configuration](http://nginx.org/en/docs/beginners_guide.html#conf_structure), 19 and others. 20 21 It includes an expression syntax that allows basic inline computation and, 22 with support from the calling application, use of variables and functions 23 for more dynamic configuration languages. 24 25 HCL provides a set of constructs that can be used by a calling application to 26 construct a configuration language. The application defines which attribute 27 names and nested block types are expected, and HCL parses the configuration 28 file, verifies that it conforms to the expected structure, and returns 29 high-level objects that the application can use for further processing. 30 31 ```go 32 package main 33 34 import ( 35 "log" 36 37 "github.com/hashicorp/hcl/v2/hclsimple" 38 ) 39 40 type Config struct { 41 IOMode string `hcl:"io_mode"` 42 Service ServiceConfig `hcl:"service,block"` 43 } 44 45 type ServiceConfig struct { 46 Protocol string `hcl:"protocol,label"` 47 Type string `hcl:"type,label"` 48 ListenAddr string `hcl:"listen_addr"` 49 Processes []ProcessConfig `hcl:"process,block"` 50 } 51 52 type ProcessConfig struct { 53 Type string `hcl:"type,label"` 54 Command []string `hcl:"command"` 55 } 56 57 func main() { 58 var config Config 59 err := hclsimple.DecodeFile("config.hcl", nil, &config) 60 if err != nil { 61 log.Fatalf("Failed to load configuration: %s", err) 62 } 63 log.Printf("Configuration is %#v", config) 64 } 65 ``` 66 67 A lower-level API is available for applications that need more control over 68 the parsing, decoding, and evaluation of configuration. For more information, 69 see [the package documentation](https://pkg.go.dev/github.com/hashicorp/hcl/v2). 70 71 ## Why? 72 73 Newcomers to HCL often ask: why not JSON, YAML, etc? 74 75 Whereas JSON and YAML are formats for serializing data structures, HCL is 76 a syntax and API specifically designed for building structured configuration 77 formats. 78 79 HCL attempts to strike a compromise between generic serialization formats 80 such as JSON and configuration formats built around full programming languages 81 such as Ruby. HCL syntax is designed to be easily read and written by humans, 82 and allows _declarative_ logic to permit its use in more complex applications. 83 84 HCL is intended as a base syntax for configuration formats built 85 around key-value pairs and hierarchical blocks whose structure is well-defined 86 by the calling application, and this definition of the configuration structure 87 allows for better error messages and more convenient definition within the 88 calling application. 89 90 It can't be denied that JSON is very convenient as a _lingua franca_ 91 for interoperability between different pieces of software. Because of this, 92 HCL defines a common configuration model that can be parsed from either its 93 native syntax or from a well-defined equivalent JSON structure. This allows 94 configuration to be provided as a mixture of human-authored configuration 95 files in the native syntax and machine-generated files in JSON. 96 97 ## Information Model and Syntax 98 99 HCL is built around two primary concepts: _attributes_ and _blocks_. In 100 native syntax, a configuration file for a hypothetical application might look 101 something like this: 102 103 ```hcl 104 io_mode = "async" 105 106 service "http" "web_proxy" { 107 listen_addr = "127.0.0.1:8080" 108 109 process "main" { 110 command = ["/usr/local/bin/awesome-app", "server"] 111 } 112 113 process "mgmt" { 114 command = ["/usr/local/bin/awesome-app", "mgmt"] 115 } 116 } 117 ``` 118 119 The JSON equivalent of this configuration is the following: 120 121 ```json 122 { 123 "io_mode": "async", 124 "service": { 125 "http": { 126 "web_proxy": { 127 "listen_addr": "127.0.0.1:8080", 128 "process": { 129 "main": { 130 "command": ["/usr/local/bin/awesome-app", "server"] 131 }, 132 "mgmt": { 133 "command": ["/usr/local/bin/awesome-app", "mgmt"] 134 }, 135 } 136 } 137 } 138 } 139 } 140 ``` 141 142 Regardless of which syntax is used, the API within the calling application 143 is the same. It can either work directly with the low-level attributes and 144 blocks, for more advanced use-cases, or it can use one of the _decoder_ 145 packages to declaratively extract into either Go structs or dynamic value 146 structures. 147 148 Attribute values can be expressions as well as just literal values: 149 150 ```hcl 151 # Arithmetic with literals and application-provided variables 152 sum = 1 + addend 153 154 # String interpolation and templates 155 message = "Hello, ${name}!" 156 157 # Application-provided functions 158 shouty_message = upper(message) 159 ``` 160 161 Although JSON syntax doesn't permit direct use of expressions, the interpolation 162 syntax allows use of arbitrary expressions within JSON strings: 163 164 ```json 165 { 166 "sum": "${1 + addend}", 167 "message": "Hello, ${name}!", 168 "shouty_message": "${upper(message)}" 169 } 170 ``` 171 172 For more information, see the detailed specifications: 173 174 * [Syntax-agnostic Information Model](spec.md) 175 * [HCL Native Syntax](hclsyntax/spec.md) 176 * [JSON Representation](json/spec.md) 177 178 ## Changes in 2.0 179 180 Version 2.0 of HCL combines the features of HCL 1.0 with those of the 181 interpolation language HIL to produce a single configuration language that 182 supports arbitrary expressions. 183 184 This new version has a completely new parser and Go API, with no direct 185 migration path. Although the syntax is similar, the implementation takes some 186 very different approaches to improve on some "rough edges" that existed with 187 the original implementation and to allow for more robust error handling. 188 189 It's possible to import both HCL 1 and HCL 2 into the same program using Go's 190 _semantic import versioning_ mechanism: 191 192 ```go 193 import ( 194 hcl1 "github.com/hashicorp/hcl" 195 hcl2 "github.com/hashicorp/hcl/v2" 196 ) 197 ``` 198 199 ## Acknowledgements 200 201 HCL was heavily inspired by [libucl](https://github.com/vstakhov/libucl), 202 by [Vsevolod Stakhov](https://github.com/vstakhov). 203 204 HCL and HIL originate in [HashiCorp Terraform](https://terraform.io/), 205 with the original parsers for each written by 206 [Mitchell Hashimoto](https://github.com/mitchellh). 207 208 The original HCL parser was ported to pure Go (from yacc) by 209 [Fatih Arslan](https://github.com/fatih). The structure-related portions of 210 the new native syntax parser build on that work. 211 212 The original HIL parser was ported to pure Go (from yacc) by 213 [Martin Atkins](https://github.com/apparentlymart). The expression-related 214 portions of the new native syntax parser build on that work. 215 216 HCL 2, which merged the original HCL and HIL languages into this single new 217 language, builds on design and prototyping work by 218 [Martin Atkins](https://github.com/apparentlymart) in 219 [zcl](https://github.com/zclconf/go-zcl).