Terraform State Migration: Local Backend to Terraform Cloud

Terraform State Migration: Local Backend → Terraform Cloud
Terraform Terraform Cloud AWS

📘 Terraform State Migration: Local Backend → Terraform Cloud

Project Topic: Migrate Terraform State from Local Machine to Terraform Cloud

Table of Contents

🎯 Objective

The goal of this project is to provision AWS infrastructure using Terraform with a local state file, then migrate that state to Terraform Cloud and continue managing the infrastructure remotely.

This project demonstrates:

  • Terraform backend migration
  • Terraform Cloud authentication
  • Workspace-based state management
  • Safe continuation of infrastructure after migration

🧩 Prerequisites

Before starting this project, the following are required:

  • An active Terraform Cloud account
  • A Terraform Cloud Organization
  • AWS account with programmatic access
  • Terraform CLI installed locally
  • AWS CLI configured locally (~/.aws/credentials)
  • Git & GitHub

🛠️ Project Structure

migrate-state-cloud/
├── ami-datasource.tf
├── apache-install.sh
├── main.tf
├── outputs.tf
├── variables.tf
├── versions.tf

1️⃣ Infrastructure Configuration Files

ami-datasource.tf

This file dynamically fetches the latest Amazon Linux 2 AMI using a Terraform data source.

data "aws_ami" "amzlinux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-gp2"]
  }

  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }
}

versions.tf

Defines Terraform version and AWS provider. The remote backend is initially commented out to allow local state creation first.

terraform {
  required_version = "~> 1.6"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }

  # backend "remote" {
  #   hostname     = "app.terraform.io"
  #   organization = "<YOUR_ORG_NAME>"
  #
  #   workspaces {
  #     name = "state-migration"
  #   }
  # }
}

Provider configuration:

provider "aws" {
  region = var.aws_region
}

main.tf

Creates SSH + Web security groups and an EC2 instance with Apache installed.

resource "aws_instance" "my-ec2-demo" {
  ami           = data.aws_ami.amzlinux.id
  instance_type = var.instance_type
  count         = 1

  user_data = file("apache-install.sh")

  vpc_security_group_ids = [
    aws_security_group.vpc-ssh.id,
    aws_security_group.vpc-web.id
  ]

  tags = {
    Name = "Terraform-state-migration-${count.index}"
  }
}

variables.tf

variable "aws_region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  default     = "t2.micro"
}

apache-install.sh

Installs and starts Apache on the EC2 instance.

#!/bin/bash
yum update -y
yum install -y httpd
systemctl enable httpd
systemctl start httpd

echo "<h1>Welcome! Infrastructure provisioned with Terraform</h1>" \
> /var/www/html/index.html

outputs.tf

output "ec2_instance_publicip" {
  value = aws_instance.my-ec2-demo.*.public_ip
}

output "ec2_publicdns" {
  value = aws_instance.my-ec2-demo.*.public_dns
}

2️⃣ Provision Infrastructure Locally

Run the following Terraform commands:

terraform init
terraform validate
terraform plan
terraform apply -auto-approve

This creates:

  • Local state file (terraform.tfstate)
  • One EC2 instance in AWS

3️⃣ Create Terraform Cloud Workspace (CLI-Driven)

  1. Log in to Terraform Cloud
  2. Select Organization
  3. Create New Workspace
  4. Choose CLI-Driven Workflow
  5. Name workspace: state-migration

4️⃣ Configure Remote Backend

Uncomment and update the backend block in versions.tf:

backend "remote" {
  hostname     = "app.terraform.io"
  organization = "YOUR_ORG_NAME"

  workspaces {
    name = "state-migration"
  }
}

5️⃣ Migrate State to Terraform Cloud

Authenticate:

terraform login

Re-initialize:

terraform init

When prompted:

Copy existing state to the new backend?
Type yes

✅ State is now stored in Terraform Cloud.

6️⃣ Configure AWS Credentials in Terraform Cloud

In Terraform Cloud workspace → Variables:

Environment Variables (Sensitive ✅)

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

7️⃣ Verify State Migration

Backup and delete local state:

cp terraform.tfstate terraform.tfstate_local_backup
rm terraform.tfstate

Change instance count from 1 → 2 and apply:

terraform apply -auto-approve

Terraform provisions only one additional instance, confirming the state is being read from Terraform Cloud.

8️⃣ Destroy & Cleanup

From Terraform Cloud:

  • Settings → Destruction & Deletion
  • Queue Destroy Plan
  • Confirm & Apply

Local cleanup:

rm -rf .terraform*
rm -rf terraform.tfstate*

✅ Conclusion

You have successfully migrated a Terraform state file from a local backend to Terraform Cloud, validated state continuity, and managed infrastructure using a remote, production-ready workflow.