2
votes

I'm currently working on an fully managed by Terraform environment but I reached some limitations and I would like to know if there is a feature or a workaround to do what I want :

I have an environment described like that :

  • A VPC with public and private subnets
  • An EKS cluster with some workers
  • Some kubernetes configurations (using the kubernetes provider)
  • Some helm configurations (using the helm provider)

Everything work, but when I want to do a full clean up by running terraform destroy I have to destroy some resources one by one with -target option and then delete manually some references in the state file.

Two reasons why I would like to do that:

  1. Just because it fails

    Don't know why, but I was unable to destroy with Terraform and manually some subnets (imposible to detach the internet gateway) but I was able to destroy them by simply destroying the VPC.

    In this case, I would like to tell to Terraform to only delete the VPC, by doing that, AWS automatically destroy related components such as Subnets, Internet Gateway, Route table, Networks ACL, etc.

  2. Because it would be faster

    I'm using Terraform with Kubernetes (and Helm) provider to define my Kubernetes configuration, but when I run terraform destroy it will delete all the Kubernetes resources, then the Cluster (and workers).

    Only deleting the Cluster would be really faster.


So here is my question : Is it possible to exclude resources to the destroy process in the Terraform configuration files ?

3

3 Answers

3
votes

There is actually no ways to do what I want, but the documentation says :

Instead of using -target as a means to operate on isolated portions of very large configurations, prefer instead to break large configurations into several smaller configurations that can each be independently applied. Data sources can be used to access information about resources created in other configurations, allowing a complex system architecture to be broken down into more manageable parts that can be updated independently.

This will not fits with some use cases if we use standard pattern (one configuration for the VPC, one for the Cluster and workers, and one for the kubernetes configuration) because destroying the VPC will still destroy all the components before destroying the VPC (and will result into a failure).


Here is a possible workaround, the goal would be to create two configurations :

  • Main configuration : contains all the components which needs to be destroyed
    • Ex : VPC, Cluster, RDS, DynamoDB
  • Sub configuration : contains all the components which will be destroyed (provider side) by destroying the main components
    • Ex : Kubernetes configuration, subnets, internet gateway, etc

With this pattern, we can then create a simple CLI with a destroy command :

  1. Run the command terraform destroy in the main configuration
  2. When the step 1 is successfully finished, remove the state of the sub configuration

I made an issue on the Terraform github repository to propose an enhancement, an annotation system allowing plugins to interact with annotated resources and listen to the different events (creation, destruction, state refresh, etc)

If you are in the same case, take a look to the issue, add a +1 and maybe comment your opinion !

https://github.com/hashicorp/terraform/issues/23547

1
votes

This allows you to create a plan that destroys all resources except the module "module.exclude.me"

terraform plan -destroy $(for r in `terraform state list | fgrep -v module.exclude.me` ; do printf " -target ${r} "; done) -out destroy.plan

Credits go to cmacrae from the corresponding github issue:https://github.com/hashicorp/terraform/issues/2253

0
votes

I have also seen terraform failures while destroying resources, needing manual intervention. The recommended way seems to be to modularise the required resources into separate configurations and then plan/destroy them as needed. In your case, say a separate eks.tf for EKS configuration.