Variable in Terraform

Variables in Terraform

We create a file variables.tf, put the values for our configuration which can change or vary. Makes it useful to make your config more dynamic, reusable and flexible.

Variables is used for parameterized, can use as pramsT to pass volume values to projects. In terraform we don’t prefer hardcode of values, whose values may vary; this approach helps to use the configuration file of terraform to use in production.

Variables are of 2 types

  1. Input variables: They help to pass values into your modules or config from outside.

    Input variables can be defined within a module or at root level of config. Leads to help in parameterizing your terraform config.

  2. Output variables: It will start with keyword output. We will get output once we will use apply command. Output Variables display or share information about your Terraform-managed infrastructure.

    Example below: We have used an asterisk so that every instance will display its public IP as output.

     resource "aws_instance" "example" {
       ami           = "ami-123456"
       instance_type = "t2.micro"
     }
    
     output "instance_id" {
       description = "The ID of the instance"
       value       = aws_instance.example.id
     }
    

Data block in Terraform

In Terraform, a data block is used to fetch or reference information that is already available in your infrastructure or from external sources. This allows you to use existing resources without having to recreate them. Data blocks are useful for reading information like AMI IDs, VPC IDs, or other resource attributes that you might need in your configuration.

Here's an example of a data block in Terraform:

data "aws_ami" "os_image" {
  most_recent = true
  filter {
    name = "state"
    values = ["available"]
  }

    filter {
        name   = "name"
        values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-20.08-amd64-server-*"]
    }
}

You can put the owner too if you face the warning

Go to your EC2 dashboard -> AMI IDs (paste your AMI ID that you get when running the command $terraform plan)

We use a data block for AMI ID configuration because if your config file is written with an old AMI ID, it might cause functionality issues. By providing the latest available AMI ID, we ensure that our machine stays up to date.

State Management in Terraform

Terraform stores all the information about its state in the terraform.tfstate file.

Whatever resources you create on any platform, like AWS, you can view a summary locally, including the instance state. Instance state is see the current state of resources on local.

Example: After running terraform apply, we have 4 instances running in EC2.

  1. terraform state list: List all the instance running

  1. terraform state show: This command provides details about the Terraform state.

  2. We stopped 1st instance

  1. We need to sync our local Terraform state with changes on AWS for the instance, so we use the command

     terraform apply -refresh-only
    

    Since our EC2 instance has been stopped, you will notice that the public IP of the first instance is empty. This is because when you stop an instance, the public IP is no longer visible.

  2. This is how we can sync the changes made directly on AWS. These steps apply to Terraform with AWS or any other resources. So, we need to ensure we sync the changes that have been made.

Terraform.tfstate

It stores all the sensitive information about your infrastructure, such as resource IDs, IP addresses, and other metadata. This file is crucial for Terraform to understand the current state of your infrastructure and to make updates accurately. It's important to keep this file secure and backed up, as losing it can lead to difficulties in managing your resources. Additionally, when working in teams, you should use a remote backend to store the terraform.tfstate file to ensure consistency and collaboration.

S3 helps in storing the terraform.tfstate file securely and reliably. By using S3 as a remote backend, teams can ensure consistency and collaboration, as it allows multiple users to access and update the state file without conflicts.

State Locking in Terraform with DynamoDB and S3

  • State Locking: Prevents multiple users from making changes at the same time.

  • DynamoDB: Used to lock the state file, ensuring only one operation happens at a time.

  • S3: Stores the state file securely, allowing team access and updates.

  • Benefits: Avoids conflicts and ensures smooth collaboration.

In state locking, we keep a single source of truth in an S3 bucket. However, since anyone can access S3, we use a DynamoDB table to maintain a lock ID. This lock ID stores details about the user accessing the state file. Until these details are released, no other DevOps engineer can access the state file or execute the terraform apply command.

Terraform-backend folder

We create different folder to store backend infrastructure

Stores: Dynamo db and S3 bucket configuration

In terraform-backend folder we are using three file

  1. backend_infra.tf
resource "aws_s3_bucket" "my_bucket" {
  bucket = var.aws_s3_bucket
  tags = {
    Name = "tws-junoon-state"
  }
}

resource "aws_dynamodb_table" "my_dynamo_table" {
  name = var.aws_dynamodb_table
  billing_mode = "PAY_PER_REQUEST"
  hash_key = "LockID"
  attribute {
    name = "LockID"
    type = "S"    #for string 
  }
  tags = {
    Name = var.aws_dynamodb_table
  }
}
  1. variables.tf
variable "aws_region" {
  description = "aws region"
  default = "eu-west-1"

}

variable "aws_s3_bucket" {
  description = "AWS backend bucket name"
  default = "tws-junoon-state-amit"
}

variable "aws_dynamodb_table" {
  description = "AWS backend dynamo table name"
  default = "tws-junoon-state-table-amit"
}
  1. terraform.tf
terraform {
  required_providers {
    aws = {
        source = "hashicorp/aws"
        version = "~> 5.0"
    }
  }
}

# Configure the AWS Provider
provider "aws" {
  region = var.aws_region
}

Steps to execute:

  1. terraform init

  2. terraform plan

  3. terraform apply -auto-approve :

What is dynamoDB?

It's a NoSQL database that not only supports SQL-like queries but also offers other functionalities. It doesn't rely on traditional table relationships or a defined schema.

In DynamoDB, we used the "PAY_PER_REQUEST" billing mode. This means you only pay for the resources you use, nothing more.

HashKey: Similar to a user ID, we have LockID in DynamoDB. LockID will be created as an attribute (column name).

Back to terraform folder -

To maintain terraform state file. work on terraform level; want to manage state for terraform.

Need to do state management for terraform and add remote backend.

Q. What is remote backend?
A remote backend is where our state file is stored remotely, such as in an S3 bucket. This allows multiple users to access and manage the state file collaboratively.

Create a backend block in terraform.tf file

We use terraform provider block in terraform.tf file → will add backend block. Backend is based on s3 bucket, will use the bucket name

Our reformed code look like this

terraform {
  required_providers {
    aws = {
        source = "hashicorp/aws"
        version = "~> 5.0"
    }
  }
  backend "s3" {
    bucket = "tws-junoon-state-amit"
    key = "terraform.tfstate"
    region = "eu-west-1"
    dynamodb_table = "tws-junoon-state-table-amit"
  }
}

After making changes on terraform level we need initialize terraform again with

terraform init // command

It will help to sync terraform with our S3 bucket (backend)

We can see that initializing the backend means the backend is now created on S3. By default, the backend is local.

What happens if you delete the terraform.tfstate file and its backup file too?

Try to write command $terraform state list it will still show the states, because now our tfstate file is present on s3 bucket.