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

prevent_destroy does not prevent destruction when removing a resource from the configuration #17599

Open
samjgalbraith opened this Issue Mar 15, 2018 · 6 comments

Comments

Projects
None yet
6 participants
@samjgalbraith

samjgalbraith commented Mar 15, 2018

The documentation for prevent_destroy says

This flag provides extra protection against the destruction of a given resource. When this is set to true, any plan that includes a destroy of this resource will return an error message

However, removing or commenting out a resource seems to still destroy it with no warning, even though technically it was a plan that includes the destruction of the resource. What I expected was that the state file would remember that it was created with prevent_destroy, and prevent its destruction even if it was no longer part of the parsed configuration. It would be reasonable to expect that the user would be forced to remove the prevent_destroy flag, terraform apply, then remove it from the configuration if they were absolutely sure they wanted to go ahead.

Terraform Version

Terraform v0.11.3
+ provider.aws v1.11.0

Terraform Configuration Files

locals {
  dynamo_db_mutext_attribute = "LockID"  # The name must be exactly this
}

provider "aws" {
  profile = "test"
  region = "ap-southeast-2"
}

resource "aws_s3_bucket" "test_environment_terraform_backend_storage" {
  region = "ap-southeast-2"
  bucket_prefix = "SOME-BUCKET-NAME_PREFIX-"
  versioning {
    enabled = true
  }
  tags {
    Environment = "test"
  }
  # We explicitly prevent destruction using terraform. Remove this only if you really know what you're doing.
  lifecycle {
    prevent_destroy = true
  }
}

resource "aws_dynamodb_table" "test_environment_terraform_backend_mutex" {
  "attribute" {
    name = "${local.dynamo_db_mutext_attribute}"
    type = "S"
  }
  hash_key = "${local.dynamo_db_mutext_attribute}"
  name = "test_environment_terraform_backend_mutex"
  read_capacity = 5
  write_capacity = 5
  # We explicitly prevent destruction using terraform. Remove this only if you really know what you're doing.
  lifecycle {
    prevent_destroy = true
  }
}

Expected Behavior

Resource is prevented from being destroyed because it was created with lifecycle { prevent_destroy = true }

Actual Behavior

Resource with prevent_destroy set to true is destroyed when commenting out or removing from configuration.

Steps to Reproduce

  1. Enter the above Terraform configuration into a new module.
  2. terraform apply and say yes.
  3. Now, comment out the s3 bucket resource.
  4. terraform apply again, and say yes

Additional Context

References

@apparentlymart

This comment has been minimized.

Contributor

apparentlymart commented Mar 15, 2018

Hi @theflyingnerd! Thanks for pointing this out.

Currently removing a resource from configuration is treated as intent to remove the resource, since that's an explicit action on your part rather than it happening as a part of some other action, such as resource replacement or a whole-configuration destroy.

However, your idea of retaining this in the state and requiring multiple steps to actually destroy is an interesting one:

  1. Leave resource in config but remove prevent_destroy
  2. Run terraform apply to update the state to no longer have that flag set.
  3. Remove the resource from configuration entirely.
  4. Run terraform apply again to actually destroy it.

I'd like to think about this some more because while this does seem safer it also feels like this flow could be quite frustrating if e.g. you've already committed some reorganization to your version control that includes removing a resource and then Terraform refuses to apply it until you revert and do steps 1 and 2 from the above.

In the mean time, we should at least update the documentation to be more explicit about how prevent_destroy behaves in this scenario.

@samjgalbraith

This comment has been minimized.

samjgalbraith commented Mar 16, 2018

Great, thanks for your quick and thorough reply @apparentlymart . I agree that a documentation update would be sufficient for now and the proposed functionality could be left open for debate. My comments about this process were a mixture of how I might expect it to work if I didn't read any more documentation as well as a proposal. It's influenced by the idea of AWS instance termination protection. This protection must be explicitly removed first before the instance may be terminated, even if the instance is explicitly terminated by id.

@a-nldisr

This comment has been minimized.

a-nldisr commented May 22, 2018

Please see: #16392

@dguisinger

This comment has been minimized.

dguisinger commented Jun 27, 2018

Any further thoughts on this?
I used Terraform to setup build pipelines including AWS CodeCommit for storage of code.
A mistake in terraform will wipe out the entire contents of the Git repo. I too want a way to protect resources in case they get removed from a script.

@tdmalone

This comment has been minimized.

tdmalone commented Jul 2, 2018

Potential duplicate of #3468

@roidelapluie

This comment has been minimized.

Contributor

roidelapluie commented Jul 8, 2018

Strange that 17599 closes 3468 and not the opposite but that is still a very wanted feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment