📘 Terraform State Migration: Local Backend → Terraform Cloud
Project Topic: Migrate Terraform State from Local Machine to Terraform Cloud
Table of Contents
- 🎯 Objective
- 🧩 Prerequisites
- 🛠️ Project Structure
- 1️⃣ Infrastructure Configuration Files
- 2️⃣ Provision Infrastructure Locally
- 3️⃣ Create Terraform Cloud Workspace (CLI-Driven)
- 4️⃣ Configure Remote Backend
- 5️⃣ Migrate State to Terraform Cloud
- 6️⃣ Configure AWS Credentials in Terraform Cloud
- 7️⃣ Verify State Migration
- 8️⃣ Destroy & Cleanup
- ✅ Conclusion
🎯 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)
- Log in to Terraform Cloud
- Select Organization
- Create New Workspace
- Choose CLI-Driven Workflow
- 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_IDAWS_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.
