Hashicorp Configuration Language

Hashicorp Configuration Language is the configuration language developed by Hashicorp, the company behind popular software such as Terraform, Vault, Consul, and Nomad. Hashicorp Configuration Language is used in definitions of infrastructure, policies, and other configurations to be applied in Hashicorp tools.
HCL is a human-readable, declarative language and is intended to define the desired state of the configuration rather than to document step-by-step how that state would be achieved. As such, it is easier for people to write and understand HCL configurations than with more imperative languages. HCL consists of four major syntax constructs

Arguments

An argument in Hashicorp Configuration Language (HCL) refers to a key-value pair intended for defining the settings or properties of resources, modules, or other objects in your configuration.

syntax

The syntax for an argument in HCL is as follows:
key = value
This is how it operates:
For example, in your Terraform configuration, you may have an argument that looks something like this:
repository = "codeartifact-repository-name"
In this case, the key is repository which is typically the name of the repository and the value is "codeartifact-repository-name" which is a string.
All the arguments declared in your HCL configurations are used throughout your infrastructure configurations. They define the desired state of your cloud resources, modules or other entities. That way, they provide a declarative means of describing settings of their configurations, making them amenable to management by Terraform or other HCL-based tools.

Blocks

Blocks in Terraform are the basic building blocks of a configuration. It is essentially a way of grouping related configuration elements in Terraform and acts as a container to hold other content, such as arguments and nested blocks.

syntax

Syntax to use a block in HCL is as follows :
block_type label1 label2 ... {
    # argument
    # nested blocks
}
This is how it operates:
Let's take the following resource terraform block as an example.
resource "aws_instance" "example" {
    ami = "0123456789"
    instance_type = "t2.micro"
    network_interface {
        subnet_id = "subnet-0123456789"
        security_groups = ["sg-0123456789"]
    }
}
In this case:
There are various block types that are utilized for the organization as well as structuring of Terraform configuration files. Each type of block has its own specific purpose and is used to define infrastructure as well as manage it. The most common blocks in Terraform include

Identifiers

Identifiers are the names of various elements in the configuration in Terraform. Such names are argument names, block type names, and the names of most Terraform-specific constructs such as resources, input variables, among others.
Terraform identifiers can consist of the following characters:
Here are some examples of valid and invalid identifiers:
variable "my_input_variable" {
    description = "tell something about your input variable."
    type = string
    default = "default value"
}

resource "aws_instance" "example" {
    ami = "0123456789"
    instance_type = "t2.micro"
    network_interface {
        subnet_id = "subnet-0123456789"
        security_groups = ["sg-0123456789"]
    }
}
module "my-custom-module" {
    source = "./path/to/module"
    module_input = var.my_input_variable
}
Here are the identifiers used:

Comments

Comments are a crucial component of any configuration management tool since they provide the ability to describe and document your infrastructure code. Terraform has three styles of writing comments in the configuration files:

Single-line comments with #

Comments that start with the # character are carried up through the end of line. It is the default and most commonly used commenting in Terraform.

Example

# This is a single-line comment
instance_type = "m7gd.8xlarge"
The # symbol is recognized by Terraform as the starting point of a comment and the rest of the line will be ignored by the parser. Commenting style is quite known and very recommended in the Terraform community.

Single-line comments using //

Terraform also supports using the // syntax to begin a single-line comment. It is a further alternative to the # style but the # style is really preferred.

Example

// This is also a single-line comment
source = "../../ec2/"
The // characters are considered a line comment starter. Whatever left on the line is ignored as a result of it. This style is supported but it's not very common and is also not the idiomatic way for Terraform configurations.

Multi-line comments using /* */:

To write a comment that spans multiple lines, you can make use of the delimiters /* and */. Any text enclosed between these delimiters is considered as a comment and is ignored by the Terraform parser. This style of commenting proves useful when you wish to provide more elaborate explanations or comments that just cannot be said in a line.

Example

/* This is a
  multi-line
  comment */
region = "us-west-1"
NOTE: The # single-line comment style is the default and preferred style of comments in Terraform. Automatically formatting tools for Terraform configuration files, such as terraform fmt, automatically replace // comments with # comments since the double-slash style is not idiomatic for configurations in Terraform.

Configuration Formats

Hashicorp Configuration Language, HCL provides two different formats of configurations wherein users can use any format that suits them the most and their preferences are

Native syntax

The Native format of HCL is a human-readable domain-specific language. Its syntax is similar to JSON but much more concise and intuitive, making it much easier to write and understand.
Native format is the preferred way to specify infrastructure, policies, or other configurations in Hashicorp tools such as Terraform. Here is a demonstration of a Terraform configuration, where it has demonstrated using Native Format:
resource "aws_security_group" "example" {
    name = "Example Security Group"
    vpc_id = aws_vpc.example.id
    ingress {
        from_port = 80
        to_port = 80
        protocol = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
    egress {
        from_port = 0
        to_port = 0
        protocol = "-1"
        cidr_blocks = ["0.0.0.0/0"]
    }
}

JSON format

HCL also supports a JSON-based format aside from native format. The JSON format is a direct translation of the native HCL format into a JSON representation.
This format comes in handy if you want to programmatically generate or manipulate HCL configurations because JSON is an extremely widely-supported data format. Here is an example of a Terraform configuration showing the usage of Json Format:
{ 
  "resource" : {
    "aws_security_group" : {
      "example" : {
          "name" : "Example Security Group",
          "vpc_id" : "${aws_vpc.example.id}",
          "ingress" : [
            {
                "from_port" = 80
                "to_port" = 80
                "protocol" = "tcp"
                "cidr_blocks" = ["0.0.0.0/0"]
            }
          ],
          "egress" : [
            {
                "from_port" = 0
                "to_port" = 0
                "protocol" = "-1
                "cidr_blocks" = ["0.0.0.0/0"]
            }
          ]
        }
      }
   }
}
The choice between the two depends on personal preference and specific use cases. Native HCL format would usually be preferred for a manual configuration management since it is more directly readable by humans than its JSON format counterpart. JSON format is much better suited for automated or programmatic workflows where the configuration needs to be generated or manipulated programmatically.

Related Pages

Feedback

Was this page helpful?