Skip to main content

Ephemeral Resources and the End of Secrets in State Files

· 3 min read
Abdulmalik
AppSec Engineer

If you've been following my content, you know I'm big on IaC security. I've written about encrypting your OpenTofu state files before - because let's be honest, downloading unencrypted terraform state files dangling around has been a goldmine for attackers.

Well, OpenTofu 1.11 just dropped and it's addressing this problem from a completely different angle - what if secrets never made it to state files in the first place?

The Problem with Secrets in State Files

Here's a tweet I made a while back:

"I love downloading unencrypted terraform state dangling around, helps me understand your infra and if i get lucky, i might find a key or token, please just enable state encryption, this is bare minimum"

State file encryption is great, but it's still a safety net. The secrets are still there, just encrypted. If someone gets access to your KMS key or your encryption passphrase, game over.

OpenTofu 1.11 takes a completely different approach with Ephemeral Resources.

Ephemeral Resources - The Game Changer

This is the headline feature. Ephemeral values allow OpenTofu to work with data and resources that exist only in memory during a single OpenTofu phase. They're guaranteed to never be persisted in state snapshots or plan files.

Before (The Old Way)

# Traditional approach - secret STORED in state
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "prod/db/password"
}

resource "aws_db_instance" "main" {
password = data.aws_secretsmanager_secret_version.db_password.secret_string
# Password is now in your state file forever!
}

After (The OpenTofu 1.11 Way)

# NEW: Ephemeral resource - secret NEVER stored in state
ephemeral "aws_secretsmanager_secret_version" "db_password" {
secret_id = "prod/db/password"
}

resource "aws_db_instance" "main" {
password = ephemeral.aws_secretsmanager_secret_version.db_password.secret_string
# Password used during apply but NEVER saved in state file!
}

See that? Same functionality, but the secret exists only during the tofu apply execution. Once it's done, poof - gone from memory, never persisted.

Why This Matters

  1. Zero-exposure secrets - Even if someone gets your state file, there are no secrets to steal
  2. Compliance made easier - SOC2, HIPAA, PCI-DSS auditors love hearing "secrets never touch disk"
  3. Defense in depth - Combined with state encryption, you've got multiple layers now

Write-Only Attributes

There's also a related feature called write-only attributes. Some managed resource types now support attributes that can be set but never stored. Perfect for passwords, API keys, and other sensitive configs.

resource "some_provider_database" "example" {
name = "production-db"

# This is a write-only attribute
admin_password = var.db_admin_password
# ↑ Password is sent to the provider but not saved in state
}

Ephemeral Variables and Outputs

You can also declare input variables and output values as ephemeral:

variable "api_secret" {
type = string
ephemeral = true # Won't be stored in state
}

output "generated_token" {
value = some_resource.token
ephemeral = true # Won't persist in state snapshots
}

My Take

Ephemeral resources are genuinely exciting. Combined with state file encryption, this puts OpenTofu leagues ahead of Terraform in the security department.

If you're still on Terraform and haven't made the switch to OpenTofu yet, this feature alone might be the nudge you need.

Till next time, Peace be on you 🤞🏽

References


Comments