# TerraWeek Day 3: Mastering Terraform Configuration, Provisioners, and Lifecycle Management

### Introduction

Terraform is a powerful tool for defining, provisioning, and managing infrastructure as code (IaC). On Day 3 of **TerraWeek**, I explored Terraform's capabilities by creating an AWS EC2 instance, configuring provisioners, managing lifecycle configurations, and using essential Terraform commands. This blog walks you through the tasks I accomplished, complete with explanations, code snippets, and key takeaways.

---

Github full code for Day-03 : [https://github.com/Amitabh-DevOps/TerraWeek/tree/feat/day03/day03](https://github.com/Amitabh-DevOps/TerraWeek/tree/feat/day03/day03)

---

## **Task 1: Define Resources with Terraform Configuration**

The first step was to create Terraform configuration files to define an AWS EC2 instance and its associated resources.

### Highlights:

1. **AWS Provider**:
    
    * Configured in `main.tf`, specifying the AWS region and provider version.
        
    
    ```bash
    provider "aws" {
      region = "us-east-1"
    }
    ```
    
2. **EC2 Instance Configuration**:
    
    * Defined in `ec2.tf`, using the latest Ubuntu AMI, a security group, and a key pair.
        
    * Included a provisioner to install and start Nginx automatically.
        
    
    ```bash
    resource "aws_instance" "my_instance" {
      ami           = "ami-0c02fb55956c7d316"
      instance_type = "t2.micro"
      key_name      = "terraweek_key"
      security_groups = ["my_terraweek_sg"]
    
      provisioner "remote-exec" {
        inline = [
          "sudo apt update",
          "sudo apt install -y nginx",
          "sudo systemctl start nginx",
          "sudo systemctl enable nginx"
        ]
        connection {
          type        = "ssh"
          user        = "ubuntu"
          private_key = file(var.aws_private_key_pair_name)
          host        = self.public_ip
        }
      }
    }
    ```
    
3. **Security Group**:
    
    * Configured to allow SSH, HTTP, and HTTPS traffic.
        
    
    ```bash
    resource "aws_security_group" "my_terraweek_sg" {
      ingress {
        from_port   = 22
        to_port     = 22
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
      # HTTP and HTTPS rules are added similarly
    }
    ```
    

---

## **Task 2: Validate Configuration and Check State Files**

### **State Files**

Terraform's state files (`terraform.tfstate`) track infrastructure resources. Before making changes, I reviewed the state files to ensure consistency between the configuration and actual resources.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1733490503127/3740e55f-9ef5-4254-aa10-ec73084437c2.png align="center")

### **Validation**

To validate the syntax and usability of my configuration files, I ran:

```bash
terraform validate
```

✅ Output: *Success! The configuration is valid.*

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1733490525173/6b2814d3-2312-474e-a48f-c0a12426aff8.png align="center")

### **Commands Used**

1. `terraform init`: Initialize Terraform.
    
2. `terraform plan`: Review planned changes.
    
3. `terraform apply`: Apply changes to create the resources.
    

---

## **Task 3: Provisioning Resources with Terraform**

A **remote-exec provisioner** was added to the EC2 instance to install Nginx automatically.

### Provisioner Code

```bash
provisioner "remote-exec" {
  inline = [
    "sudo apt update",
    "sudo apt install -y nginx",
    "sudo systemctl start nginx",
    "sudo systemctl enable nginx"
  ]
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1733490551992/c74a3f1b-b480-442e-8f4e-7ce0f8b9a706.png align="center")

### **Terraform Commands**

* **Apply changes**:
    
    ```bash
    terraform apply --auto-approve
    ```
    
* **Destroy resources**:
    
    ```bash
    terraform destroy
    ```
    

---

## **Task 4: Lifecycle Management**

Terraform's `lifecycle` block was added to manage how resources are created, modified, and destroyed.

### Lifecycle Configuration

```bash
lifecycle {
  create_before_destroy = true
  prevent_destroy        = false
  ignore_changes         = [tags]
}
```

### Key Features:

1. `create_before_destroy`: Prevents downtime by creating a new resource before destroying the old one.
    
2. `prevent_destroy`: Protects critical resources when set to `true`.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1733490595860/245ef94f-be40-4326-8d3c-d6ad0c509488.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1733490579258/9904a8a2-bbb7-4139-b0cb-1a324ce60277.png align="center")
    
3. `ignore_changes`: Prevents Terraform from modifying specific attributes like `tags`.
    

---

## **Key Takeaways**

* **Terraform State Files**: Crucial for maintaining consistency between infrastructure and configuration.
    
* **Provisioners**: Automate tasks like software installation post-deployment.
    
* **Lifecycle Management**: Offers fine-grained control over resource behavior during updates and deletions.
    
* **Essential Commands**:
    
    * `terraform init`
        
    * `terraform validate`
        
    * `terraform plan`
        
    * `terraform apply`
        
    * `terraform destroy`
        

---

## **Conclusion**

Terraform simplifies infrastructure management with its declarative syntax, state management, and robust provisioning capabilities. Day 3 of TerraWeek deepened my understanding of defining resources, configuring provisioners, and leveraging lifecycle blocks for better control.

Ready to dive into Terraform? Let’s Terraform your world!

---

What do you think about the tasks? Share your feedback or questions in the comments! 😊

---

**Connect with me**  
💻 Portfolio: [amitabh.engineer](https://amitabh.engineer)  
🌟 LinkedIn: [Amitabh soni](https://linkedin.com/in/amitabh-devops)
