修改 Cloud Storage 存储桶名称时需要注意的陷阱
由于最近经常从事数据基础架构建设的工作,我开始使用Terraform进行对GCP的操作。这次我要介绍的是在更改Cloud Storage桶名称时容易陷入困境的地方。当然,不仅仅是Cloud Storage,在其他服务或AWS上也有一些可应用的地方吧。
Terraform 版本 1.1.2
运行在 darwin_arm64 上
供应商 registry.terraform.io/hashicorp/google 版本 4.15.0尚未验证其他环境是否正常运行。
由来
在创建了以下存储桶并在验证环境中应用后,我提交了PR。
resource "google_storage_bucket" "my_bucket" {
name = "my-bucket"
storage_class = var.gcs_storage_class.coldline
project = var.project_id
location = var.gcs_location
force_destroy = false
uniform_bucket_level_access = true
retention_policy {
is_locked = true
retention_period = 30
}
lifecycle_rule {
condition {
age = 30
}
action {
type = "Delete"
}
}
}
接受了团队成员的审查后,他们告诉我说将存储桶名称从my-bucket改为my-bucket-hoge更好。于是我执行了terraform apply来进行该名称更改,但出现了错误。当然,在最开始的时候,我将force_destroy设置为false,因为存储桶内有对象存在,所以无法强制更改。
force_destroy - (Optional, Default: false) When deleting a bucket, this boolean option will delete all contained objects. If you try to delete a bucket that contains objects, Terraform will fail that run.
我找到了两个解决办法。
-
- 删除存储桶内的对象后,再次执行terraform apply。
完全删除存储桶。
除非有特殊原因,否则1明显更方便。如果必须完全删除此开发用存储桶,或者(像作者一样)在控制台中意外删除存储桶,则需要采取额外的措施。
桶被删除时的应对措施 shí de
首先,执行terraform plan
Error: Error acquiring the state lock
Error message: resource temporarily unavailable
由于Terraform和GCP的状态不一致,因此可以对其进行锁定。
可以使用terraform force-unlock {你的锁定ID}命令来解除锁定。这个操作非常危险,建议在确认团队成员最近是否进行了操作后再执行。
当再次执行terraform plan时,似乎会无限停留在”Refreshing state…”。根据官方文档的调查,设置环境变量并重新执行plan可以查看更详细的日志。
export TF_LOG=TRACE
terraform plan
---[ RESPONSE ]--------------------------------------
HTTP/2.0 404 Not Found
Content-Length: 171
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json; charset=UTF-8
Date: Fri, 27 May 2022 01:12:48 GMT
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Pragma: no-cache
Server: UploadServer
Vary: Origin
Vary: X-Origin
X-Guploader-Uploadid: xxxx
{
"error": {
"code": 404,
"message": "The specified bucket does not exist.",
"errors": [
{
"message": "The specified bucket does not exist.",
"domain": "global",
"reason": "notFound"
}
]
}
}
尽管应该存在一个存储桶,但却一直不断出现“存储桶不存在”错误消息。原因是terraform的状态仍然是旧的。幸运的是,Terraform已经提供了一个功能,可以删除旧状态,即terraform state rm命令。请使用以下命令来删除最初创建的存储桶的状态。
terraform state rm module.storage.google_storage_bucket.my_bucket
再次执行terraform plan将解决问题。
除了云存储外,当发生类似情况时,我们也可以利用这次的经验。
那么,再见!