-
Notifications
You must be signed in to change notification settings - Fork 9.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: support prevent_destroy for modules #18367
Comments
Hi @tdmalone! The available settings inside I assume that your intent here was this to behave as if We won't be able to work on this immediately due to other work in progress, but I like the idea of it and would like to dig into it a little more and see what the implementation might look like some time after the next major release (which is already pretty large in scope at this point). Thanks for this suggestion! |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
I have specific modules that I'd like to prevent_destroy and ignore Unfortunately there has been drift and TF is marking them to destroy (forces new resource) |
@apparentlymart is there any update on this? It is already after major release and it seems like terraform 0.12 really misses that feature to allow moving modules between various environments (qa -> prod) where in one infrastructure should terraform should be able to destroy module and on another no destroy action is welcomed ;). |
Terraform v0.12.28 but it is still not released
I also tried to pass variable for the module # main.tf
module "dns" {
source = "./modules/dns"
prevent_destroy = true
}
# modules/dns/main.tf
resource "aws_route53_zone" "publiczone" {
lifecycle {
prevent_destroy = var.prevent_destroy
}
comment = "..."
} Getting :
No pb! please let me violate DRY. |
Our Use Case: We build X instances derived from a module. During daily tasks, they should be prevented from destroy. |
@apparentlymart 0.13 is out and this feature is still not included in the release even though it has received a lot of love over the years. Now that modules support Any plan to integrate it soon? By the way for other users stuck with this, there is a (dirty) workaround which is not scalable at all but might work for small modules: You can put a condition at the resource level rather than at the block level. It's not scalable because you'd have to duplicate any resource you want to protect and use conditional expressions whenever you want to reference them. And if you eventually want to destroy these resources, you will need to remove the prevent_destroy from the module code. For example, to take @abdennour's example # main.tf
module "dns" {
source = "./modules/dns"
prevent_destroy = true
}
# modules/dns/main.tf
resource "aws_route53_zone" "publiczone" {
count = var.prevent_destroy ? 0 : 1
comment = "..."
}
# modules/dns/main_protected.tf
resource "aws_route53_zone" "publiczone_protected" {
count = var.prevent_destroy ? 1 : 0
lifecycle {
prevent_destroy = true
}
comment = "..."
} |
Would really love to see this feature implemented to help guard against accidentally deleting an environment worth of resources. |
current workflow:
we cannot use the workaround by @politician because we cant duplicate 30 lines of code just to workaround terraform internal issues. we`re using terraform 0.15 we want to use prevent_destroy in module calls for dns, clusters, project, databases in gcp |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This would be an amazing feature to have giving the user control on their resources instead of depending on the module author. Obviously this can be worked around via creating your own modules, but does create overhead. +1 for seeing this come to light |
I put together an example that shows how to, for certain use cases, protect resources created by 3rd party modules. In a nutshell, assuming your configuration uses a 3rd party module (e.g.
The Finally,
|
Is this in the plans at all? Without it reusing code seems nearly impossible. The above solution works, but adds complication when you do actually need to destroy that resource later. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Read the docs:
https://www.terraform.io/language/meta-arguments/lifecycle It definitely makes no sense. |
People use custom terraform modules to provision entire clusters of primary-source-of-truth databases. To place a I mean, you don't even get a plan if a single resource in a custom module protected by Modular programming shouldn't have to work this way, and it makes me cringe at my job when I should really be having fun using an efficient tool that doesn't work against me. In my opinion, this feature is critical for the continued adoption of Terraform. |
I think that this feature would be valuable, but I think something that hasn't really been brought up is that To provide some additional feedback/insight here, below is an example of how I currently protect deployment modules/resources from accidentally being removed and therefore destroying things. Note: This solution is not pure Terraform, as I'm not sure if there is really a way to do this with just Terraform. Supposes we have a structure like so: .
├── deployments
│ └── deployment-a.tf
└── modules
└── module-a deployment-a.tf module "module_a" {
source "../modules/module-a"
} module-a/main.tf resource "something" "something" {
# contents
} Currently, if we were to remove The current way I prevent this is to change the contents of deployment-a.tf to: module "protected_module_a" {
source "../modules/module-a"
} (We've now prefixed the module definition with This is the script I use to prevent "protected" definitions from being deleted: #!/bin/bash
set -e
# Run Terraform plan as normal, and generate a local plan file.
terraform plan -out=plan.cache
# Take the generated plan file and create another file, but this time in JSON
terraform show -json plan.cache > plan.cache.json
# This is where we check for deleted protected resources
# 1. Use `jq` to parse our generated plan JSON file
# 2. `jq` looks for any `resource_changes` with the `action_reason ` "delete_because_no_resource_config"
# 3. `jq` then looks for any of those findings that has the address which starts with `^(module.)?protected_`
# - Note: `module.` is optional in the event you define actual resources in deployment-a.tf as well
# 4. Store a list of all matching addresses to a temp file named `changes`.
cat plan.cache.json | jq -r '.resource_changes[] | select( .action_reason == "delete_because_no_resource_config" ) | select( .address | match( "^(module.)?protected_" ) ) | .address' > changes
# Get the number of protected_ things being removed.
change_count=$(cat changes | wc -l)
# Check if the count is greater than 0
if [ $change_count -ne 0 ];
then
# print some helpful info
echo "Error: Protected Resources are Removed Ungracefully."
echo "Resources affected:"
cat changes
# exit 1 (error) to prevent anything further
exit 1
fi The way you'd need to properly remove a
deployment-a.tf - module "protected_module_a" {
- source "../modules/module-a"
- }
+ module "module_a" {
+ source "../modules/module-a"
+ }
+ moved {
+ from = module.protected_module_a
+ to = module.module_a
+ }
deployment-a.tf - module "module_a" {
- source "../modules/module-a"
- }
- moved {
- from = module.protected_module_a
- to = module.module_a
- }
By gating the ability to remove "protected_" definitions behind 2 applies, and some additional state manipulation, it becomes an intentional act to remove something "protected_" then an accidental one. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
I'd be glad to take a stab at this. I can't promise quick results. Also, I see this as a nice opportunity to get to know the module part of the codebase better. @apparentlymart, does your view on this feature remain the same today? I've went ahead and opened a draft PR, I'll link it to this PR whenever it's starting to look like something 😉. |
This comment was marked as off-topic.
This comment was marked as off-topic.
2 similar comments
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as duplicate.
This comment was marked as duplicate.
Would be nice to have an update on this 6 year old issue. We module authors can't even specify prevent_destroy as a local variable in the module, so that module consumers could have a way to specify the value. Module consumers need a way to override this setting without having to rely on CI scripts editing the file. It appears to me that the only way to make this dynamic at present is via CI scripts (and only by doing exactly what you're not supposed to do, which is editing the cached copy under the |
@tspearconquest, this was actually a duplicate of #27360, but changed slightly. You can see my comments here regarding the possibilities of a feature like this: #27360 (comment) To repeat some of the fundamental problems, policy about what actions can take place is generally better handled outside of Terraform. I'll leave this open for now to better account for the 👍's it's gathered, but if there is a solution it would probably need to be designed somewhat differently than adding a |
Terraform Version
Terraform Configuration Files
Expected Behavior
I was hoping I could prevent destroy of any resources created by the module.
Actual Behavior
References
lifecycle
attributes with interpolations, which would get around this issue but for self-managed modules onlyThe text was updated successfully, but these errors were encountered: