A Guide to How Terraform Architecture Functions

In this blog, we will explore how Terraform's architecture is built and how it works behind the scenes. We will cover the Terraform CLI, Terraform Core, provisioners, providers, and more.

Terraform CLI:

Terraform CLI is the interface for the devops engineers to execute terraform commands and manage terraform configuration files(.tf) . It is the user-facing tool that you interact with to manage your infrastructure as code. It provides the commands needed to create, modify, and destroy infrastructure resources, as well as to manage Terraform's configuration files and state. After a user executes a command on terraform CLI it passes the control to Terraform Core.

Terraform Core

Terraform Core is the main engine of terraform. It is the central component that executes the operations required to align your real-world infrastructure with infrastructure described in terraform files.

Core is responsible for carrying out following tasks:

  • Parsing of configuration files written in HCL(Hashicorp configuration language):

    It parses the the provided configuration files(.tf) into internal data structures necessary to process the management of resources mentioned in the file

  • Dependency graph calculation:

    It constructs the dependency graph to map out relationship between resources.

    It is essential as it helps terraform to understand the dependencies between the resources and plan the order of creation of resources appropriately.

    For example, in AWS, it creates VPC prior to launching EC2 instances even if EC2 instances are mentioned before VPC in configuration files.

  • Maintaining state file:

    Core also maintains a state file that contains the current status of the infrastructure managed by terraform.

    It is often used to compare the current state of infrastructure and desired state of infrastructure and draw a plan to launch or destroy infrastructure as required.

    Thus core handles the creation, update and deletion of resources and logs it in the state file.

  • Interaction with provisioners:

    Provisioners are scripts that Terraform runs on the target infrastructure during creation or destruction. Terraform Core manages these provisioners, ensuring they execute at the right time in the resource lifecycle.

  • Provider Interaction

    Terraform Core interacts with provider plugins, which are responsible for translating Terraform’s configuration into API calls to specific cloud platforms or services (AWS, Azure, Google Cloud, etc.).

    Provider plugins are downloaded and managed by Terraform Core during the terraform init process.

Provisioners:

Provisioners are scripts that terraform runs on the target resources after they are created or destroyed. Provisioners are often used to download the additional software configurations in the created resource to make it compatible to run an application. For example, install nginx whenever the the resource is created.

There are three type of provisioners:

1. Remote-Exec Provisioner

The remote-exec provisioner is used to run commands on a remote resource, such as an EC2 instance, after it has been created.

hclCopy codeprovider "aws" {
  region = "us-west-2"
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0" # Example AMI ID
  instance_type = "t2.micro"

  # Remote-Exec Provisioner to run commands on the instance after creation
  provisioner "remote-exec" {
    connection {
      type        = "ssh"
      user        = "ubuntu"
      private_key = file("~/.ssh/id_rsa") # Path to your private key
      host        = self.public_ip
    }

    inline = [
      "sudo apt-get update",
      "sudo apt-get install -y nginx",
      "sudo systemctl start nginx"
    ]
  }
}

The remote-exec provisioner updates the package list on an Ubuntu EC2 instance, installs Nginx, and starts the Nginx service.

2. Local-Exec Provisioner

The local-exec provisioner is used to run commands locally on the machine where Terraform is executed, rather than on the remote resource.

hclCopy codeprovider "aws" {
  region = "us-west-2"
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0" # Example AMI ID
  instance_type = "t2.micro"

  # Local-Exec Provisioner to log the instance's public IP address locally
  provisioner "local-exec" {
    command = "echo ${self.public_ip} > instance_ip.txt"
  }
}

The local-exec provisioner writes the public IP address of the EC2 instance to a file named instance_ip.txt on your local machine.

3. File Provisioner

The file provisioner is used to copy files or directories from your local machine to the remote resource.

hclCopy codeprovider "aws" {
  region = "us-west-2"
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0" # Example AMI ID
  instance_type = "t2.micro"

  # File Provisioner to upload a configuration file to the instance
  provisioner "file" {
    source      = "config/nginx.conf"
    destination = "/etc/nginx/nginx.conf"

    connection {
      type        = "ssh"
      user        = "ubuntu"
      private_key = file("~/.ssh/id_rsa") # Path to your private key
      host        = self.public_ip
    }
  }

  # Remote-Exec Provisioner to restart Nginx after the config file is uploaded
  provisioner "remote-exec" {
    connection {
      type        = "ssh"
      user        = "ubuntu"
      private_key = file("~/.ssh/id_rsa")
      host        = self.public_ip
    }

    inline = [
      "sudo systemctl restart nginx"
    ]
  }
}

The file provisioner uploads a local Nginx configuration file to the EC2 instance's /etc/nginx/ directory.

Providers:

Terraform Providers are plugins that enable Terraform to interact with the APIs of different cloud platforms and other services.

Providers handle the communication between Terraform and the platform’s API, allowing you to manage resources like virtual machines, databases, and networks.

Each cloud provider (AWS, Azure, GCP, etc.) has its own Terraform provider, which knows how to translate Terraform's declarative syntax into the specific API calls required by that platform.

Conclusion.

In conclusion, Terraform's architecture is designed to efficiently manage infrastructure as code by breaking down complex tasks into manageable components.

The Terraform CLI serves as the interface for developers, enabling them to interact with their infrastructure through simple commands.

Behind the scenes, Terraform Core drives the entire process, from parsing configuration files to managing the state of infrastructure and ensuring dependencies are respected.

Provisioners and Providers extend Terraform's capabilities by enabling it to execute scripts and interact with cloud platforms.

This modular approach allows Terraform to be both flexible and powerful, enabling DevOps teams to manage infrastructure efficiently across multiple platforms and environments.

10
Subscribe to my newsletter

Read articles from Ronit Vardhamane directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ronit Vardhamane
Ronit Vardhamane