Terraform
Use write-only arguments
Write-only arguments let you securely pass temporary values to Terraform's managed resources during an operation without persisting those values to state or plan files. Use write-only arguments to handle sensitive data such as passwords, API tokens, and other secrets.
Background
Write-only arguments complement other ephemeral values in Terraform, letting you securely pass sensitive data throughout your configuration without ever storing it in Terraform's artifacts. For example, you can generate a random password using an ephemeral
resource then pass it to a write-only argument on another resource
block. The provider uses the write-only argument value to configure the resource, then Terraform discards the value without storing it.
Hands-on: Declare a write-only argument in the Upgrade RDS major version tutorial.
Unlike other ephemeral constructs in Terraform, such as ephemeral resources or variables, write-only arguments accept both ephemeral and non-ephemeral values.
Requirements
To use write-only arguments, you must use Terraform v.1.11 or later and use a resource that supports write-only arguments.
Declare a write-only argument
Providers indicate in the Terraform registry whether an argument is write-only. For example, the aws
provider's aws_db_instance
resource has a write-only password_wo
argument. The password_wo
argument accepts a value to use as the database password:
resource "aws_db_instance" "test" {
instance_class = "db.t5.micro"
allocated_storage = "5"
engine = "postgres"
username = "admin"
skip_final_snapshot = true
password_wo = <ephemeral or non-ephemeral value>
password_wo_version = 1
}
Write-only arguments accept both ephemeral and non-ephemeral values. For example, you could also use a string as the value of a write-only argument:
resource "aws_db_instance" "test" {
instance_class = "db.t5.micro"
allocated_storage = "5"
engine = "postgres"
username = "admin"
skip_final_snapshot = true
password_wo = "my-password-here"
password_wo_version = 1
}
However, we recommend using write-only arguments for passing ephemeral values to resources. If you use a non-ephemeral value, Terraform stores that value or hard-codes it in your configuration. For example, you can use an ephemeral
resource to generate a random password and pass it to the password_wo
write-only argument:
ephemeral "random" "password" {
length = 16
}
resource "aws_db_instance" "test" {
instance_class = "db.t5.micro"
allocated_storage = "5"
engine = "postgres"
username = "admin"
skip_final_snapshot = true
password_wo = ephemeral.random.password.value
password_wo_version = 1
}
During a Terraform operation, the provider uses the password_wo
value to configure the database instance, and then Terraform discards that value without storing it in the plan or state file.
Update write-only arguments with versions
Terraform does not store write-only arguments in state files, so Terraform has no way of knowing if a write-only argument value has changed. Because Terraform cannot track write-only argument values, it sends write-only arguments to the provider during every operation.
Terraform also cannot create plan diffs for write-only arguments because it does not store those values in plan files. However, providers typically include version arguments alongside write-only arguments. Terraform stores version arguments in state, and can track if a version argument changes.
Providers implement version arguments to let practitioners track write-only argument values and control when a provider uses those write-only arguments. The implementation of write-only arguments and their version arguments is provider-specific, so consult the Registry for more details about your specific provider.
For example, the aws_db_instance
resource has an accompanying password_wo_version
argument for the password_wo
write-only argument:
resource "aws_db_instance" "test" {
instance_class = "db.t5.micro"
allocated_storage = "5"
engine = "postgres"
username = "admin"
skip_final_snapshot = true
password_wo = "old-password-here"
password_wo_version = 1
}
The provider uses the write-only argument value when creating the aws_db_instance
resource and Terraform stores the password_wo_version
argument value in state.
To trigger an update of a write-only argument, increment the version argument's value in your configuration:
resource "aws_db_instance" "main" {
instance_class = "db.t5.micro"
allocated_storage = "5"
engine = "postgres"
username = "admin"
password_wo = "new-password-here"
password_wo_version = 2
}
When you increment the password_wo_version
argument, Terraform notices that change in its plan and notifies the aws
provider. The aws
provider then uses the new password_wo
value to update the aws_db_instance
resource.