Managing Terraform state securely is a critical part of Infrastructure as Code. When working in teams or managing multiple environments, storing state locally becomes unreliable, unsafe, and difficult to collaborate on. AWS S3 provides a durable, secure, and highly available backend for storing Terraform state files, and with recent updates, Terraform now supports native S3 state locking without DynamoDB.
This guide explains how Terraform state works, why remote backends are necessary, how S3 state locking works, and how to configure an S3 bucket with versioning and encryption to store Terraform state files.
How Terraform Updates Infrastructure
Terraform maintains a state file called terraform.tfstate. This file represents the current state of all resources managed by Terraform. Every terraform plan or terraform apply compares:
• The desired state defined in your configuration
• The actual state stored in the state file
Terraform updates only the resources whose configurations have changed.
Terraform State File Details
The state file contains:
• Resource metadata and attributes
• Provider configurations
• Resource dependencies
• Output values
• Sensitive resource details
Because of the sensitive data stored inside it, state files must be handled carefully.
State File Best Practices
• Never edit the state file manually
• Store state in a remote backend
• Enable state locking
• Regularly back up state files
• Use separate state files for dev, test, and prod
• Restrict access to state storage
• Enable encryption
Why Remote Backends Matter
Remote backends such as Amazon S3 offer:
• Collaboration with shared state
• State locking to prevent simultaneous changes
• Encryption for security
• Versioning for backups
• High availability and durability
Local state files cannot provide these features.
AWS S3 as a Remote Backend
Terraform supports S3 as a backend for storing state files. The backend configuration lives inside the terraform block and instructs Terraform where to store the state.
Backend example:
terraform {
backend "s3" {
bucket = "adarsh-s3-statefile-bucket-1"
key = "dev/terraform.tfstate"
region = "ap-south-1"
encrypt = true
use_lockfile = true
}
}
Important note: The backend block cannot create the S3 bucket. It must already exist before terraform init is executed.
S3 Native State Locking
Terraform 1.10 introduced native state locking using S3 itself, removing the need for DynamoDB tables. S3 uses conditional writes to create a lock file (.tflock). If the file exists, Terraform blocks concurrent operations.
This reduces complexity, saves cost, and simplifies backend setup.
Testing S3 State Locking
Terminal 1:
terraform apply
Terminal 2:
terraform plan
Expected output:
Error acquiring the state lock.
StatusCode: 412
A .tflock object appears in the S3 bucket and is removed when the operation completes.
Complete Terraform Configuration
Below is the Terraform configuration used to deploy a VPC and an S3 bucket, while storing the Terraform state file in an S3 backend.
terraform {
backend "s3" {
bucket = "adarsh-s3-statefile-bucket-1"
key = "dev/terraform.tfstate"
region = "ap-south-1"
encrypt = true
use_lockfile = true
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
provider "aws" {
region = "ap-south-1"
}
resource "aws_vpc" "main_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main_vpc"
Environment = "Dev"
}
}
resource "aws_s3_bucket" "bucket1" {
bucket = "bucket12345-${aws_vpc.main_vpc.id}"
tags = {
Name = "bucket1"
VpcLinkedTo = aws_vpc.main_vpc.id
}
}
output "resource_ids" {
value = {
vpc_id = aws_vpc.main_vpc.id
s3_bucket_id = aws_s3_bucket.bucket1.id
}
}
This configuration demonstrates:
• A remote backend for Terraform state
• S3 native state locking
• A VPC resource
• An S3 bucket with an implicit dependency on the VPC
Useful State Commands
List resources:
terraform state list
View resource state:
terraform state show <resource>
Remove from state:
terraform state rm <resource>
Move resources:
terraform state mv <source> <destination>
Pull raw state:
terraform state pull
Verifying S3 Configuration
Check versioning:
aws s3api get-bucket-versioning --bucket your-bucket
Check encryption:
aws s3api get-bucket-encryption --bucket your-bucket
Final Thoughts
Terraform state management is a foundational skill for any Infrastructure as Code workflow. Using AWS S3 for storing state provides a secure, collaborative, and resilient backend. With the arrival of S3 native state locking, the process is simpler and more efficient than ever.
Top comments (0)