-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Persistent state and automatic reimport for resources that aren't fully deleted on destroy #33216
Description
Terraform Version
Terraform v1.5.0-beta1
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v4.67.0Use Cases
Some resources, like aws_secretsmanager_secret or aws_kms_key, go into a pending deletion state outside of Terraform when destroyed, rather than being immediately deleted.
If a configuration containing a resource like this is intended to be applied and destroyed regularly -- for example, a dev or CI environment -- then it is currently already painful to handle. Because the resource can't be fully deleted by design, it must be manually undeleted and reimported into Terraform before the configuration can be applied again. The new import blocks coming in Terraform 1.5.0 seemed like they had the potential to improve this: if those resources could be enhanced to undelete themselves when imported, then the import block would get rid of any manual steps needed in between applies.
resource "aws_secretsmanager_secret" "test" {
name = "test"
}
import {
# Doesn't actually need to be a full ARN to be imported successfully, in spite of documentation.
# This resource type gets some random characters added to the end of its ARN by AWS.
id = "arn:aws:secretsmanager:us-west-2:xxx:secret:test"
to = aws_secretsmanager_secret.test
}But now the pain point comes on the first apply. In a configuration like this, the import block would be intended to be permanent. But this means that on the first apply, it needs to be commented out, otherwise it fails with Error: Cannot import non-existent remote object.
Attempted Solutions
The way we currently manage resources of this type is with a wrapper script that undeletes and reimports the resource outside of Terraform before running apply.
Proposal
A new concept of "persistence" is added to resources. A persistent resource continues to have its ID stored in the state after it is destroyed. Persistent bool is added as a new attribute to schema.Resource to effect this change. When a provider adds support for a resource that can't be immediately deleted by Terraform, they should set this to true on that resource.
Every time state is refreshed, if the resource has been previously destroyed, the resource is read via the stored ID, and is only removed from the state when it is found to have been fully deleted outside of Terraform.
When a destroyed persistent resource is applied, Terraform automatically proposes an import of the previously deleted resource, rather than creation of a new resource. It would be up to providers to ensure that import of the resource includes undeleting/restoring it.
terraform state list for a resource like this that has been destroyed might show:
aws_secretsmanager_secret.test [destroyed]
The resource could be terraform state rm'd to make Terraform fully forget about it and attempt to create a new resource instead of reimporting the previous one. A new lifecycle option, persistence, of type bool, can be used on persistent resources to optionally disable the behavior:
lifecycle {
persistence = false
}
Trying to use this attribute on a resource that is not persistent would generate an error.
Open Questions
What should terraform taint do with a persistent resource? taint is intended to destroy and recreate, but this is likely to cause a conflict with the resource that was just destroyed, but isn't actually gone. Maybe it should be an error.
What happens if the configuration for a persistent resource is removed from the configuration? It should likely be retained in the state as if it were destroyed, since it still has the same property of not actually having been deleted. A user might be switching between git branches that do and don't have the resource.