DEV Community

Samuel Udeh
Samuel Udeh

Posted on

State Isolation: Layout vs Workspace

Terraform State isolation refers to the practice of managing and organizing your infrastructure state files to ensure that different environments or projects do not interfere with one another. There are two ways you could isolate state files:
Isolation via workspaces
Useful for quick, isolated tests on the same configuration
Isolation via file layout
Useful for production use cases for which you need strong separation between environments.

In this blog post, we’ll focus on Workspace-based Isolation, providing examples to demonstrate its capabilities.
Isolation via Workspaces
Terraform workspaces allow you to store your Terraform state in multiple, separate, named workspaces. Terraform starts with a single workspace called “default,” and if you never explicitly specify a workspace, the default workspace is the one you’ll use
the entire time. To create a new workspace or switch between workspaces, you use the terraform workspace commands.

main.tf

provider "aws" {
region = "us-east-1" # Adjust as needed
}

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

resource "aws_s3_bucket" "terraform_state" {
bucket = "samley-bucket" # Ensure this name is unique across all of AWS
acl = "private" # Set the ACL for the bucket

versioning {
enabled = true # Enable versioning
}

# Enable server-side encryption
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256" # Use S3-managed keys for encryption
}
}
}

lifecycle {
prevent_destroy = false # Prevent accidental deletion
}
}

Block public access settings for the bucket

resource "aws_s3_bucket_public_access_block" "public_access" {
bucket = aws_s3_bucket.terraform_state.id
block_public_acls = true
ignore_public_acls = true
block_public_policy = true
restrict_public_buckets = true
}

resource "aws_dynamodb_table" "terraform_locks" {
name = "state-locks"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"

attribute {
name = "LockID"
type = "S"
}
}

output "s3_bucket_arn" {
value = aws_s3_bucket.terraform_state.arn
description = "The ARN of the S3 bucket"
}

output "dynamodb_table_name" {
value = aws_dynamodb_table.terraform_locks.name
description = "The name of the DynamoDB table"
}

Run the terraform plan
Run the terraform apply

After creating the resources, the new backend s3 code can now be added to the configuration...

terraform {
backend "s3" {
bucket = "samley-bucket"

key = "workspaces-example/terraform.tfstate"

region = "us-east-1"

dynamodb_table = "state-locks"

encrypt = true

}
}

Run terraform init
Run terraform apply

The state for this deployment is stored in the default workspace. You can confirm this by running the terraform workspace show command,

Image description
The default workspace stores your state in exactly the location you specify via the key configuration. As shown in the Figure below, if you take a look in your S3 bucket, you’ll
find a terraform.tfstate file in the workspaces-example folder.

Image description

Managing Workspaces
You can create and switch between workspaces using the Terraform commands:

Create workspaces

terraform workspace new example1
terraform workspace new example2

Switch to a workspace

terraform workspace select example1

Plan and Apply changes to the current workspace

terraform plan
terraform apply

Terraform wants to create a totally new EC2 Instance from scratch! That’s because the state files in each workspace are isolated from one another, and because you’re now in the example1 workspace, Terraform isn’t using the state file from the default
workspace and therefore doesn’t see the EC2 Instance was already created there.
By running terraform apply, to deploy this second EC2 Instance in the new workspace.

Image description

In this example above,

  • The example1 workspace uses the state file example1/terraform.tfstate. The example2 workspace uses the state file example2/terraform.tfstate.

Inside each of those workspaces, Terraform uses the key you specified in your backend configuration, so you should find an example1/workspaces-example/terraform.tfstate and an example2/workspaces-example/terraform.tfstate. In other words,
switching to a different workspace is equivalent to changing the path where your statefile is stored.

To avoid unnecessary charges, delete the bucket by destroying the infrastructure using the terraform destroy command

CONCLUSION
Terraform workspaces allow you to run terraform workspace new and deploy a new copy of the exact same infrastructure, but storing the state in a separate file.
Workspace-based isolation offers a flexible way to manage multiple environments with a shared Terraform configuration. By associating each workspace with its own state file, you can ensure environment-specific changes without interference.

Let us know how you’re using Terraform workspaces in your projects! Happy Terraforming!

Top comments (0)