Terraform
ephemeral block reference
Use the ephemeral block to define temporary resources that Terraform does not store in state or plan files.
Background
The ephemeral block declares a temporary ephemeral resource that only exists during the current Terraform operation. Terraform does not store ephemeral resources in state or plan files, making them ideal for managing sensitive or temporary data that you do not want to persist, such as temporary passwords or connections to other systems.
To learn more about the ephemeral block and its unique lifecycle and provisioning order, refer to Manage sensitive data.
Lifecycle
Ephemeral resources have a unique lifecycle compared to regular resources and data sources. Terraform performs the following lifecycle steps for each ephemeral resource:
- Terraform opens an ephemeral resource if it needs access to the resource’s result.
- Terraform asks the ephemeral resource’s provider to periodically renew access if it needs to access the resource for longer than the remote system's enforced expiration time.
- Terraform closes the ephemeral resource after the providers that depend on that resource complete their work for the current run phase.
As an example, if your Terraform configuration defines an ephemeral resource for a Vault secret, Terraform begins by opening the resource by having the Vault provider obtain a lease and return the secret. If needed, Terraform renews the resource by calling Vault's lease renewal API endpoint to extend the expiration time. Finally, Terraform closes the resource by explicitly ending the lease, letting Vault immediately revoke the associated credentials.
Order of provisioning
Ephemeral resources form nodes in Terraform's dependency graph and interact similarly to resources and data sources. When a resource or data source depends on an attribute of an ephemeral resource, Terraform automatically provisions the ephemeral resource first.
If an input argument of an ephemeral resource references a value that Terraform does not know yet but can learn during or after a plan, Terraform defers executing that resource until the apply stage.
Refer to ephemeral resources
You can only refer to ephemeral resources in specific ephemeral contexts. Otherwise, Terraform throws an error when it plans your changes. The following are valid contexts for referring to ephemeral resources:
- In a managed resource write-only argument
- In another ephemeralblock
- In the localsblock
- In variableblocks with theephemeralargument set totrue
- In child module outputblocks with theephemeralargument set totrue
- Configuring providers in the providerblock
- In a provisioner and provisioner connection configuration. Refer to Use a provisioner for more information.
Configuration model
The ephemeral block supports the following arguments:
- ephemeral "<TYPE>" "<LABEL>"block- <PROVIDER_ARGUMENTS>various | refer to your provider documentation
- countnumber | mutually exclusive with- for_each
- depends_onlist of references
- for_eachmap or set of strings | mutually exclusive with- count
- providerreference
- lifecycleblock- preconditionblock- conditionexpression
- error_messagestring
 
- postconditionblock- conditionexpression
- error_messagestring
 
 
 
