Skip to content

Prevent Destroy Encryption

Adds prevent_destroy = true to KMS keys and Secrets Manager secrets, blocking accidental deletion of encryption infrastructure.

When to use this rule

Use this when: Your modules create KMS keys or Secrets Manager secrets used by production workloads. Losing these resources would make encrypted data inaccessible or break applications.

Do not use this when: You are rotating KMS keys as part of a planned key management lifecycle, or deleting test secrets in a non-production environment.


Why this rule exists

Deleting a KMS key is irreversible after the waiting period (7-30 days). Any data encrypted with that key becomes permanently inaccessible: S3 objects, RDS snapshots, EBS volumes, everything. Deleting a Secrets Manager secret can break applications that depend on stored credentials, API keys, or configuration values.

Unlike data resources where backups might help, losing a KMS key means losing access to the data itself. There is no recovery path.

RepositoryIssueTitle
hashicorp/terraform#3116Cannot use interpolations in lifecycle attributes
hashicorp/terraform#18367Feature request: support prevent_destroy for modules

Affected resources

ResourceServiceWhy
aws_kms_keyAWS KMSKey deletion makes all encrypted data permanently inaccessible
aws_secretsmanager_secretAWS Secrets ManagerSecret deletion breaks applications referencing stored credentials

Known limits

  • Does not cover aws_kms_alias, aws_kms_grant, or other KMS-related resources.
  • Does not prevent KMS key disabling (only deletion). A disabled key can be re-enabled.
  • Does not cover AWS Certificate Manager (ACM) certificates or other encryption-adjacent resources.

What this rule does

Adds a lifecycle { prevent_destroy = true } block to each matching resource. Terraform and OpenTofu will refuse to destroy these resources during terraform destroy or resource replacement.


Before and after

resource "aws_kms_key" "this" {
  # ... resource configuration ...

  tags = var.tags
}
resource "aws_kms_key" "this" {
  # ... resource configuration ...

  tags = var.tags

  lifecycle {
    prevent_destroy = true
  }
}

The only change is the rule transformation. All existing arguments, outputs, and module behavior remain identical.

Real-world scenario

During a Terraform workspace cleanup, terraform destroy deleted a KMS key used to encrypt an RDS production database. The 30-day deletion window passed before anyone noticed. All database backups encrypted with that key became permanently unrecoverable.


Compliance framework support

This rule is not a compliance control. It supports these framework objectives as an operational safeguard:

FrameworkControlsRole
SOC 2CC6.1, CC6.7Supports cryptographic key protection and data confidentiality
PCI DSS 4.03.6, 3.7Supports cryptographic key management lifecycle

Default configuration

This rule ships with the following defaults. Custom parameterization via the registry is planned for a future release.

ParameterTypeDefaultDescription
resource_typeslist(string)["aws_kms_key", "aws_secretsmanager_secret"]Encryption resource types to protect

How to enable

Add ?rules=pofix/prevent_destroy_encryption to your HTTPS module source:

module "example" {
  source = "https://soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws?version=5.0.0&rules=pofix/prevent_destroy_encryption"
}

Configure via the compliance.tf API. See Getting Started with Operational Rules.


Break-glass path

Use ?rules=-pofix/prevent_destroy_encryption in the module source URL to download without this rule for a single terraform init.


Failure modes

ScenarioResult
KMS key scheduled for deletion needs to be keptCancel the deletion schedule via AWS Console or CLI. The prevent_destroy block prevents Terraform from initiating deletion.
You need to intentionally delete a KMS keyUse the break-glass path to download the module without this rule, then run terraform destroy.

Terraform and OpenTofu compatible

This rule works with both Terraform (1.x+) and OpenTofu (1.6+). The generated HCL uses standard lifecycle meta-arguments supported by all versions.

Help us improve this page

Operational Rules are a new feature. We'd love your feedback on this rule page — what's useful, what's missing, what's confusing. Share feedback.