TerraWeek Day 3

TerraWeek Day 3

Terraform Configuration and Resource Management

Task 1: Create a Terraform configuration file to define a resource of AWS EC2 instance

Provisioning resources on AWS has never been easier than with Terraform. Before we dive into the details, let's ensure you have the necessary prerequisites in place:

  1. AWS CLI Installation: The AWS Command Line Interface

    (AWS CLI) serves as a unified tool for managing your AWS services efficiently. It allows you to control multiple AWS services from the command line and automate tasks through scripts.

  2. AWS IAM User: AWS Identity and Access Management (IAM) is a pivotal service for securely controlling access to AWS resources. IAM helps manage authentication and permissions. To connect your AWS account with Terraform, you'll need to export your access keys and secret access keys to your local machine.

export AWS_ACCESS_KEY_ID=<access_key>
export AWS_SECRET_ACCESS_KEY=<secret_access_key>

💻AWS EC2 Instance Configuration Using Terraform

The heart of resource management in Terraform lies in the configuration.

Below is a snippet of the HCL (HashiCorp Configuration Language) file illustrating the setup of an AWS provider and the creation of an EC2 instance

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  required_version = ">= 1.2.0"
}
provider "aws" {
  region = "us-east-1"
}
resource "aws_instance" "my_terraform_ec2_instance" {
  count         = 1
  ami           = "ami-053b0d53c279acc90"
  instance_type = "t2.micro"

  tags = {
    Name = "Terraform-Ec2-instane"
  }
}

In this configuration:

  • The provider block establishes the connection to AWS using your access key & secret access key(already exported), and preferred region.

  • The resource block defines the creation of an EC2 instance. You must specify the AMI ID, instance type, etc...

  • Tags are used to assign metadata to the EC2 instance, facilitating easy identification.

Task 2: Check State Files and Validate Configuration

Before running any Terraform commands, let's check the state files and validate our configuration.

✔Initialize/Plan/Apply Terraform

Open your terminal and navigate to the directory containing main.tf. Initialize Terraform by running the following command:

terraform init

✔Check State Files

Terraform maintains state files to track the current state of your infrastructure. Let's check the state files using the terraform state command

terraform state list

This should show an empty list (In case no configuration applies)

✔Validate Configuration

Use the terraform validate command to check your configuration for syntax errors:

terraform validate

⚓Resource Dependencies

Resource dependencies are pivotal in determining the sequence of actions when creating, updating, or destroying resources.

Terraform automatically identifies these dependencies based on your configuration, but you can also explicitly define them using the depends_on argument.

For instance, you can establish a dependency between an AWS EC2 instance and a security group like this, and update the main.tf file with below & then apply again

resource "aws_security_group" "example" {
  name = "example"
}

resource "aws_instance" "EC2-Instance" {
  ami = "ami-053b0d53c279acc90"
  instance_type = "t2.micro"
  vpc_security_group_ids = ["${aws_security_group.example.id}"]
  depends_on = [aws_security_group.example]
}

Updated main.tf

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

resource "aws_instance" "my_terraform_ec2_instance" {
  count         = 1
  ami           = "ami-0b0ea68c435eb488d"
  instance_type = "t2.micro"
  vpc_security_group_ids = ["${aws_security_group.http_access.id}"]
  depends_on = [aws_security_group.http_access]


  tags = {
    Name = "Terraform_EC2-Instance"
  }
}

output "instance_id" {
  description = "ID of the EC2 instance"
  value       = aws_instance.my_terraform_ec2_instance[0].id
}

resource "aws_security_group" "http_access" {
  name = "http_access"
  description = "Allow HTTP access"
}

Task 3: Add a Provisioner

Terraform's provisioners enable you to execute actions or scripts on resource instances during their creation or destruction.

This functionality is crucial for tasks like software installation, package management, and configuration setup.

Here's an example of using a remote-exec provisioner to execute commands on an EC2 instance:

provider "aws" {
  access_key = "<YOUR_AWS_ACCESS_KEY>"
  secret_access_key = "<YOUR_AWS_SECRET_ACCESS_KEY>"
  region = "us-east-1"
}

resource "aws_instance" "example" {
  ami = "ami-0c94855ba95c71c99"  # Replace with your desired AMI ID
  instance_type = "t2.micro"
  key_name = "my-key-pair"


  tags = {
    Name = "example-instance"
  }

  provisioner "remote-exec" {
    inline = [
      "echo 'Hello, World!'",
      "echo 'This is a provisioner example.'"
    ]
  }
}

In this example, we've added a provisioner of type remote-exec to the aws_instance resource. Here's a breakdown of the changes:

  1. After the tags block, we've added a provisioner block to define the provisioner.

  2. The remote-exec provisioner type executes commands remotely on the newly created EC2 instance.

  3. Inside the remote-exec block, the inline argument is used to specify the commands that will be executed on the EC2 instance. In this case, we're echoing two messages.

Once you have added the provisioner, you can use Terraform commands to manage your infrastructure:

  • terraform init: Initializes the Terraform project.

  • terraform plan: Generates an execution plan showing the proposed changes to the infrastructure.

  • terraform apply: Applies the changes defined in the Terraform configuration and provisions the resources. This includes the creation of the EC2 instance and the execution of the provisioner commands.

  • terraform destroy: Destroys all the resources created by Terraform. This will remove the EC2 instance and any associated resources.

Task 4: Add Lifecycle Management

📌Lifecycle Management

Terraform's lifecycle management allows you to control resource behavior, specifying how resources should be created, updated, or destroyed based on specific conditions. Several settings are available:

  • create_before_destroy: Specifies whether to create a new resource before destroying the existing one, useful for minimizing downtime during transitions.

  • prevent_destroy: Prevents a resource from accidental deletion, protecting critical resources.

  • ignore_changes: Allows you to ignore specific attribute changes during updates to prevent unintended modifications.

  • timeouts: Defines the maximum time Terraform should wait for resource creation or deletion.

📌Lifecycle Configuration

Edit your main.tf file to add a lifecycle block:

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

resource "aws_instance" "example" {
  ami = "ami-0c94855ba95c71c99"  # Replace with your desired AMI ID
  instance_type = "t2.micro"
  key_name = "my-key-pair"


  tags = {
    Name = "example-instance"
  }

  lifecycle {
    prevent_destroy = true
  }
}

The prevent_destroy setting ensures that a terraform will not allow the deletion of an EC2 instance

Once you have added the lifecycle management configurations, you can use Terraform commands to manage your infrastructure:

  • terraform init: Initializes the Terraform project.

  • terraform plan: Generates an execution plan showing the proposed changes to the infrastructure.

  • terraform apply: Applies the changes defined in the Terraform configuration and provisions the resources. The lifecycle configurations will control the creation, modification, and deletion of the resource according to the specified behavior.

  • terraform destroy: Destroys all the resources created by Terraform. This will remove the EC2 instance and any associated resources.

Hashnode: https://hashnode.com/@NileshSahare

LinkedIn: www.linkedin.com/in/nilesh-sahare-102325148

Happy Learning :)

If you find my blog valuable, I invite you to like, share, and join the discussion. Your feedback is immensely cherished as it fuels continuous improvement. Let's embark on this transformative DevOps adventure together! 🚀