Complete configuration
The following ephemeral block defines all of the supported built-in arguments you can set on an ephemeral resource:
ephemeral "<TYPE>" "<LABEL>" {
  <PROVIDER_ARGUMENTS>
  count = <NUMBER>      # `for_each` and `count` are mutually exclusive
  depends_on = [ <RESOURCE.ADDRESS.EXPRESSION> ]
  for_each = {          # `for_each` accepts a map or a set of strings
    <KEY> = <VALUE>
  }
  for_each = [          # `for_each` accepts a map or a set of strings
    "<VALUE>",
    "<VALUE>"
  ]
  provider = <REFERENCE.TO.ALIAS>
  lifecycle {
    precondition {
      condition = <EXPRESSION>
      error_message = "<STRING>"
    }
    postcondition {
      condition = <EXPRESSION>
      error_message = "<STRING>"
    }
  }
}
Specification
An ephemeral block supports the following configuration.
ephemeral "<TYPE>" "<LABEL>"
You must set the following for every ephemeral block:
- TYPE: Specifies the type of ephemeral resource to create. Provider developers define the available ephemeral resource types. Refer to the provider documentation for details about specific ephemeral resource types.
- LABEL: Specifies a name for the ephemeral resource. Terraform uses this label to track the resource during the current operation. The label does not affect settings on the actual infrastructure resource. Refer to References to Named Values and Resource naming for label syntax and recommendations.
Refer to the ephemeral resource using ephemeral.<TYPE>.<LABEL> syntax.
Provider-specific arguments
The provider developer determines which arguments you can define for an ephemeral resource. Refer to the provider documentation for details about available arguments and how to format their values.
Summary
- Data type: Various, depending on the provider
- Default: None, but requirements vary by provider
- Required: Varies by provider
count
The count meta-argument instructs Terraform to provision multiple instances of the same ephemeral resource with identical or similar configuration. You cannot use both a count and  for_each argument in the same block.
ephemeral "<TYPE>" "<LABEL>" {
  count = <number>
}
count is a meta-argument. Meta-arguments are built into the Terraform language and control how Terraform creates resources. Refer to the count reference for details about how the argument works.
depends_on
The depends_on meta-argument specifies an upstream resource that the ephemeral resource depends on. When it creates a plan, Terraform sequences all operations on the upstream resource before performing operations on the ephemeral resource configured with the depends_on meta-argument.
ephemeral "<TYPE>" "<LABEL>" {
  depends_on = [ <resource reference> ]
}
depends_on is a meta-argument. Meta-arguments are built into the Terraform language and control how Terraform creates resources. Refer to the depends_on reference for details about how the argument works.
for_each
The for_each meta-argument instructs Terraform to provision similar ephemeral resources without requiring separate configuration blocks for each resource.
ephemeral "<TYPE>" "<LABEL>" {
  for_each = [ "<VALUE>" ]
  # ...
}
for_each is a meta-argument. Meta-arguments are built into the Terraform language and control how Terraform creates resources. Refer to the for_each reference for details about how the argument works.
provider
The provider argument instructs Terraform to use an alternate provider configuration to provision the ephemeral resource.
ephemeral "<TYPE>" "<LABEL>" {
  provider = <PROVIDER>.<ALIAS>
}
provider is a meta-argument. Meta-arguments are built into the Terraform language and control how Terraform creates resources. Refer to the provider reference for details about how the argument works.
lifecycle
The lifecycle block defines lifecycle rules for how Terraform operates on your ephemeral resource.
ephemeral "<TYPE>" "<LABEL>" {
  lifecycle {
    <lifecycle>
  }
}
You can specify the following lifecycle rules to manage how Terraform performs operations on the ephemeral resource:
- precondition: Specifies a condition that Terraform evaluates before creating the ephemeral resource. Refer to Test and validate for more information.
- postcondition: Specifies a condition that Terraform evaluates after creating the ephemeral resource. Refer to Test and validate for more information.
You can include both precondition and postcondition blocks in the same lifecycle block, and you can define multiple precondition and postcondition blocks in the same lifecycle block.
lifecycle is a meta-argument. Meta-arguments are built into the Terraform language and control how Terraform creates resources. Refer to the lifecycle reference for details about how the argument works.
precondition
The precondition block specifies a condition that must return true before Terraform evaluates and performs operations on the ephemeral resource. You can also specify an error message for Terraform to print when the condition returns false.
ephemeral "<TYPE>" "<LABEL>" {
  lifecycle {
    precondition {
      condition           = <expression>
      error_message       = "<message>"
    }
  }
}
precondition is a directive available in the lifecycle meta-argument. Meta-arguments are built into the Terraform language and control how Terraform creates resources. Refer to the lifecycle reference for details about how the argument works.
postcondition
The postcondition block specifies a condition that must return true after Terraform performs operations on the ephemeral resource. You can also specify an error message for Terraform to print to the console when the condition returns false.
ephemeral "<TYPE>" "<LABEL>" {
  lifecycle {
    postcondition {
      condition = <expression>
      error_message = "<message>"
    }
  }
}
postcondition is a directive available in the lifecycle meta-argument. Meta-arguments are built into the Terraform language and control how Terraform creates resources. Refer to the lifecycle reference for details about how the argument works.
Examples
The following examples demonstrate common use cases for ephemeral blocks.
Fundamental ephemeral resource
In the following example, the aws_secretsmanager_secret_version ephemeral resource provides credentials to configure the PostgreSQL provider:
ephemeral "aws_secretsmanager_secret_version" "db_master" {
  secret_id = aws_secretsmanager_secret_version.db_password.secret_id
}
locals {
  credentials = jsondecode(ephemeral.aws_secretsmanager_secret_version.db_master.secret_string)
}
provider "postgresql" {
  host     = aws_db_instance.example.address
  port     = aws_db_instance.example.port
  username = local.credentials["username"]
  password = local.credentials["password"]
# …
}
An ephemeral resource handles the credentials so Terraform never stores them in state or plan files. If you reference an ephemeral resource in locals block that value in the locals block is also not stored in state or plan files because Terraform intuitively understands you do not want that value stored.
Use ephemeral values with a write-only argument
Write-only arguments let you securely pass temporary values to managed resources during an operation without persisting those resource values to state or plan files. In the following example, the random_password ephemeral resource generates a temporary password and passes it to the password_wo write-only argument:
#...
ephemeral "random_password" "db_password" {
  length           = 16
  override_special = "!#$%&*()-_=+[]{}<>:?"
}
resource "aws_db_instance" "example" {
  instance_class       = "db.t3.micro"
  allocated_storage    = "5"
  engine               = "postgres"
  username             = "example"
  skip_final_snapshot  = true
  publicly_accessible  = true
  db_subnet_group_name = aws_db_subnet_group.example.name
  password_wo          = ephemeral.random_password.db_password.result
  password_wo_version  = 1
}
Neither write-only arguments nor ephemeral resources are persisted outside of the current Terraform run, ensuring that the ephemeral.random_password.db_password.result value is completely omitted from state and plan files.
Terraform does not store the generated value of ephemeral.random_password.db_password.result, but you can capture it in another resource to ensure the value is not lost. For an example of generating, storing, retrieving, and using an ephemeral password, refer to write-only arguments.
Create multiple ephemeral resources
In the following example, the for_each argument creates multiple passwords for different database environments:
locals {
  environments = toset(["dev", "staging", "prod"])
}
ephemeral "random_password" "db_passwords" {
  for_each = local.environments
  length           = 16
  override_special = "!#$%&*()-_=+[]{}<>:?"
}
resource "aws_db_instance" "databases" {
  for_each = local.environments
  identifier                = "${each.key}-database-${var.environment_suffix}"
  db_name                   = "${each.key}db"
  username                  = "dbadmin"
  password_wo               = ephemeral.random_password.db_passwords[each.key].result
 # …
}
The ephemeral block creates a random_password ephemeral resource for each environment in the local.environments set. The aws_db_instance resource then uses the generated passwords for each database instance.
Terraform does not store the generated db_passwords values, but you can capture them in another resource to ensure those values are not lost. For an example of generating, storing, retrieving, and using an ephemeral password, refer to write-only arguments.
Use alternate provider configurations
In the following example, the ephemeral resource uses an alternate AWS provider configuration:
provider "aws" {
  region = "us-east-1"
}
provider "aws" {
  alias  = "west"
  region = "us-west-2"
}
ephemeral "aws_secretsmanager_secret_version" "db_password" {
  provider  = aws.west
  secret_id = aws_secretsmanager_secret.db_password.id
}
Terraform uses the aws.west provider configuration to create the aws_secretsmanager_secret_version resource in the us-west-2 region.
Validate ephemeral resources
In the following example, the aws_ssm_parameter ephemeral resource has a precondition to ensure that compliance mode is enabled to secure production secrets, and a postcondition to ensure the generated password meets password requirements:
variable "environment" {
  description = "Deployment environment"
  type        = string
}
variable "compliance_mode" {
  description = "Enable compliance requirements for production"
  type        = bool
  default     = false
}
ephemeral "aws_ssm_parameter" "database_password" {
  name = "/secrets/${var.environment}/database/password"
  lifecycle {
    precondition {
      condition     = var.environment != "prod" || var.compliance_mode == true
      error_message = "Enable compliance mode to assess production secrets."
    }
    postcondition {
      condition     = can(regex("^[A-Za-z0-9!@#$%^&*()_+=-]{16,}$", self.value))
      error_message = "Password from external source must meet security requirements."
    }
  }
}