Skip to main content
Blog terraform
terraform

Stop Storing Cloud Credentials in Terraform State

Introduction Terraform state files contain everything Terraform needs to manage your infrastructure. That includes any cloud credentials you use to...

Stop Storing Cloud Credentials in Terraform State

Introduction

Terraform state files contain everything Terraform needs to manage your infrastructure. That includes any cloud credentials you use to authenticate providers – AWS access keys, Azure service principals, GCP service account credentials.

This creates a security problem: anyone with access to your state file has access to your cloud credentials. Even when stored remotely in S3 or HCP Terraform, state files remain sensitive artifacts that require protection.

There’s a better approach: ephemeral resources in the Vault provider. They generate short-lived cloud credentials on demand, use them during your Terraform run, and ensure they never touch your state file.


The Old Way: Data Blocks

The traditional approach uses Vault’s data sources to retrieve credentials:

data "vault_aws_access_credentials" "creds" {
  backend = "aws"
  role    = "terraform"
}

provider "aws" {
  access_key = data.vault_aws_access_credentials.creds.access_key
  secret_key = data.vault_aws_access_credentials.creds.secret_key
}

The problem: These credentials end up in your Terraform state file. The vault_aws_access_credentials data source returns credentials that Terraform persists to state like any other data source.

If your state file is compromised, those credentials are exposed. Even with a short TTL, you’ve created an unnecessary security risk.


The New Way: Ephemeral Resources

Terraform 1.10 introduced ephemeral resources – resources that exist only during plan and apply operations and are never written to state.

The Vault provider now supports ephemeral resources for AWS, Azure, and GCP credentials:

ephemeral "vault_aws_access_credentials" "creds" {
  backend = "aws"
  role    = "terraform"
}

provider "aws" {
  access_key = ephemeral.vault_aws_access_credentials.creds.access_key
  secret_key = ephemeral.vault_aws_access_credentials.creds.secret_key
}

What’s different:

  • Credentials are generated when Terraform needs them (during plan/apply)
  • They’re used to configure your AWS provider
  • They’re automatically revoked when Terraform finishes
  • They never appear in your state file

Check your state after running this configuration – you won’t find the ephemeral resource or its credentials anywhere.

Note: Not all providers support ephemeral resources, so double-check the provider documentation for your targeted platform to validate. For example, here are the docs for one of Vault’s ephemeral resources. Look for the top-level Ephemeral Resources in the navigation pane.


How Terraform Should Authenticate to Vault

Before Terraform can retrieve credentials from Vault, it must first authenticate with Vault. The best approach: identity-based authentication.

For CI/CD systems, Terraform can authenticate using JWT tokens from your platform:

provider "vault" {
  address = "https://vault.example.com"
  
  auth_login_jwt {
    role      = "terraform"
    jwt       = var.jwt_token  # From CI/CD platform
  }
}

GitHub Actions, GitLab CI, and most modern CI/CD platforms can provide JWT tokens that Vault can validate. This eliminates the need for long-lived Vault tokens in your pipeline.

For local development, you can use your existing Vault token from environment variables:

provider "vault" {
  address = "https://vault.example.com"
  # Reads VAULT_TOKEN from environment variable
}

Identity-based authentication means Terraform never stores long-lived Vault credentials. Combined with ephemeral resources for cloud credentials, you’ve eliminated both credential storage problems.


Setting Up Vault

Before using ephemeral resources, you need to configure Vault’s secrets engine for your cloud provider.

For AWS:

# Enable the AWS secrets engine
vault secrets enable aws

# Configure with root credentials
vault write aws/config/root \
  access_key=AKIA... \
  secret_key=SECRET...

# Create a role that generates temporary credentials
vault write aws/roles/terraform \
  credential_type=iam_user \
  policy_document=-<<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["ec2:*", "s3:*"],
      "Resource": "*"
    }
  ]
}
EOF

For Azure:

Vault supports Azure through the Azure secrets engine, which generates service principals:

vault secrets enable azure
vault write azure/config \
  subscription_id=... \
  tenant_id=... \
  client_id=... \
  client_secret=...

Then use ephemeral "vault_azure_access_credentials" in your Terraform code.

For GCP:

Vault’s GCP secrets engine generates OAuth2 access tokens or service account keys:

vault secrets enable gcp
vault write gcp/config credentials=@credentials.json

Use ephemeral "vault_gcp_access_credentials" in Terraform.


Complete Example

Here’s a working example that authenticates Terraform to Vault using JWT, retrieves ephemeral AWS credentials, and deploys infrastructure:

