为何Terragrunt会销毁已创建的资源?附Terraform代码结构说明
First, let's recap your setup for context:
Your Infrastructure Structure
$ tree infrastructure infrastructure ├── ecr │ └── terraform.tfvars ├── ecs │ ├── ecs-iam.json │ └── terraform.tfvars └── terraform.tfvars 2 directories, 4 files
Root terraform.tfvars Content
terragrunt = { remote_state { backend = "s3" config { bucket = "terraform-dev-state-west2" key = "dev/terraform.tfstate" region = "us-west-2" encrypt = true } } }
Now, based on this structure, here are the most likely reasons Terragrunt is destroying your existing resources, along with how to diagnose and fix each:
1. Shared Remote State File Across Components
The biggest red flag here is that your root terraform.tfvars defines a single remote state key (dev/terraform.tfstate), but you're running Terragrunt in component subdirectories (ecr/, ecs/). If those components don't have their own unique remote state configurations, Terragrunt will reuse the root state file for all components.
Here's what happens:
- When you run
terragrunt applyinecr/, it saves ECR resources todev/terraform.tfstate. - Then when you run
terragrunt applyinecs/, Terragrunt loads the same state file, sees no ECS resources in the current configuration, and marks the ECR resources for destruction.
Fix: Add a terragrunt.hcl (or extend terraform.tfvars) in each component directory to define a unique remote state key. For example, in ecr/terragrunt.hcl:
remote_state { backend = "s3" config = { bucket = "terraform-dev-state-west2" key = "dev/ecr/terraform.tfstate" region = "us-west-2" encrypt = true } }
2. Missing Component-Level Terragrunt Configuration
Terragrunt requires a terragrunt.hcl file in each working directory to properly scope the module and state. Right now, your components only have terraform.tfvars—without a terragrunt.hcl that specifies which module to use (or inherits from the root), Terragrunt might be treating each component as an empty module.
When it compares this empty configuration to the existing state, it will try to destroy all resources in the state file.
Fix: Create a terragrunt.hcl in each component directory. For example, ecs/terragrunt.hcl might look like:
terraform { source = "../modules/ecs" # Point to your ECS module source } remote_state { backend = "s3" config = { bucket = "terraform-dev-state-west2" key = "dev/ecs/terraform.tfstate" region = "us-west-2" encrypt = true } } # Include variables from your terraform.tfvars include { path = find_in_parent_folders() }
3. Accidental State Overwrites or Corruption
If your component directories are accidentally pointing to the same state key as the root, running apply in a component will overwrite the root state with only that component's resources. Later, when you run commands from the root, Terragrunt will see the missing resources and plan to destroy them.
Diagnose: Run terragrunt state list in the root directory and each component directory. If the root state only has resources from one component, or components show no resources, you've got a state overwrite issue.
Fix: Restore the original state from a backup if possible, then configure unique state keys for each component as mentioned in point 1.
4. Resource Identifier Changes Without State Updates
If you modified resource names, module sources, or unique attributes (like an ECR repo name) in your component configurations, Terragrunt will see these as new resources and mark the old ones for destruction. For example, if you changed repo_name = "old-ecr" to repo_name = "new-ecr" without importing the existing repo into the new state, Terragrunt will create the new repo and destroy the old one.
Diagnose: Run terragrunt plan and look for "destroy" actions paired with "create" actions for similar resources.
Fix: Use terragrunt import to bring the existing resource into the new state, or revert the identifier change if it was accidental.
内容的提问来源于stack exchange,提问作者roadtest ma

