Terraform workarounds, module by module
A lifecycle block cannot take a variable. That single restriction is behind
most of the recurring "why can't this module just…" requests: prevent_destroy
on a data bucket, ignore_changes on tags an external controller writes,
create_before_destroy on a security group that is still attached. No module in
any registry can expose them, because Terraform evaluates lifecycle before it
evaluates anything a module could pass in.
These pages document the ones that come up per module. Each problem states what causes it, links the upstream issues, gives the native workaround in full, and says whether compliance.tf has a rule for it yet - including where it does not.
These limits belong to Terraform and OpenTofu; no module can lift them, and
each page's table links the upstream issues. Every page gives the native
workaround first. Where an Operational Rule exists, one source line applies
it: the module URL on registry.compliance.tf with ?version= and
?add_rules= in it. To get started, register a free compliance.tf account and
configure an access token. The
Rules Playground shows the diff
for every module below with no account.
The native option is named first, every time
Several of these problems have a good answer that needs nothing from
compliance.tf: provider default_tags, a resource's own deletion protection,
or simply not managing a field two systems both want to own. Those are named
before any rule is.
What this needs from you
A rule applied at download: a free compliance.tf account, an
access token (it stays out of git), and one
source line with the version and ?add_rules= in it. A preview in the
Rules Playground: nothing. Paid
plans add organization-wide Baselines and rulesets; none of these pages depend
on them. A problem with no rule yet gets the native workaround only.
Modules
Each problem links the Playground with only its rule selected; the last column opens the module with every rule this page answers.
| Module | Problems and the rule that answers each | Playground |
|---|---|---|
| Auto Scaling | Auto Scaling group desired_capacity reverts on every apply - lifecycle_ignore_scaling_changes | Open with all rules |
| DynamoDB table | DynamoDB read and write capacity reverts on every plan - lifecycle_ignore_autoscaling_changes terraform destroy deleted a DynamoDB table - lifecycle_prevent_destroy_data | Open with all rules |
| EC2 instance | Terraform wants to replace my EC2 instance because the AMI changed - lifecycle_ignore_ami_changes | Open with all rules |
| ECS | Terraform reverts the task definition my pipeline just deployed - lifecycle_ignore_deployed_artifacts ECS service desired_count keeps resetting - lifecycle_ignore_scaling_changes | Open with all rules |
| EKS | EKS node group desired_size changes on every plan - lifecycle_ignore_scaling_changes | Open with all rules |
| IAM | Terraform keeps reverting tags on IAM roles - lifecycle_ignore_tags | Open with all rules |
| KMS | terraform destroy scheduled deletion of a KMS key - lifecycle_prevent_destroy_encryption | Open with all rules |
| Lambda | Terraform keeps reverting my Lambda code to an old version - lifecycle_ignore_deployed_artifacts | Open with all rules |
| RDS | terraform destroy deleted a production database - lifecycle_prevent_destroy_data Terraform wants to reset the database password on every plan - lifecycle_ignore_secret_rotation | Open with all rules |
| RDS Aurora | terraform destroy deleted an Aurora cluster - lifecycle_prevent_destroy_data | Open with all rules |
| S3 bucket | terraform destroy deleted a production S3 bucket - lifecycle_prevent_destroy_data Terraform keeps reverting tags on my S3 buckets - lifecycle_ignore_tags | Open with all rules |
| Secrets Manager | terraform destroy deleted a secret other systems depend on - lifecycle_prevent_destroy_encryption | Open with all rules |
| VPC | Terraform keeps removing the tags that Kubernetes and load balancer controllers add - lifecycle_ignore_tags | Open with all rules |
How to read a page
- The symptom, written the way it gets searched for.
- Why Terraform cannot fix it, with the upstream issues so you can check.
- The native workaround in full, including when it is a fork.
- The rule, where one exists, with the HCL diff it produces - or an explicit "native option only, today" where it does not.
On a framework host you name the rules you want in ?add_rules=, on top of whatever
Baseline your organization has Enforced; on an organization host that
organization's configuration decides. See
Operational Rules for the model and
Operational Rule Definitions for what each rule is.