Terraform:State、变更与接管

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。

在目标 Terraform 工作目录操作,先确认 backend 与 Project。

推荐做法#

  • GCS state 独立管理权限并启用 Object Versioning;state/plan 文件按敏感数据处理。
  • GCS backend 支持锁;同一资源由单一配置管理,不与手工变更并行争用。
  • 已有资源先写等价配置再 import;审查 plan 的替换/删除后再 apply。

常用操作#

terraform workspace show
terraform state list
terraform plan -out=tfplan
# 审查 tfplan 后才执行:terraform apply tfplan

容易踩的坑#

  • gcloud CLI 登录不等于 ADC 已配置;Provider 与 backend 都需要对应权限。
  • import 不会自动接管整个 Project;锁与版本备份解决的是不同问题。

本地认证 · 循环依赖

配置说明与完整示例(按需展开)

前置:环境篇、已安装 Terraform。先用 gcloud 理解资源,再用 Terraform 管理独立资源;同一资源不要同时被两套配置管理。

遇到 GKE/provider 循环、模块互相依赖或拆分 state,参见 Terraform 循环依赖企业手册。

State、锁与凭据分别管什么#

配置 作用
GCS backend 的 bucket / prefix 保存这份基础设施的 state;不同环境使用不同路径与适用权限
State locking 协调同一 state 的 Terraform 并发写入;GCS backend 支持,无须另建锁表
Bucket Object Versioning 为 state 误改/误删提供恢复版本;不能代替锁或业务备份
Provider / backend credentials 分别需要目标资源管理权和 state 访问权;可使用 ADC,与普通 gcloud 登录分开

plan 展示拟执行的差异;apply tfplan 才执行该计划。import 将已有资源记录到 state,仍需对应配置。不要在存在运行中的 apply 时强制解锁。GCS backend、ADC

创建远程 State#

source lab.env
gcloud auth application-default login
export TF_STATE_BUCKET="${PROJECT_ID}-tfstate"
gcloud storage buckets create "gs://$TF_STATE_BUCKET" --location="$REGION" --uniform-bucket-level-access --public-access-prevention
gcloud storage buckets update "gs://$TF_STATE_BUCKET" --versioning
mkdir -p terraform-lab
cd terraform-lab

State / plan 可能保存密码等敏感数据,sensitive 标记不等于文件加密。 独立限制访问,不提交 Git;state Bucket 用 bootstrap 管理,不让业务 state 销毁自身存储。State 中的敏感数据

保存 main.tf:

terraform {
  required_version = ">= 1.6.0"
  required_providers {
    google = { source = "hashicorp/google", version = "~> 6.0" }
  }
  backend "gcs" {}
}
variable "project_id" { type = string }
variable "region" { type = string }
provider "google" {
  project = var.project_id
  region  = var.region
}
resource "google_storage_bucket" "archive" {
  name                        = "${var.project_id}-tf-archive"
  location                    = var.region
  uniform_bucket_level_access = true
  public_access_prevention    = "enforced"
  force_destroy               = false
  labels = { env = "lab", managed_by = "terraform" }
}
output "bucket_name" { value = google_storage_bucket.archive.name }

固定 provider 主版本是实验基线,不宣称是最新版本;提交 .terraform.lock.hcl,按官方升级指南升级。Google provider

export TF_VAR_project_id="$PROJECT_ID"
export TF_VAR_region="$REGION"
terraform init -backend-config="bucket=$TF_STATE_BUCKET" -backend-config='prefix=lab/archive'
terraform fmt
terraform validate
terraform plan -out=tfplan
terraform apply tfplan
terraform plan

验收:最后一次 plan 显示无变更。用 Console 修改实验桶 label,再 plan 看出漂移,然后 apply 恢复声明状态。

已有 CLI 创建的资源要先写等价配置,再 terraform import 并审查 plan;不能期待 Terraform 自动接管整个项目。新增资源按网络、身份、应用、监控拆模块,模块输出只包含下游需要的 ID。

删除与验证#

terraform plan -destroy -out=destroy.tfplan
terraform apply destroy.tfplan
terraform state list
cd ..
# 确认没有其他环境使用此专用 state 桶后
gcloud storage rm --all-versions --recursive "gs://$TF_STATE_BUCKET"

如果业务桶有对象,force_destroy=false 会阻止删除;先明确备份和保留需求再处理。不要将数据库密码作为普通 Terraform resource 参数而忽略 state 中的明文副本。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