What is Idempotency in Terraform and Ansible

What is Idempotency in Terraform and Ansible

Introduction:

In this article, you'll see what is idempotency and why we need an idempotent tool to implement infrastructure as code(IaC).

What is Terraform:

Terraform is an infrastructure as a code (IaC) tool. We can provision the cloud infrastructure using Terraform code.

What is Ansible:

Ansible is an automation tool. It's mainly used for configuration automation.

Let's provision the infrastructure:

Here is a python script to create a simple EC2 instance.

Filename: ec2.py

import boto3

ec2 = boto3.client('ec2', 'us-east-1')

my_instance = ec2.run_instances(InstanceType="t2.micro", 
                                MaxCount=1,
                                MinCount=1,    
                                ImageId="ami-0b5eea76982371e91")

After running this script, we can list all of the created instances using this python script.

Filename: count.py

import boto3

ec2 = boto3.client('ec2', 'us-east-1')

count = 0
instances = ec2.describe_instances()

# Iterate through the reservations
for reservation in instances['Reservations']:
    # Iterate through the instances in each reservation
    for instance in reservation['Instances']:
        # check if the instance state is not terminated
        if (instance["State"]["Name"] != 'terminated'):
            count += 1

print(count)

After running this script you'll see the following output.

Now let's run the ec2.py script again. This will be going to create one more instance. And after creating the instance let's run count.py and you will see the following output.

This method of creating EC2 instances follows a declarative syntax because we are specifying each and every step that needs to be performed. However, this is not the same in the case of Terraform. The Terraform follows an imperative syntax. That means in Terraform unlike python we don't define each and every step to perform and what API calls to make. Instead, we define the desired state of our infrastructure. And the Terraform figures out on its own what steps to perform to meet the requirements.

Now terminate the existing EC2 instances and let's create a Terraform file to provision an ec2 instance.

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "4.51.0"
    }
  }
}

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

resource "aws_instance" "web" {
  ami           = "ami-0b5eea76982371e91"
  instance_type = "t2.micro"
}

After doing a 'terraform init' and 'terraform apply' you can see that a single instance is created. Now, what if you run 'terraform apply' again? Is it going to create another instance? The answer is no. The Terraform compares the code with the actual infrastructure state and only performs an action when something needs to be changed. So if you run the 'ec2.py' script a hundred times it will create a hundred EC2 instances. But no matter how many times you execute the same terraform config file again and again the infrastructure will remain the same unless you change the code. Idempotency is a property of some operations such that no matter how many times you execute them, you achieve the same result. So in the Terraform, we will receive the same result regardless of the execution count, that's why the Terraform is said to be idempotent.

The same logic also applies to ansible. The ansible also follows the imperative syntax similar to the Terraform. We can define our desired configurations inside ansible playbooks. And then the ansible compares the desired state with the current state. The ansible performs necessary actions only when the desired state differs from the current state.

Importance of idempotent tools:

Assume that you have created an EC2 instance using a python script. And after a few days, you realized that the instance is running out of storage so you need to increase the EBS volume capacity. If you go to the script that you've created the instance with and change the EBS volume type and execute the script it's going to create a new instance instead of modifying the existing EBS volume.

To avoid this from happening you may need to manually change the EBS volume size or create a new script to perform this task. But this is a big problem if you want to automate your infrastructure. Here idempotent tools come to the rescue. Because of the idempotency of Terraform, you can simply change the EBS volume size and then apply the configs. The Terraform will compare the desired state with the current state and will simply scale the EBS volume instead of creating a new instance.

So the conclusion is that the idempotent tools are very crucial for infrastructure automation.