Welcome to In my earlier blogs, we have discussed what is HashiCorp Ecosystem and we have been through the Terraform Introduction. In this blog, we will deep dive into Terraform and understand each and every functionality of it. If you are just starting Terraform, please follow the hyperlinks above and come back here. To create your first infrastructure using Terraform, click here.

Terraform is an Infrastructure as Code tool that helps you to create and improve your infrastructure. So let’s start with the configuration. Building infrastructure is easy, but building it in an automated and usable way is harder.

If you are a Developer or a DevOps Engineer, you can understand the need for managing infrastructure components efficiently. Now going straight to point, we will deep dive into the Terraform.


Terraform uses text files to describe the infrastructure. These files are called Terraform File and end in .tf. Here in this section, we will talk about the format of these files and how Terraform understands these files and spin up the infrastructure.

There are two formats of configuration: Terraform format and JSON format. The terraform format is more human readable, more declarative, supports comments and is prescribed by Terraform. Though we can use JSON templates to modify and update the infrastructure by changing the file extension as .tf.json.


The syntax of the Terraform is described in HashiCorp Configuration Language (HCL). It is a human-readable language as well machine friendly. It can also understand JSON configuration. Now, we are going to provide an AWS instance. Below is an example of the HCL syntax:

# Definition of an AMI
variable "ami" {
  description = "LinuxNix AMI"
/* A multi
   line comment. */
resource "aws_instance" "LinuxNix Website" {
  ami               = "${var.ami}"
  count             = 2
  source_dest_check = false
  connection {
    user = "root"

Below are the references:

  • Single line comment with #
  • Multi-line comment inside /* */
  • Strings are in “”
  • Boolean values are True, False

Terraform also supports JSON configuration. The above file in JSON will look like:

  "variable": {
    "ami": {
      "description": "LinuxNix AMI"

  "resource": {
    "aws_instance": {
      "LinuxNix Website": {
        "ami": "${var.ami}",
        "count": 2,
        "source_dest_check": false,
        "connection": {
          "user": "root"


Terraform keeps all the configuration files in a directory. So what overrides means is, it is a way where we keep our Terraform files untouched and just add values to it at the last moment and keep changing it in spite of changing the main file every time.

Naming Convention: Override names must be “override” at last or ends with “_override” excluding the extension. For Ex:, or

Let’s take a Terraform configuration:

variable "ami" {
  description = "LinuxNix AMI"

And we have created another file:

variable "ami" {
  description = "Ankesh AMI"

Here the AMI description from will be overridden by the AMI description from Override file can be in .tf or .tf.json.


Resources play a vital role in Terraform. These are the components of your infrastructure. Resources can be a physical server, cloud server, container, email provider, DNS record, etc.

For Ex:

resource "aws_instance" "LinuxNix Website" {
  ami           = "ami-898x7g23"
  instance_type = "t2.micro"


Variables act as a parameter for Terraform modules. These can be used inside the Terraform file and can be changed from another file in spite of changing the main file configuration.

provider "aws" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region     = "${var.region}"


You can even create a different file named where the variables can be saved. The content of the file is displayed below:

variable "access_key" {ASDFGHKL3ERDFLL4LLTJJ4}
variable "secret_key" {ASNIRFMWOC00LINUXNUIX.COM00NRVR6WRV6UH8K9}
variable "region" {
  default = "us-east-1"


The output is the value that is displayed when you apply to terraform. By using outputs, you can easily extract data and query information. Most of the resources have attributes attached to it so it’s easy to extract them.

For Ex:

output "ip" {
  value = "${aws_instance.linuxnix.public_ip}"

This outputs the Public IP of an AWS instance named linuxnix.


Terraform is capable of storing the state of infrastructure and configuration. This is used by Terraform to match the real-time resource with the resources it has implemented. The state is stored by default in a local file named “terraform.tfstate”.

Terraform uses this local state to create and make changes to your infrastructure. Before any changes, Terraform updated the state with the real infrastructure.


In Terraform, Providers manages the lifecycle of the Resources. All the providers have their configurations to provide authentication information, endpoint URLs, outputs, etc.

Let’s take Amazon Web Services as an example. For this, “aws” is associated with it. We can even pass multiple configurations for the same providers at a time. A provider configuration looks like this:

provider "aws" {
  access_key = "ASDFGHKL3ERDFLL4LLTJJ4"
  region     = " us-east-1"

A provider understands API interactions and exposes resources. There are so many providers terraform supports such as Azure, DNSimple, Docker, DigitalOcean, Github, RabbitMQ, Vault, etc. We will go through some of the types of providers below.

1. Cloud Providers:

HashiCorp closely partners with the major cloud providers to offer best-in-class integration to create and manage infrastructure. These providers are supported by cloud vendors in close collaboration with HashiCorp.

  • AWS
  • Azure
  • AliCloud
  • Google Cloud Platform
  • Oracle Public Cloud
  • VMware NSX-T
  • vCloud Director
  • VMware vSphere, etc
2. Infrastructure Software Providers:

A group of software offers specialized infrastructure management capabilities like configuration management. Terraform integrates with these tools and helps in the provisioning of infrastructure. Some of these providers are:

3. Network Providers:

There are some offerings in terraform providers which offer Network capabilities such as DNS, firewall, routing, etc. These generally offer a cloud-based service and Terraform integrates with these services using a service provider. Some of these providers are:

  • Cloudflare
  • DNS
  • DNSimple
  • HTTP
  • PowerDNS
  • UltraDNS
  • DNSMadeEasy, etc
4. Version Control Providers:

Terraform offers some of the Version control providers too. These providers help you to manage your repositories, teams or projects. Some of these are:

5. Database Providers:

There is a group of databases Terraform supports as a provider. They are integrated with Terraform to provision and manage databases. Some of those providers are:

  • MySQL
  • PostgreSQL


Provisioners are used to executing scripts on the local or remote machine when provisioning the infrastructure. These can be added to any resource. We can even add multiple provisioners to the same resources.

For Ex:

provisioner "local-exec" {
    command = "ifconfig"

This provisioner will execute the command “ifconfig” on localhost and show you the output. Below are the few more provisioners:

1. Provisioner Connections:

This provisioner helps to get the required access to the remote server. For example, if a provisioner used to connect to the machine via ssh or winrm. Any connection information provided to the resource will be applied to the provisioners. Below is an example for the same.

# Copies the file as the root user using SSH
provisioner "file" {
  source      = "conf/linuxnix.conf"
  destination = "/etc/linuxnix.conf"

  connection {
    type     = "ssh"
    user     = "root"
    password = "${var.root_password}"
2. Provisioner local-exec:

This provisioner is used to execute commands or scripts in the local machine. This runs while provisioning the resource and gets the output on the screen. For Ex:

provisioner "local-exec" {
    command = "ifconfig"
3. Provisioner remote-exec:

This provisioner invokes a script or runs a command on a remote machine. This can be used to run configuration management changes and even used in bootstrapping servers. Let’s take an example where you need to go onto a remote server, installs nginx and start it.

provisioner "remote-exec"{
            "git --version",
            "sudo apt-get -y update",
            "sudo apt-get -y install nginx",
            "sudo service nginx restart"


Modules are a self-contained package which is managed by Terraform. Modules are used to create reusable components as well as basic coding configurations. These are very easy to use and create. Let’s create an AWS server to create a consul configuration.

module "consul" {
  source  = "hashicorp/consul/aws"
  servers = 3

In modules, you can specify a name rather specifying the whole configuration for resources in Terraform file. The above configuration tells Terraform to create a consul module for AWS. It is taking the pre-defined configuration from the Terraform Registry. And the server count is mentioned as 3.

You can even create your own modules. And save it on the local path. A local path must begin with either ./ or ../ to indicate it as a local path and to make it different from module registry address. This can be represented as:

module "consul" {
  source = "./consul"


Till now, we have covered what is HashiCorp tools all about and Terraform Introduction and why is the tool in place in the pipeline. Now with this blog, we covered almost all the internal functionalities of Terraform like Providers, Provisioners, Modules, etc. If you want to create your first infrastructure using Terraform, click here.

Stay tuned for more updates..

The following two tabs change content below.
Hello, my name is Ankesh and I work as a Sr. DevOps Engineer in an IT firm where I have hands-on experience in supporting and automating deployments in the cloud, leveraging configuration management and DevOps process. I like to keep myself always in the learning path and love to share knowledge with others. One of my other interests is Graphics Designing and my hobbies are Cooking and Playing Cricket.