4. Terraform Refresh:refresh 命令作用、refresh 与 plan 的区别、refresh 使用场景
terraform refresh 是 Terraform 工作流中一个容易被低估但极其重要的命令。它的核心职责是 同步状态文件,让 Terraform 重新认识当前真实的基础设施状态。在漂移检测与修复的上下文中,refresh 是发现漂移的起点,也是后续 plan 和 apply 的基础。
4.1 refresh 命令的作用
terraform refresh 会读取当前 Terraform 配置中管理的所有资源,然后调用对应 Provider 的 API 去查询这些资源在云平台上的 实时属性,最后用查询到的真实值更新本地的 terraform.tfstate 状态文件。
refresh 执行后,状态文件中的属性值会与云上资源完全一致。如果有人在云控制台手动修改了安全组规则、调整了实例规格,或者通过其他工具删除了资源,这些变化都会通过 refresh 被“拉取”到状态文件中。
| 操作 | 是否读取云 API | 是否修改状态文件 | 是否修改真实资源 | 是否输出变更计划 |
|---|---|---|---|---|
| terraform refresh | 是 | 是(更新为当前真实值) | 否 | 否(仅输出状态对比摘要) |
| terraform plan | 是 | 否(仅读取) | 否 | 是(生成变更计划) |
| terraform apply | 是 | 是(写入新状态) | 是 | 是(执行变更) |
4.2 refresh 与 plan 的区别
很多初学者容易混淆 refresh 和 plan,因为两者都会读取云 API 并输出一些信息。但它们的 目的 和 产出 有本质区别:
- refresh 的目标:让状态文件与真实世界对齐。它不关心配置代码(
.tf文件)写了什么,只关心“云上现在是什么样”。 - plan 的目标:对比状态文件(已更新或未更新)与配置代码之间的差异,生成一份“从当前状态到期望状态”的变更计划。plan 的输出是 动作列表(哪些资源要创建、修改、删除)。
在实际工作流中,refresh 通常作为 plan 的前置步骤。Terraform 官方也推荐在运行 plan 之前先执行 refresh,以确保 plan 基于最新的状态进行差异计算。从 Terraform 0.15.4 开始,terraform plan 默认会自动执行 refresh(除非显式使用 -refresh=false 禁用)。
4.3 refresh 使用场景
以下场景中,terraform refresh 是必不可少的操作:
| 场景 | 说明 | 推荐做法 |
|---|---|---|
| 漂移检测 | 怀疑有人手动修改了云资源,需要确认状态文件是否已过期 | 先 refresh,再 plan,对比漂移量 |
| 团队协作 | 其他成员通过 apply 修改了基础设施,本地状态文件落后 | 执行 refresh 拉取最新状态,避免 plan 误判 |
| 资源导入后 | 使用 terraform import 导入现有资源后,需要刷新确认导入属性完整 |
import 后立即 refresh 验证 |
| 状态文件损坏恢复 | 状态文件丢失或损坏,需要从真实资源重建状态 | 配合 terraform init 和 terraform state pull 使用 |
| CI/CD 流水线 | 自动化部署前需要确保状态文件与云上一致 | 在 plan 步骤前显式执行 refresh(或依赖 plan 的自动 refresh) |
terraform plan 默认会执行 refresh。但在某些场景下(如大规模基础设施,refresh 耗时过长),你可能希望使用 terraform plan -refresh=false 跳过 refresh 以加速 plan。此时需要确保状态文件足够新,否则 plan 结果可能不准确。
4.4 refresh 工作流程示意图
下图展示了 refresh 命令在 Terraform 工作流中的位置及其与 plan、apply 的关系:
4.5 实际使用示例
以下是一个典型的漂移检测场景,展示 refresh 如何帮助发现手动修改:
# 1. 初始状态:状态文件与云上一致
terraform apply -auto-approve
# 2. 有人通过云控制台手动修改了安全组规则(漂移发生)
# 3. 执行 refresh 发现漂移
terraform refresh
# 输出示例:
# aws_security_group.web_sg: Refreshing state... [id=sg-0123456789abcdef0]
# aws_instance.web_server: Refreshing state... [id=i-0a1b2c3d4e5f67890]
#
# 注意:refresh 会显示资源的当前属性,但不会标记为“漂移”
# 4. 执行 plan 确认漂移
terraform plan
# 输出示例:
# Terraform will perform the following actions:
# # aws_security_group.web_sg will be updated in-place
# ~ resource "aws_security_group" "web_sg" {
# name = "web-sg"
# ~ ingress = [
# + {
# cidr_blocks = [
# + "0.0.0.0/0",
# ]
# ...
# },
# ]
# }
# Plan: 0 to add, 1 to change, 0 to destroy.
terraform plan 之前显式执行 terraform refresh,并将 refresh 的输出日志保存为构建产物。这样当 plan 出现意外变更时,可以通过 refresh 日志追溯状态文件是否在 plan 之前已经正确同步。
4.6 refresh 的局限性
虽然 refresh 是漂移检测的重要工具,但它并非万能:
- 不检测配置漂移:refresh 只更新状态文件,不会告诉你配置代码与真实资源之间的差异。要检测配置漂移,必须运行
terraform plan。 - 不处理被删除的资源:如果某个资源在云上被手动删除,refresh 会在状态文件中将其标记为“已删除”,但不会自动从状态文件中移除。你需要运行
terraform apply或terraform state rm来清理。 - 性能开销:对于拥有数百个资源的大型基础设施,refresh 可能需要数分钟甚至更长时间,因为它会逐个调用每个资源的 API。
terraform refresh,尤其是对 API 调用有速率限制的 Provider(如 AWS、Azure)。建议在 plan 之前执行一次即可,或者依赖 plan 的自动 refresh 功能。