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
ephemeral
block - In the
locals
block - In
variable
blocks with theephemeral
argument set totrue
- In child module
output
blocks with theephemeral
argument set totrue
- Configuring providers in the
provider
block - 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 documentationcount
number | mutually exclusive withfor_each
depends_on
list of referencesfor_each
map or set of strings | mutually exclusive withcount
provider
referencelifecycle
blockprecondition
blockcondition
expressionerror_message
string
postcondition
blockcondition
expressionerror_message
string
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.
ephemeral "<TYPE>" "<LABEL>" {
count = <number>
}
The value must be a whole number. You can reference variables or local values and use expressions to compute the value, but the value must resolve to a whole number.
In blocks where you set count
, Terraform exposes an additional count
object. You can reference the object within the ephemeral block to modify the configuration of each instance. The count
object has an index
attribute starting from 0
.
To refer to an individual instance of an ephemeral resource created using the count
meta-argument, use the ephemeral.<TYPE>.<LABEL>[INDEX]
syntax. For example, ephemeral.random_password.db_password[0]
refers to the first instance of the random_password
ephemeral resource named db_password
.
The count
argument is a meta-argument, which is built into Terraform and controls the way that Terraform creates resources. Refer to Meta-arguments for more information.
Summary
- Data type: Number
- Default: None
- Example: Create multiple ephemeral resources
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> ]
}
When an ephemeral resource configuration refers to another resource, Terraform identifies the dependency and creates the upstream resource first. In some cases, you may need Terraform to create a resource before creating an ephemeral resource, even though the resources are configured independently.
Use the depends_on
argument when the resources do not reference each other. We recommend always including a comment to explain resource dependencies when using a depends_on
argument.
When using the depends_on
meta-argument, you can only reference other resources in the same root module or its child modules. The list cannot include arbitrary expressions. Any values referenced in the depends_on
list must be known before Terraform begins the operation so that it can evaluate dependencies.
The depends_on
argument is a meta-argument, which is built into Terraform and controls the way that Terraform creates resources. Refer to Meta-arguments for more information.
Summary
- Data type: List
- Default: None
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>" ]
# ...
}
The for_each
meta-argument accepts a map or a set of strings and creates an instance for each item in that map or set. Each instance is associated with a distinct ephemeral resource. Terraform creates, updates, or destroys each instance when applying changes to the configuration.
You can use pure functions, such as toset()
and tomap()
, to create a map or set for use in the for_each
argument. Whether iterating over the keys of a map or set of strings, all of the values must be known when Terraform creates a plan. Otherwise, Terraform prints an error message that for_each
has dependencies that it cannot determine before applying the configuration.
Keys in the for_each
argument cannot be the result of or rely on the result of impure functions, including uuid
, bcrypt
, or timestamp
, because Terraform defers evaluating impure functions during the main evaluation step.
You cannot use sensitive values, such as sensitive input variables, sensitive outputs, or sensitive resource attributes, as arguments in for_each
. Terraform uses the value in for_each
to identify the ephemeral resource instance and always discloses it in UI output, so sensitive values are not allowed.
The for_each
argument exposes an each
object that you can reference within the same block to modify specific instances of the ephemeral resource. The object has the following attributes:
each.key
: Map key or list member that corresponds to an instance.each.value
: Map value that corresponds to an instance.
Use the ephemeral.<TYPE>.<LABEL>[<KEY>]
syntax to access an instance of an ephemeral resource created using for_each
. For example, ephemeral.random_password.passwords["admin"]
refers to an instance of the random_password
ephemeral resource named passwords
created from the admin
key.
The for_each
argument is a meta-argument, which is built into Terraform and controls the way that Terraform creates resources. Refer to Meta-arguments for more information.
Summary
- Data type: Map or set of strings
- Default: None
- Example: Create multiple ephemeral resources
provider
The provider
argument instructs Terraform to use an alternate provider configuration to provision the ephemeral resource.
ephemeral "<TYPE>" "<LABEL>" {
provider = <PROVIDER>.<ALIAS>
}
By default, Terraform automatically selects a provider based on the ephemeral resource type, but you can create multiple provider configurations and use a non-default configuration for specific ephemeral resources.
Use the <PROVIDER>.<ALIAS>
syntax to reference a provider configuration in the provider
argument.
The provider
argument is a meta-argument, which is built into Terraform and controls the way that Terraform creates resources. Refer to Meta-arguments for more information.
Summary
- Data type: Reference
- Default: None
- Example: Use alternate provider configurations
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.
The lifecycle
block is a meta-argument. Meta-arguments are built-in arguments that control how Terraform creates resources. Refer to Meta-arguments for more information.
Summary
- Data type: Block
- Default: None
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>"
}
}
}
The following arguments in the precondition
block are required:
Argument | Description | Data type |
---|---|---|
condition | Expression that must return true for Terraform to proceed with an operation. You can refer to any other object in the same configuration scope unless the reference creates a cyclic dependency. | Expression that can include references, strings, and operators. |
error_message | Message that Terraform prints to the console if the condition returns false . | String |
Terraform evaluates precondition
blocks before evaluating the ephemeral resource's configuration arguments. The precondition
block errors can take precedence over argument evaluation errors.
Terraform evaluates precondition blocks after evaluating count
and for_each
meta-arguments. As a result, Terraform can evaluate the precondition
separately for each instance and makes the each.key
and count.index
objects available in the conditions.
You can include a precondition
and postcondition
block in the same ephemeral resource.
Refer to Test and validate for information about adding validations to your Terraform configuration.
Summary
- Data type: Block
- Default: None
- Example: Validate ephemeral resources
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>"
}
}
}
The following arguments in the postcondition
block are required:
Argument | Description | Data type |
---|---|---|
condition | Expression that must return true for Terraform to perform operations on downstream resources. You can refer to any other object in the same configuration scope unless the reference creates a cyclic dependency. | Expression that can include references, strings, and operators. |
error_message | Message that Terraform prints to the console if the condition returns false . | String |
Terraform evaluates postcondition
blocks after planning and applying changes to the ephemeral resource. Postcondition failures prevent changes to other resources that depend on the failing ephemeral resource.
You can include a postcondition
and precondition
block in the same ephemeral resource.
Refer to Test and validate for information about adding validations to your Terraform configuration.
Summary
- Data type: Block
- Default: None
- Example: Validate ephemeral resources
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."
}
}
}