Terraform Basics 🔥

·

9 min read

What is Infrastructure as Code (IaC)?

  • Infrastructure as Code (IaC) is an approach to provisioning and managing infrastructure resources using machine-readable configuration files or scripts.

  • It treats infrastructure configuration in the same way as application code.

  • IaC enables infrastructure to be defined, versioned, and deployed through automation.

  • Declarative configuration files describe the desired state of the infrastructure, specifying resources, properties, relationships, and dependencies.

  • Infrastructure configurations are stored in version control systems like Git, facilitating collaboration, change tracking, and rollback to previous versions.

  • IaC tools automate the provisioning and management of infrastructure resources, reducing manual effort and increasing repeatability.

  • There are several popular tools and frameworks available for implementing Infrastructure as Code out of which Terraform is one of the popular IaC tools.

  • In Terraform we write the configuration file using HashiCorp Configuration Language (HCL).

Here's a list of some of the most popular IaC tools: Terraform, AWS CloudFormation, Ansible, puppet, chef,

What is Terraform?

Terraform is an open-source infrastructure as code (IaC) software tool created by HashiCorp. It allows you to create, manage, and update infrastructure resources such as virtual machines, networks, and storage in a repeatable, scalable, and automated way.

We write terraform scripts using Hasicorp configuration language or HCL and it is a declarative language, meaning you just have to define what end result you want. It's not much about remembering syntax.

This language allows you to describe the desired state of your infrastructure, specifying resources, their configurations, dependencies, and relationships. The Terraform configuration files define the infrastructure as code, which can be version-controlled, shared, and collaboratively developed.

What is HCL?

  • HCL stands for HashiCorp Configuration Language. It is the language used in Terraform for defining infrastructure configurations and resources.

  • HCL is a declarative language designed to be easy to read and write, allowing users to express their infrastructure requirements in a human-friendly and intuitive manner.

  • HCL is specifically created for managing infrastructure as code and provides a structured and concise syntax for defining resources, their configurations, and their relationships.

  • It enables users to describe the desired state of their infrastructure in a Terraform configuration file, which is typically named with the .tf extension.

Why do we use terraform?

Here are some reasons why Terraform has gained popularity among engineers and DevOps teams:

Infrastructure as Code (IaC): Terraform allows you to define your infrastructure as code using a declarative language. This means you can write configuration files that describe the desired state of your infrastructure, and Terraform will automatically create and manage the resources accordingly. This approach improves consistency, repeatability, and reduces the risk of manual errors.

Multi-Cloud Support: Terraform is cloud-agnostic and supports multiple cloud providers, including AWS, Azure, Google Cloud Platform, and more. This allows organizations to adopt a multi-cloud strategy and manage infrastructure across different cloud environments using a single tool.

Automation and Efficiency: With Terraform, infrastructure provisioning and management tasks can be automated, reducing manual effort and human error.

Infrastructure Lifecycle Management: Terraform handles the entire lifecycle of infrastructure, from provisioning to scaling and even destruction. With Terraform, you can easily manage infrastructure changes, enforce best practices, and enable efficient collaboration among teams.

State Management: Terraform maintains a state file that keeps track of the actual resources created in the cloud. This state file allows Terraform to understand the current state of the infrastructure and make necessary changes to achieve the desired state.

Version Control and Auditing: Terraform code is stored in version control systems like Git, providing versioning and auditing capabilities. This allows teams to track changes, collaborate effectively, and roll back to previous configurations if needed.

Why Terraform?

Terraform offers extensive support for various cloud providers, allowing organizations to manage infrastructure across different environments seamlessly, enabling multi-cloud or hybrid strategies.

HCL supports a declarative approach to infrastructure provisioning. This is also the reason to learn and use Terraform as it is easy to understand also.

Terraform Workflow

Terraform workflow consists of three stages:

  1. Write

Here we write a configuration to define the resources for managing the infrastructure among various cloud platforms.

  1. Plan

Terraform will create an execution plan describing the infrastructure it will create, update, or destroy based on the configuration we wrote.

  1. Apply

Terraform will then apply those plans and perform those actions.

Important Terminologies in Terraform

Providers:

A provider is a plugin that lets Terraform manage an external API. When we run terraform init, plugins required for the provider are automatically downloaded and saved locally to a .terraform directory. Terraform supports multiple providers. Depending on what type of infrastructure we want to launch, we have to use appropriate providers accordingly.

 provider "aws" {
     region = "us-east-1"
  }

Resources:

Resource block describes one or more infrastructure objects.

Example: resource aws_instance, resource aws_alb, resource iam_user, resource digitalocean_droplet

A resource block declares a resource of a given type ("aws_instance") with a given local name ("aws_ec2_test"). Resource type and Name together serve as an identifier for a given resource and so must be unique.

resource "aws_instance" "devops_instance" {
count = 2
ami="<ami-id>"

instance_type = "t2.micro"

tags = {
Name = "devops_terraform_instance"
}
}

Module

  • A module is a reusable unit of infrastructure configuration. It encapsulates a set of resources and configurations that can be used to create and manage infrastructure components.

  • Modules promote modularity, code reuse, and maintainability by abstracting complex configurations into manageable units.

  • Modules can be used across different projects or shared within a team, making infrastructure configurations more maintainable and scalable.

        module "dev-app"{
           source = "./modules/my-app"
           my_environment = "dev"
           ami = "<ami-id>"
           instance_type = "t2.micro"
           instance_name = "demo"
           bucket_name = "demo-bucket-my-app"
           dynamo_table_name = "demo-table-my-app"
        }
    

