DEV Community

Mukami
Mukami

Posted on

# State Isolation: Workspaces vs File Layouts — When to Use Each

Day 7 of the 30-Day Terraform Challenge — and today I faced the million-dollar question: How do you manage dev, staging, and production without accidentally nuking production?

Terraform gives you two answers. One is quick and easy. One is boring and safe. Let me tell you which one I'm choosing.


The Problem: One State to Rule Them All

Yesterday I had one state file. One. For everything.

That's fine for a personal project. But imagine a team of 10 people all running Terraform on the same state file. Dev changes. Staging changes. Production changes. All mixed together like a smoothie of chaos.

Someone adds a tag in dev. Someone else deletes a bucket in staging. Suddenly production is down and nobody knows why.

I needed isolation. Real isolation.


Option 1: Workspaces (The Quick Fix)

Workspaces are Terraform's built-in solution. Same code. Different state files.

How It Works:

terraform workspace new dev
terraform workspace new staging
terraform workspace new production
Enter fullscreen mode Exit fullscreen mode

Then in your code:

resource "aws_s3_bucket" "app" {
  bucket = "myapp-${terraform.workspace}"

  tags = {
    Environment = terraform.workspace
  }
}
Enter fullscreen mode Exit fullscreen mode

When you're in dev, you get a dev bucket. In production, you get a production bucket. Same code, different resources.

What Workspaces Get Right:

  • Dead simple — one command and you're done
  • No code duplication — change one file, all environments get the update
  • Fast switchingterraform workspace select dev and go

Where Workspaces Fall Short:

No Code Isolation

Same code means same bugs everywhere. I fixed something in dev? That change applies to production too. Unless you're using Git branches carefully, one bad commit breaks everything.

Too Easy to Misconfigure

I did this three times today:

terraform workspace select production  # Wait, I meant dev!
terraform apply  # Oops, I just deployed to prod
Enter fullscreen mode Exit fullscreen mode

No warning. No confirmation. Just me and my mistake.

Team Pain

Everyone works on the same codebase. Merge conflicts. Coordination headaches. Sarah's dev change blocks John's production deployment.

Workspaces are like using the same recipe for all three meals — breakfast, lunch, and dinner. Sure, it's simple, but you probably don't want pancakes for dinner.


Option 2: File Layouts (The Grown-Up Way)

Different folders. Different code. Different state. Complete isolation.

How It Works:

environments/
├── dev/
│   ├── backend.tf   # points to dev state
│   └── main.tf      # dev resources
├── staging/
│   ├── backend.tf   # points to staging state
│   └── main.tf      # staging resources
└── production/
    ├── backend.tf   # points to prod state
    └── main.tf      # prod resources (with extra protections)
Enter fullscreen mode Exit fullscreen mode

What File Layouts Get Right:

Complete Isolation

Dev folder has dev code. Production folder has production code. They never touch. I can delete the entire dev folder and production keeps running.

Hard to Misconfigure

To break production, I have to:

  1. cd environments/production
  2. Run Terraform
  3. Type yes

Three conscious decisions. No accidental deploys.

Team-Friendly

Dev team works in dev folder. Prod team works in prod folder. Different branches, different approvals, no stepping on toes.

Environment-Specific Logic

Production can have:

lifecycle {
  prevent_destroy = true  # Can't delete prod resources!
}
Enter fullscreen mode Exit fullscreen mode

Dev can be reckless. Production can be locked down. Different needs, different code.

Where File Layouts Add Friction:

More Directory Management

Five folders. Ten files. Backend configs everywhere. It's organized, but it's also... a lot.

Repeated Backend Config

Every environment needs its own backend.tf. Copy-paste the same thing three times:

backend "s3" {
  bucket = "my-state-bucket"
  key    = "environments/dev/terraform.tfstate"  # Only this changes
  region = "us-east-1"
}
Enter fullscreen mode Exit fullscreen mode

One line changes per environment. The rest is identical. Feels repetitive.

More Setup

Each environment needs its own terraform init. More commands, more waiting, more chances to forget something.

File layouts are like having separate kitchens for breakfast, lunch, and dinner. More work to set up, but you never accidentally serve breakfast food at a dinner party.


The Comparison Table

Aspect Workspaces File Layouts
Setup Time 5 seconds 5 minutes
Code Duplication None Some (backend.tf)
Accidental Prod Deploy Risk High Low
Team Collaboration Hard (one codebase) Easy (separate folders)
Environment-Specific Code Complex (if statements) Simple (different files)
Learning Curve Easy Moderate

When to Use Workspaces

You're working alone or in a small team. Two people? Workspaces are fine.

You're testing or prototyping. Spin up dev, test something, destroy it. Quick and dirty.

Your environments are nearly identical. Same resources, just different names. Workspaces handle that perfectly.

You value speed over safety. Sometimes that's the right tradeoff.


When to Use File Layouts

You work in a team. I don't care if it's 3 people or 300 — separate folders save relationships.

You have production infrastructure. If customers depend on it, use file layouts. Protect your sleep schedule.

Your environments differ. Dev uses t3.micro, prod uses t3.large? Different monitoring? Different backups? Separate code.

You need approvals. Prod requires code review. Dev doesn't. Separate folders make that easy.


My Recommendation

Workspaces for personal projects and testing. File layouts for everything else.

I know file layouts feel like more work. But here's the thing: that "more work" is actually the friction that prevents disaster.

Every time I cd environments/production, I pause. I check. I think. That pause is what keeps me from running terraform destroy on production by accident.

Workspaces are a sledgehammer. File layouts are a scalpel. Both can build infrastructure. Only one belongs in surgery.


The Bottom Line

Today I learned that infrastructure isolation isn't just about state files. It's about creating boundaries that protect you from yourself and your team.

Workspaces are clever. File layouts are boring. In production, boring wins every time.

Tomorrow I'll probably complain about managing all these folders. But tonight, I'll sleep knowing my dev experiments can't touch production.


What would you choose? I'm genuinely curious — drop your thoughts in the comments.

P.S. If you're using workspaces in production and it's working for you — I'm genuinely impressed. Tell me your secrets. I need them. 😅

Top comments (0)