Terraform每次执行apply时AWS EKS关联的EFS资源被重复创建问题排查
First off, let’s break down exactly what’s causing your EFS resources to recreate on every terraform apply, and walk through fixes for each part of the problem.
The Core Culprit: KMS Alias vs. Key ARN Mismatch
The main issue here lies in how you’re specifying the KMS key for EFS. AWS EFS expects the kms_key_id to be either the actual KMS key ARN (format: arn:aws:kms:region:account:key/key-id) or the key’s UUID. When you use data.aws_kms_alias.efs.arn, you’re pulling the alias ARN (format: arn:aws:kms:region:account:alias/your-alias-name), not the key’s own unique ARN.
Here’s the play-by-play of why this triggers recreation:
- When Terraform first creates the EFS, it resolves the alias ARN to the actual key ARN and stores that key ARN in its state file.
- On subsequent
plan/applyruns, Terraform compares your configured value (the alias ARN) against the state value (the key ARN). Since these don’t match, Terraform incorrectly decides the EFS needs to be recreated to "fix" this discrepancy.
Fix for the KMS Issue
Instead of using the alias data source, use a aws_kms_key data source to fetch the actual key ARN via its alias:
# Fetch the actual KMS key using its alias data "aws_kms_key" "efs" { key_id = "alias/${var.eks_efs_kms_alias}" # Replace with your alias variable } resource "aws_efs_file_system" "efs_fs" { creation_token = var.eks_efs_name encrypted = true # Tip: Use boolean true instead of string "true" for better type consistency kms_key_id = data.aws_kms_key.efs.arn # Now this matches the value stored in state performance_mode = "generalPurpose" throughput_mode = "bursting" tags = merge(var.aws_tags, { Name = var.eks_efs_name }) }
This ensures your config’s value aligns perfectly with what’s stored in Terraform’s state, eliminating the false "change" that triggers recreation.
Security Group Recreations: Not a Universal Terraform Bug
The issue you read about with security groups and data sources isn’t a widespread Terraform bug—it’s almost always tied to unstable data source outputs or misconfigured dependencies.
Common triggers include:
- A data source that returns slightly varying values on each refresh (e.g., extra whitespace, case differences in CIDR blocks)
- Unnecessary
depends_onclauses that force Terraform to re-evaluate the security group even when no changes are needed - Dynamic values in the security group name or rules that Terraform misinterprets as changes
Troubleshooting Steps for Security Groups
- Stabilize data source outputs: If you’re using data sources for CIDR blocks or rule values, use functions like
trim()to ensure consistent formatting. - Remove redundant
depends_on: Let Terraform automatically infer dependencies unless you have a specific reason to override them. Forcing dependencies can lead to unnecessary re-creations. - Test with
terraform plan -refresh=false: This skips refreshing data sources. If the plan shows no changes when you run this, the issue is likely a fluctuating data source output.
Do You Need a Lifecycle Hook?
Short answer: No—not for this scenario. Lifecycle hooks like ignore_changes or prevent_destroy would only mask the underlying problem (the ARN mismatch) instead of fixing it. It’s always better to resolve the root cause rather than patch over it with lifecycle settings.
内容的提问来源于stack exchange,提问作者Theo Sweeny

