使用 Terraform 时锁定状态文件的 Google Cloud Platform 机制是什么? 类似 AWS 上的
DynamoDB
...
谢谢
gcs
后端通过使用带有.tflock
扩展名的特殊锁定文件来实现Terraform状态锁定。在 Terraform 状态操作期间,此文件放置在 Terraform 状态本身旁边。例如,如果状态文件位于路径
gs://BUCKET/PREFIX/WORKSPACE.tfstate
那么相应的锁定文件将位于path
gs://BUCKET/PREFIX/WORKSPACE.tflock
锁定的原子性是通过使用称为 Precondition 的 GCS 功能来保证的。 Terraform 本身利用 GCP Go SDK 的 DoesNotExist 条件,而后者又使用 GCS Precondition。在下面,这会将此 HTTP 标头
x-goog-if-generation-match: 0
添加到 GCS 复制请求中。
根据GCS文档:
当
前提条件使用值 0 而不是代号时,仅当 Cloud Storage 存储桶中不存在具有请求中指定名称的活动对象时,请求才会成功。Match
这正是 Terraform 状态锁定所需要的。
Google Cloud Platform 与大多数远程后端一样本身支持锁定。 AWS 不支持通过 S3 本地锁定,但它可以像您提到的那样通过 DynamoDB 进行锁定。
运行
terraform apply
,Terraform会自动获取锁;如果其他人已经在运行 apply,他们就已经拥有锁,你就必须等待。
您可以使用
apply
参数运行 -lock-timeout=<TIME>
来告诉 Terraform 等待 TIME
来释放锁(例如,-lock-timeout=10m
将等待 10 分钟)。
在 Terraform 操作期间,Terraform 会在与状态文件相同的 GCS 存储桶和前缀中自动创建一个扩展名为 .tflock 的锁定文件。 例如,如果状态文件位于 gs://my-bucket/terraform/state.tfstate,则锁定文件将位于 gs://my-bucket/terraform/state.tflock。
Terraform 使用GCS 的DoesNotExist 前提条件来检查锁定文件是否已存在。 这是使用 HTTP 标头 x-goog-if- Generation-match: 0 实现的。如果锁定文件不存在( Generation = 0),则锁定操作成功。如果锁文件存在,则操作失败,说明当前有另一个进程持有该锁。
Terraform 操作完成后,锁定文件将被删除。锁的释放允许其他进程获取它以进行操作。