为何Terraform会重建未发生变更的AWS与MongoDB Atlas资源?
Terraform重复apply时无变更资源被销毁重建的问题
我有一套用于在AWS和MongoDB Atlas部署资源的Terraform代码,首次执行apply时资源创建符合预期,但立即再次执行apply时,Terraform会提示销毁并重建大量未实际变更的资源。
以Route53资源为例,Terraform声称zone_id发生变化需要重建aws_route53_record,但实际该值并未改变。
示例代码
data "aws_route53_zone" "selected" { name = var.domain } resource "aws_route53_record" "record" { name = "REDACTED" type = "A" zone_id = data.aws_route53_zone.selected.zone_id alias { evaluate_target_health = "false" name = var.accelerator_dns_name zone_id = var.accelerator_zone_id } }
执行日志
# module.REDACTED.data.aws_route53_zone.selected will be read during apply # (depends on a resource or a module with changes pending) <= data "aws_route53_zone" "selected" { + arn = (known after apply) + caller_reference = (known after apply) + comment = (known after apply) + id = (known after apply) + linked_service_description = (known after apply) + linked_service_principal = (known after apply) + name = "REDACTED" + name_servers = (known after apply) + primary_name_server = (known after apply) + resource_record_set_count = (known after apply) + tags = (known after apply) + vpc_id = (known after apply) + zone_id = (known after apply) } # module.REDACTED.aws_route53_record.record must be replaced -/+ resource "aws_route53_record" "record" { + allow_overwrite = (known after apply) ~ fqdn = "REDACTED" -> (known after apply) ~ id = "REDACTED" -> (known after apply) - multivalue_answer_routing_policy = false -> null name = "REDACTED" - records = [] -> null - ttl = 0 -> null ~ zone_id = "REDACTED" # forces replacement -> (known after apply) # forces replacement # (1 unchanged attribute hidden) # (1 unchanged block hidden) }
问题根源与解决方法
问题根源
日志显示data.aws_route53_zone.selected会在apply阶段才读取,这意味着Terraform在plan阶段无法确定其zone_id的值,导致每次plan时都会认为aws_route53_record的zone_id是未知的,从而标记资源需要重建。
解决方法
- 确保数据源在plan阶段解析:检查
var.domain是否依赖于某个仅在apply阶段创建的资源。如果是,调整依赖关系,让var.domain在plan阶段即可确定,或通过depends_on显式声明依赖,确保数据源提前解析。 - 直接传入固定zone_id:如果Route53 zone是预先存在的,可直接将
zone_id作为变量传入,替代动态数据源获取的方式,避免plan阶段值未知的问题。 - 校验数据源配置:确认
data.aws_route53_zone.selected的name参数与zone域名完全匹配(注意域名末尾的.,比如zone域名为example.com.时,var.domain也需保持一致),避免数据源每次重新查找导致的不稳定解析。
内容的提问来源于stack exchange,提问作者Ray Saltrelli
相关产品推荐
相关产品推荐

