Terraform Associate: Change Infrastructure

A Step-by-Step Guide to Updating, Applying, and Managing Your Cloud Infrastructure

Terraform Associate: Change Infrastructure

In today’s fast-paced DevOps landscape, managing and evolving your infrastructure efficiently is crucial. Infrastructure as Code (IaC) tools like Terraform have revolutionized the way we provision and manage resources across cloud platforms. In this blog post, we’ll walk you through the process of changing your infrastructure with Terraform—from modifying configuration files to applying and verifying updates.

Why Use Terraform for Infrastructure Changes?

Terraform enables you to describe your infrastructure using configuration files, making it:

  • Predictable: Changes are planned before they’re applied.

  • Automated: Repeatable processes reduce human error.

  • Versioned: Configuration files can be tracked using version control systems.

  • Scalable: Easily manage infrastructure across multiple providers.

Terraform compares your current infrastructure state with your updated configuration, calculates the differences, and applies the necessary changes. This ensures that your live environment always matches your intended state.

Step 1: Modify Your Configuration Files

The first step in changing your infrastructure with Terraform is to update your configuration files (typically with a .tf extension). These files define the resources, their configurations, and how they relate to each other.

Example Scenario

Imagine you initially deployed an EC2 instance with a t2.micro instance type. Now, you want to upgrade the instance to t2.medium and add a security group rule to allow HTTP traffic (port 80) in addition to SSH.

Initial Configuration

Below is an example of the initial configuration that creates an EC2 instance and a security group that only allows SSH traffic:

provider "aws" {
  region = "us-west-2"
}

resource "aws_security_group" "allow_ssh" {
  name        = "allow_ssh"
  description = "Allow SSH inbound traffic"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  key_name      = "my-key-pair"

  security_groups = [aws_security_group.allow_ssh.name]
}

Updated Configuration

To reflect the changes you want:

  1. Change the EC2 instance type from t2.micro to t2.medium.

  2. Add a new security group rule for HTTP traffic on port 80.

The updated configuration might look like this:

resource "aws_security_group" "allow_ssh_http" {
  name        = "allow_ssh_http"
  description = "Allow SSH and HTTP inbound traffic"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.medium"  # Changed instance type from t2.micro to t2.medium
  key_name      = "my-key-pair"

  security_groups = [aws_security_group.allow_ssh_http.name]  # Referencing the updated security group
}

By modifying these configuration files, you define the desired state of your infrastructure.

Step 2: Preview Changes with terraform plan

Before making any actual changes, it’s important to review what Terraform intends to do. The terraform plan command compares your current state (stored in the terraform.tfstate file) with your updated configuration, then outputs a detailed plan.

Run the following command in your terminal:

terraform plan

What to Look For

The output will list the resources that will be created, modified, or destroyed. For example:

# aws_instance.example will be updated in-place
~ resource "aws_instance" "example" {
      ami                    = "ami-0c55b159cbfafe1f0"
  ~ instance_type           = "t2.micro" -> "t2.medium"
    }

# aws_security_group.allow_ssh_http will be created
+ resource "aws_security_group" "allow_ssh_http" {
      ...
    }

This preview confirms:

  • The EC2 instance's type will change from t2.micro to t2.medium.

  • A new security group (allow_ssh_http) will be created.

Step 3: Apply the Changes with terraform apply

After reviewing the plan and ensuring everything is as expected, apply the changes using:

terraform apply

Terraform will re-display the plan and prompt you for confirmation. Type yes to proceed:

Plan: 1 to add, 1 to change, 0 to destroy.
  Do you want to perform these actions? 
  Only 'yes' will be accepted to approve.
  Enter a value: yes

Once confirmed, Terraform will:

  • Update the EC2 instance to the new t2.medium instance type.

  • Create the new security group with both SSH and HTTP rules.

  • Attach the updated security group to the EC2 instance.

Step 4: Verify the Changes

After the terraform apply completes successfully, it’s essential to verify that your changes have been implemented correctly. You can do this by:

  • Checking the AWS Console (or your cloud provider’s dashboard):

    • Confirm that the EC2 instance is now of type t2.medium.

    • Verify that the new security group (allow_ssh_http) exists with the appropriate rules.

    • Ensure the EC2 instance is associated with the updated security group.

Step 5: Managing Terraform State

Terraform uses a state file (terraform.tfstate) to keep track of your infrastructure’s current state. Every time you apply changes, Terraform updates this file.

Best Practices for State Management:

  • Remote Backends: For team environments or production, store your state file in a remote backend (e.g., AWS S3 with DynamoDB for state locking, Terraform Cloud, etc.).

  • State Backups: Regularly back up your state file to avoid potential data loss.

  • Version Control: Keep your configuration files in version control to track changes over time.

Step 6: Handling Resource Destruction and Lifecycle

Certain changes in Terraform require the destruction and recreation of resources. For example, modifying immutable attributes (like changing an AMI for an EC2 instance) might force Terraform to destroy the existing resource and create a new one.

Preventing Unwanted Destruction

To prevent accidental destruction of critical resources, Terraform provides lifecycle blocks. For instance, you can prevent a resource from being destroyed during updates:

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

  lifecycle {
    prevent_destroy = true  # Prevents destruction of this resource
  }
}

By carefully reviewing the terraform plan output and using lifecycle configurations, you can control how Terraform handles resource changes.

Conclusion

Changing your infrastructure with Terraform is a systematic process that enhances both the reliability and predictability of your cloud environment. By following these steps:

  1. Modify Your Configuration Files: Update your .tf files to reflect the desired changes.

  2. Run terraform plan: Preview the changes and verify the impact on your infrastructure.

  3. Run terraform apply: Apply the changes and update your live environment.

  4. Verify the Changes: Confirm that your updates are reflected in your cloud provider’s dashboard.

  5. Manage Your State: Ensure that your Terraform state is stored safely and managed effectively.

  6. Handle Resource Lifecycle: Use lifecycle blocks to control the destruction and recreation of critical resources.

Terraform abstracts much of the underlying complexity, enabling you to manage infrastructure changes with confidence. Whether you’re scaling resources, updating configurations, or rolling out new features, Terraform ensures your infrastructure remains automated, predictable, and repeatable.

Happy provisioning!

Reference

  1. Terraform: Infrastructure as Code Introduction
    An excellent starting point to understand the fundamentals of Terraform and its approach to managing infrastructure as code.

  2. Terraform AWS Provider Documentation
    Detailed documentation on configuring and managing AWS resources with Terraform, including examples similar to those in the blog.

  3. Terraform State Management
    Learn how Terraform handles state files, best practices for managing state, and the importance of remote backends.

  4. Terraform Plan and Apply: Preview and Execute Changes
    A tutorial that walks you through the process of using terraform plan and terraform apply to implement infrastructure updates safely.

  5. Terraform Best Practices
    Guidance on optimizing your Terraform workflow, including strategies for version control, state management, and resource lifecycle handling.