terraform {
  required_providers {
    vault = {
      source  = "hashicorp/vault"
      version = "~> 5.7.0"
    }
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
  required_version = ">= 1.10"
}

provider "vault" {
  address = "https://vault.example.com"
  
  auth_login_jwt {
    role = "terraform"
    jwt  = var.oidc_token
  }
}

ephemeral "vault_aws_access_credentials" "aws" {
  backend = "aws"
  role    = "terraform"
  ttl     = "1h"
}

provider "aws" {
  region     = "us-east-1"
  access_key = ephemeral.vault_aws_access_credentials.aws.access_key
  secret_key = ephemeral.vault_aws_access_credentials.aws.secret_key
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
}

During terraform plan and terraform apply:

  1. Terraform authenticates to Vault using the JWT token
  2. Terraform requests temporary AWS credentials from Vault
  3. Terraform uses those credentials to configure the AWS provider
  4. Terraform creates your infrastructure
  5. Vault automatically revokes the credentials after the TTL expires

The credentials never appear in plan output or state files.


Why This Matters

Security: Credentials aren’t stored in state files or plan artifacts. Even if someone gains access to your state, they don’t get cloud credentials.

Auditability: Vault logs every credential request. You know exactly when Terraform requested credentials and which role was used.

Compliance: Many security frameworks require credential rotation and time-limited access. Ephemeral credentials satisfy both requirements automatically.

Reduced blast radius: Compromised state files don’t expose valid cloud credentials. The credentials that existed during your last Terraform run expired hours or days ago.


Requirements

  • Terraform 1.10 or later (when ephemeral resources were introduced)
  • Vault provider 5.0 or later (when ephemeral resources were added)
  • Vault configured with the appropriate secrets engine (AWS, Azure, or GCP)
  • JWT authentication configured in Vault for your CI/CD platform

Migration Path

If you’re currently using data sources for Vault credentials:

  1. Upgrade to Terraform 1.10+ and Vault provider 5.0+
  2. Replace data "vault_aws_access_credentials" with ephemeral "vault_aws_access_credentials"
  3. Update provider blocks to reference the ephemeral resource
  4. Test in a non-production environment first
  5. Verify credentials don’t appear in state after migration

The syntax is nearly identical – you’re mainly changing the resource type from data to ephemeral.


Final Thoughts

Storing cloud credentials in Terraform state has always been a necessary evil. Ephemeral resources eliminate that compromise.

If you’re using Vault to manage cloud credentials for Terraform, ephemeral resources should be your default approach. They provide the same functionality as data sources while keeping credentials out of state entirely.

The migration is straightforward, the security improvement is significant, and you’re finally using Terraform state the way it was meant to be used – for infrastructure metadata, not sensitive credentials.


Want to learn more about Terraform’s latest features? Check out my HashiCorp Certified Terraform Associate 004 course, which covers ephemeral resources, state management best practices, and everything you need to pass the certification exam.

Keep Reading

Related Articles

Moving Terraform to a Config-Driven Workflow
terraform
Jan 20, 2026

Moving Terraform to a Config-Driven Workflow

You’ve automated Terraform deployments in CI/CD pipelines with GitHub Actions or Harness, but have you kept state management manual by manually running...

Read Article
Why the Terraform Associate Certification Keeps Growing in Popularity
terraform
Nov 30, 2025

Why the Terraform Associate Certification Keeps Growing in Popularity

Introduction I get asked this constantly by my students: “Is the Terraform Associate certification actually worth it, or is it just another cert to collect?”...

Read Article
CloudFormation vs Terraform: Which Infrastructure-as-Code Tool Should You Choose?
terraform
Nov 20, 2025

CloudFormation vs Terraform: Which Infrastructure-as-Code Tool Should You Choose?

Introduction I get asked this question constantly in my courses and by teams I consult with: “Should we use CloudFormation or Terraform?” It’s a fair question...

Read Article
Bryan Krausen - AWS and HashiCorp educator

About the Instructor

Bryan Krausen

Bryan Krausen is a leading AWS and HashiCorp educator with over a decade of experience helping professionals and businesses succeed in the cloud. As a top-rated Udemy instructor, Bryan has taught over 150,000 students worldwide, delivering practical, real-world insights that empower learners to thrive in the ever-evolving tech landscape.

A HashiCorp Ambassador and published author, Bryan holds multiple AWS and HashiCorp certifications. His courses combine clear explanations, hands-on labs, and real-world scenarios to ensure students don't just pass exams — they truly understand the technology.

150,000+

Students Worldwide

20+

Online Courses

4.7+

Star Rating

Connect on LinkedIn

Ready to Go Deeper?

Turn these concepts into real skills. Explore Bryan's hands-on courses on Terraform, Vault, AWS, and more.

Explore Courses