Output

  • Outputs are values that are derived from the Terraform configuration and can be used to provide information about the infrastructure to external systems or users.

  • Outputs are typically used to expose important details such as IP addresses, URLs, or resource identifiers for reference or consumption by other components.

  • They are useful for sharing important information with other parts of your infrastructure or with users who need to access or interact with the provisioned resources.

        output "my_ec2_ip"{
          value = aws.instance.my_instance[*].public_ip
        }
    

State

  • The state in Terraform represents the current state of the infrastructure being managed. It is a record of the resources and their configurations defined in the Terraform configuration files.

  • The state file contains metadata about resources, their attributes, dependencies, and relationships.

  • Terraform uses this state file to understand the existing infrastructure, track changes, and plan and execute updates in a controlled manner.

        {
          "api_key": "",
          "bucket": "cf-s3-...", 
          "location_constraint": "eu-west-1",
          "endpoint": "s3-eu-west-1.amazonaws.com",
          "secret_key": "",
          "uri": "s3://..."
        }
    

Backend

  • The backend in Terraform defines where Terraform state files are stored. This can be a local file system, remote storage services like Amazon S3 or Azure Blob Storage, or a version control system like Git.

  • The backend configuration determines how the state is accessed and shared among team members.

        terraform {
          backend "remote" {
            organization = "example_corp"
    
            workspaces {
              name = "my-app-prod"
            }
          }
        }
    

Components of HCL

Blocks

  • HCL organizes configurations into blocks, which are enclosed within curly braces {}.

  • Blocks define different aspects of the configuration, such as the provider, resource, variable, or output. Each block has a specific purpose and contains configuration settings specific to that block type.

Arguments

  • Within blocks, you define arguments to set the configuration values for resources or other block types.

  • Arguments are specified using the key = value syntax, where the key represents the configuration setting name and the value represents the desired value for that setting.

    Here's an example of an aws_instance block with parameters and arguments:

        resource "aws_instance" "example" {
          instance_type = "t2.micro"
          ami           = "ami-0c94855ba95c71c99"
        }
    

Variables

  • Variables in HCL are used to parameterize configurations and provide flexibility. They allow you to define placeholders for values that can be assigned from external sources or passed as input to your configuration.

  • Variables are defined using the variable block and can have a default value or be defined as required.

        variable "region" {
          type    = string
          default = "us-west-2"
        }
    

Expressions and Interpolation

  • HCL supports expressions and interpolation, allowing you to dynamically generate or reference values within the configuration.

  • Expressions can be used to perform calculations, concatenate strings, or define conditional logic. Interpolation is used to reference values of variables or attributes of resources within other parts of the configuration.

        resource "aws_instance" "example" {
          instance_type = var.instance_type
          ami           = data.aws_ami.ubuntu.id
        }
    

Blocks Within Blocks

  • HCL allows the nesting of blocks within other blocks to define hierarchical relationships and configurations. This enables you to express more complex infrastructures and relationships between resources.

        resource "aws_vpc" "main" {
          cidr_block = "10.0.0.0/16"
    
          tags = {
            Name = "main-vpc"
          }
    
          subnet {
            cidr_block = "10.0.1.0/24"
            availability_zone = "us-west-2a"
          }
        }
    

Comments

  • HCL allows you to include comments within the configuration files to provide explanations, document decisions, or add any relevant information.

  • Single-line comments start with '#' and multi-line comments are enclosed within /* */.

        # This is a single-line comment
    
        /*
        This is a multi-line comment.
        It can span multiple lines.
        */
    

Task 1: Install Terraform on your system

  1. Create an EC2 instance and SSH into it.

  2. Visit the official Terraform website to get the installation step.

    Install Terraform

  3. For our EC2 Linux machine installation follow the below command:

      sudo apt-get update
    
      wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
    
      echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
    
      sudo apt update && sudo apt install terraform
    

  4. Verify that Terraform is installed correctly by running the following command:

      terraform --version
    

What is a State file in Terraform? What’s the importance of it?

In Terraform, a state file is a JSON-formatted file that keeps track of the current state of your infrastructure. It records the metadata and attributes of the resources managed by Terraform, including their dependencies and relationships. The state file is created and updated by Terraform during the execution of terraform apply or terraform import commands.

The "terraform refresh" command will check the latest state of your infrastructure and update the state file accordingly.

What is the Desired and Current State?

In Terraform, the desired state refers to the configuration that you have defined in your Terraform files (*.tf) to describe the infrastructure resources you want to create and manage. It represents the ideal or intended state of your infrastructure. The desired state is defined in terms of resource types, attributes, dependencies, and other configurations.

On the other hand, the current state refers to the actual state of your infrastructure resources as tracked and recorded in the Terraform state file. It reflects the current state of the resources provisioned by Terraform, including their attributes, relationships, and dependencies. The current state is updated and managed by Terraform during the execution of the Terraform apply or Terraform import commands.

Thank you for reading this blog. If you found this blog helpful, please like, share, and follow me for more blog posts like this in the future.

— Happy Learning !!!

Let’s connect !!!

Linkedin

Medium

Github

Mail

Â