The information contained in this article has been verified as up-to-date on the date of the original publication of the article. HashiCorp endeavors to keep this information up-to-date and correct, but it makes no representations or warranties of any kind, express or implied, about the ongoing completeness, accuracy, reliability, or suitability of the information provided.
All information contained in this article is for general information purposes only. Any reliance you place on such information as it applies to your use of your HashiCorp product is therefore strictly at your own risk.
Introduction
It is currently impossible for Destroy-time provisioners declared in terraform_data
to read updated variables during a destroy run. There might be a need for some pre-destroy cleanups to be done on the machine and some external services. For example, updating table content in the database to reflect the removal of resources. This tutorial provides an alternative method to fulfill this.
Expected Outcome
Destroy-time provisioners can access the updated variables when running terraform
destroy
.
Procedure
- Create a Terraform file
main.tf
that contains twoterraform_data
resources; one forreplace
and one fordestroy
:variable "domain_password" {
type = string
description = "Domain Password"
default = "oldpassword"
}
resource "terraform_data" "replace" {
input = {
PASSWORD = var.domain_password
}
}
resource "terraform_data" "destroy" {
input = {
PASSWORD = var.domain_password
}
provisioner "local-exec" {
when = destroy
command = "echo ${self.input.PASSWORD}"
}
} - Run
terraform apply
to deployterraform_data
resources,
Terraform will perform the following actions:
If changing the variable value and then running
# terraform_data.destroy will be created
+ resource "terraform_data" "destroy" {
+ id = (known after apply)
+ input = {
+ PASSWORD = "oldpassword"
}
+ output = (known after apply)
}
# terraform_data.replace will be created
+ resource "terraform_data" "replace" {
+ id = (known after apply)
+ input = {
+ PASSWORD = "oldpassword"
}
+ output = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
terraform_data.replace: Creating...
terraform_data.destroy: Creating...
terraform_data.replace: Creation complete after 0s [id=dc01235b-240b-694f-5e60-de0037a7c883]
terraform_data.destroy: Creation complete after 0s [id=bae3e43c-7373-8427-cf3e-aac8ad8dabc0]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.terraform destroy
, the command output of the destroy provisioner will still be 'oldpassword'.
- Change the default value of the variable
domain_password
to 'newpassword' and runterraform apply -replace=terraform_data.replace --auto-approve
,
variable "domain_password" {
type = string
description = "Domain Password"
default = "newpassword"
}terraform_data.destroy: Refreshing state... [id=bae3e43c-7373-8427-cf3e-aac8ad8dabc0]
Now the PASSWORD value in the resource
terraform_data.replace: Refreshing state... [id=dc01235b-240b-694f-5e60-de0037a7c883]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
~ update in-place
-/+ destroy and then create replacement
Terraform will perform the following actions:
# terraform_data.destroy will be updated in-place
~ resource "terraform_data" "destroy" {
id = "bae3e43c-7373-8427-cf3e-aac8ad8dabc0"
~ input = {
~ PASSWORD = "987654" -> "password"
}
~ output = {
- PASSWORD = "987654"
} -> (known after apply)
}
# terraform_data.replace will be replaced, as requested
-/+ resource "terraform_data" "replace" {
~ id = "dc01235b-240b-694f-5e60-de0037a7c883" -> (known after apply)
~ input = {
~ PASSWORD = "987654" -> "password"
}
~ output = {
- PASSWORD = "987654"
} -> (known after apply)
}
Plan: 1 to add, 1 to change, 1 to destroy.
terraform_data.destroy: Modifying... [id=bae3e43c-7373-8427-cf3e-aac8ad8dabc0]
terraform_data.replace: Destroying... [id=dc01235b-240b-694f-5e60-de0037a7c883]
terraform_data.replace: Destruction complete after 0s
terraform_data.destroy: Modifications complete after 0s [id=bae3e43c-7373-8427-cf3e-aac8ad8dabc0]
terraform_data.replace: Creating...
terraform_data.replace: Creation complete after 0s [id=4f0eb987-54de-91fe-4f77-cc164f309a4c]
Apply complete! Resources: 1 added, 1 changed, 1 destroyed.terraform_data.destroy
is updated to 'newpassword'.
- Run
terraform destroy -auto-approve
and the command output of the destroy provisioner is 'new' which is the updated variable value,
Terraform will perform the following actions:
# terraform_data.destroy will be destroyed
- resource "terraform_data" "destroy" {
- id = "bae3e43c-7373-8427-cf3e-aac8ad8dabc0" -> null
- input = {
- PASSWORD = "newpassword"
} -> null
- output = {
- PASSWORD = "newpassword"
} -> null
}
# terraform_data.replace will be destroyed
- resource "terraform_data" "replace" {
- id = "4f0eb987-54de-91fe-4f77-cc164f309a4c" -> null
- input = {
- PASSWORD = "newpassword"
} -> null
- output = {
- PASSWORD = "newpassword"
} -> null
}
Plan: 0 to add, 0 to change, 2 to destroy.
terraform_data.replace: Destroying... [id=4f0eb987-54de-91fe-4f77-cc164f309a4c]
terraform_data.destroy: Destroying... [id=bae3e43c-7373-8427-cf3e-aac8ad8dabc0]
terraform_data.destroy: Provisioning with 'local-exec'...
terraform_data.destroy (local-exec): Executing: ["/bin/sh" "-c" "echo newpassword"]
terraform_data.replace: Destruction complete after 0s
terraform_data.destroy (local-exec): newpassword
terraform_data.destroy: Destruction complete after 0s
Destroy complete! Resources: 2 destroyed.
Additional Information
- Allow destroy-time provisioners to access variables #23679 - Still an open issue and a solution is yet available.