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.
Related Terraform and OpenTofu issues
| Repository | Issue | Title |
|---|---|---|
| hashicorp/terraform | #3116 | Cannot use interpolations in lifecycle attributes |
| hashicorp/terraform | #18367 | Feature request: support prevent_destroy for modules |
Affected resources
| Resource | Service | Why |
|---|---|---|
aws_kms_key | AWS KMS | Key deletion makes all encrypted data permanently inaccessible |
aws_secretsmanager_secret | AWS Secrets Manager | Secret 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:
| Framework | Controls | Role |
|---|---|---|
| SOC 2 | CC6.1, CC6.7 | Supports cryptographic key protection and data confidentiality |
| PCI DSS 4.0 | 3.6, 3.7 | Supports cryptographic key management lifecycle |
Default configuration
This rule ships with the following defaults. Custom parameterization via the registry is planned for a future release.
| Parameter | Type | Default | Description |
|---|---|---|---|
resource_types | list(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
| Scenario | Result |
|---|---|
| KMS key scheduled for deletion needs to be kept | Cancel the deletion schedule via AWS Console or CLI. The prevent_destroy block prevents Terraform from initiating deletion. |
| You need to intentionally delete a KMS key | Use 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.