Ephemeral in Terraform
You get 3 places where the word ephemeral
is now added to Terraform: variables
, the ephemeral
block (which is basically a data
block), and outputs
.
Limitations
A limitation consistent between all the places you can use ephemeral
is that it is sticky. If you reference a ephemeral
var/block/output, the rest of the chain becomes ephemeral
. The only valid places Ephemeral values can be referenced are: locals
, variables
, outputs
, providers
, provisioners
and connections
. Note that resources
are not in this list, as they give the error "Ephemeral values are not valid in resource arguments, because resource instances must persist between Terraform phases."
Sample code:
variable "password" {
type = string
ephemeral = true
}
resource "azurerm_key_vault_secret" "password" {
name = "password"
value = var.password
key_vault_id = azurerm_key_vault.kv.id
}
Output:
│ Error: Invalid use of ephemeral value
│
│ with azurerm_key_vault_secret.password,
│ on ephemeral.tf line 9, in resource "azurerm_key_vault_secret" "password":
│ 9: value = var.password
│
│ Ephemeral values are not valid in resource arguments, because resource instances must persist between Terraform phases.
Ephemeral
blocks have the ability to use a depends_on
attribute, but this does not stop it validating at Plan time, so in this example it fails as the Secret named password
does not exist.
Sample code:
ephemeral "azurerm_key_vault_secret" "password" {
name = "password"
key_vault_id = azurerm_key_vault.kv.id
depends_on = [time_sleep.minute]
}
Output:
│ Error: secret password does not exist in Key Vault (Subscription: "3bb8d2ac-64fc-4d58-af80-f6097055fd34"
│ Resource Group Name: "rg-loer"
│ Key Vault Name: "kv-loer")
│
│ with ephemeral.azurerm_key_vault_secret.password,
│ on ephemeral.tf line 12, in ephemeral "azurerm_key_vault_secret" "password":
│ 12: ephemeral "azurerm_key_vault_secret" "password" {
│
│ keyvault.BaseClient#GetSecret: Failure responding to request: StatusCode=404 -- Original Error: autorest/azure: Service returned an error. Status=404 Code="SecretNotFound"
│ Message="A secret with (name/id) password was not found in this key vault. If you recently deleted this secret you may be able to recover it using the correct recovery command.
│ For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125182"
When Its All Working
When working, you can see Terraform opening and closing the connection to read the value. And if you later inspect the state file, there is no entry for the ephemeral
block at all.
ephemeral.azurerm_key_vault_secret.password: Opening...
ephemeral.azurerm_key_vault_secret.password: Opening complete after 2s
ephemeral.azurerm_key_vault_secret.password: Closing...
ephemeral.azurerm_key_vault_secret.password: Closing complete after 0s
So what Do I Use This for
Authentication keys on Providers
are the primary use case for ephemeral
,
Unfortunately the use cases are pretty limited in the AzureRM
provider as there is no reason to do this, but this does open up cool use cases when connecting to other things, like when using the postgresql
provider as in this example from the Terraform documentation
ephemeral "aws_secretsmanager_secret_version" "db_master" {
secret_id = data.aws_db_instance.example.master_user_secret[0].secret_arn
}
locals {
credentials = jsondecode(ephemeral.aws_secretsmanager_secret_version.db_master.secret_string)
}
provider "postgresql" {
host = data.aws_db_instance.example.address
port = data.aws_db_instance.example.port
username = local.credentials["username"]
password = local.credentials["password"]
}