HashiCorp Configuration Language
repository·main·Indexed 26 days ago
https://github.com/hashicorp/hclA toolkit for creating structured, human-readable, and machine-parseable configuration languages designed for DevOps and server-side tools. It includes the hcldec CLI for transforming HCL to JSON and various extensions for dynamic blocks (dynblock), custom decoding (customdecode), type expressions (typeexpr), and conditional functions like try and can (tryfunc).
What's inside HCL
- HCL Extensions are optional packages that build on the core HCL API to add additional features and expressiveness to the language. These extensions are intended for specific use-cases where increased dynamic behavior is acceptable. Note that using extensions may make the language less rigid compared to the core HCL implementation, which might be undesirable for applications requiring strict configuration structures.
Understand the HCL toolkit capabilities
mainHCL (HashiCorp Configuration Language) is a toolkit designed to help developers create structured configuration languages that serve both humans and machines.
Key features include:
- Dual Syntax: Supports a native syntax optimized for human readability/writability and a JSON-based variant optimized for machine generation and parsing.
- Expression Syntax: Enables basic inline computation.
- Dynamic Configuration: Supports variables and functions when integrated with a calling application.
- Schema Validation: Allows applications to define expected argument names and nested block types. HCL parses the configuration, verifies it conforms to the defined structure, and returns high-level objects for processing.
Note: HCL is primarily intended for use in Go applications via its library API.
Understand HCL core constructs: arguments and blocks
mainHCL configuration is composed of two primary building blocks: arguments (also called attributes) and blocks.
- Arguments: Key-value pairs assigned within a body (e.g.,
io_mode = "async"). - Blocks: Named structures that can contain nested arguments and blocks. Blocks can optionally include labels (quoted names following the block type).
- Body: The collection of arguments and blocks at a specific nesting level. Every HCL file has a root body, and every block has its own body.
Unlike JSON or YAML, HCL is a structured configuration language that is always decoded using an application-defined schema.
io_mode = "async" service "http" "web_proxy" { listen_addr = "127.0.0.1:8080" process "main" { command = ["/usr/local/bin/awesome-app", "server"] } }- Arguments: Key-value pairs assigned within a body (e.g.,
Understand the `hcldec` spec format
mainThe
hcldecspec format is used to instruct thehcldectool on how to validate HCL configuration files and translate them into JSON.Key concepts:
- Spec Files: Must contain a single top-level spec block that describes the root JSON value. This block can contain nested spec blocks to create nested JSON structures.
- Spec Blocks: Each block serves as a mapping action and often a validation constraint. Each block produces exactly one JSON value.
- Context (Body): Specs are evaluated within an HCL body. Some spec types (like
block,block_list, etc.) change the context to the body of the matched HCL element, allowing for deep decoding of nested structures.
Understand the HCL language structure
mainHCL is composed of three integrated sub-languages used together in configuration files:
- Structural language: Defines the hierarchical configuration structure using bodies, blocks, and attributes.
- Expression language: Used to express attribute values as literals or derivations of other values.
- Template language: Used to compose values together into strings via interpolation.
While typically used together, the expression and template languages can be used in isolation for tools like REPLs or debuggers.
HCL JSON Syntax Specification Overview
mainHCL provides a JSON-based serialization format designed for machine-generated configuration. While the native HCL syntax is optimized for human readability, the JSON syntax is intended to be easily produced by standard JSON implementations in various programming languages.
To correctly parse HCL JSON, a parser must be able to:
- Preserve the relative ordering of properties in an object.
- Preserve multiple definitions of the same property name.
- Preserve numeric values with the precision required by the HCL information model.
- Retain source location information for tokens to provide accurate error messages.
Understand the HCL Information Model
mainHCL (HashiCorp Configuration Language) is a system for defining configuration languages. It uses an abstract information model that allows multiple concrete syntaxes (such as the HCL native syntax and JSON syntax) to map to a common set of semantic types and structures.
Core Structural Elements
- Body: The primary container representing a set of zero or more attributes and zero or more blocks.
- Configuration File: The top-level object, which is a body representing the root attributes and blocks.
- Attribute: A unique name and value pair within a body. Values are provided as expressions.
- Block: A nested structure containing a type name, zero or more string labels (identifiers), and a nested body.
Understand HCL Information Model: Attributes and Blocks
mainHCL is built around two primary constructs:
- Attributes: Key-value pairs (e.g.,
io_mode = "async"). - Blocks: Hierarchical structures that can contain attributes or nested blocks (e.g.,
service "http" "web_proxy" { ... }).
This model allows for both human-readable native syntax and machine-friendly JSON representation. The API remains consistent regardless of whether the source is HCL native syntax or JSON.
- Attributes: Key-value pairs (e.g.,
Use HCL Templates to combine strings and values
mainHCL Templates are a sub-language used to concisely combine strings and other values into a single string. A template behaves like an expression that always returns a string value. If any element produces an unknown string or a dynamic pseudo-type, the entire result becomes an unknown string.
Templates consist of:
- Template Literals: Literal sequences of characters.
- Template Interpolations:
${expression}syntax to evaluate and insert values. - Template Directives: Control flow like
ifandfor.
Install file2fuzz to prepare seed corpus
mainIf you want to add additional seed inputs to the fuzzing corpus, files must be in the Go 1.18 corpus file format. You can use the
file2fuzztool to convert files to this format.$ go install golang.org/x/tools/cmd/file2fuzz@latest $ file2fuzz -helpUse HCL in a Go application
mainHCL is primarily intended to be used as a library within Go programs. It provides several ways to define and process configuration languages depending on the complexity of your requirements:
- Simple decoding: For straightforward configurations, HCL can decode directly into Go
structvalues, behaving similarly to theencoding/jsonorencoding/xmlpackages. - Complex processing: For languages with complex structures or portions where the schema cannot be determined until runtime, the HCL Go API offers alternative approaches.
Available integration patterns include parsing, diagnostics, decoding via
gohclorhcldec, expression evaluation, and low-level decoding.- Simple decoding: For straightforward configurations, HCL can decode directly into Go
Use JSON syntax for HCL configuration
mainHCL provides a JSON-based alternative syntax. This allows developers to generate HCL configuration programmatically using standard JSON serializers. The calling application can choose to support both HCL and JSON syntaxes. When using JSON, the application's schema is used to resolve ambiguities (such as whether a JSON object represents a nested block or an object expression).
{ "io_mode": "async", "service": { "http": { "web_proxy": { "listen_addr": "127.0.0.1:8080", "process": { "main": { "command": ["/usr/local/bin/awesome-app", "server"] }, "mgmt": { "command": ["/usr/local/bin/awesome-app", "mgmt"] } } } } } }