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 documentationcountnumber | mutually exclusive withfor_eachdepends_onlist of referencesfor_eachmap or set of strings | mutually exclusive withcountproviderreferencelifecycleblockpreconditionblockconditionexpressionerror_messagestring
postconditionblockconditionexpressionerror_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.
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."
}
}
}