处理Terraform中的”无法销毁实例”问题
我們目前正在開發新服務,我們正在使用Terraform進行操作。
雖然Terraform非常方便,但也有很多容易出錯的地方。
因为处理Cloud KMS的Key时出现了”无法销毁实例”错误,耗费了一些时间,因此记录下了相应的处理内容。
环境
-
- GCP
-
- Terraform : Ver.1.0.1
- 利用したmodule : terraform-google-modules/kms/google Ver. 1.2
将手动创建的Cloud KMS密钥同步到Terraform。
-
- 我通过Terraform创建了Cloud KMS的keyring和key(“key_terraform”)。
- 我手动在GCP的控制台上手动创建了Key(“key_manual”)。
我试图将手动创建的密钥反映到Terraform中。
“发生了无法销毁的情况”
在尝试将以下的tf文件反映到Terraform时,进行terraform plan操作出现了以下错误。
module "kms" {
source = "terraform-google-modules/kms/google"
version = "~> 1.2"
project_id = "sample_project"
location = "global"
keyring = "sample_key_ring"
keys = ["key_terraform", "key_manual"]
set_owners_for = []
key_rotation_period = "157680000s"
}
$ terraform plan
....
│ Error: Instance cannot be destroyed
│
│ on .terraform/modules/kms/main.tf line 27:
│ 27: resource "google_kms_crypto_key" "key" {
│
│ Resource module.kms.google_kms_crypto_key.key[0] has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable
│ lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.
│ Error: Instance cannot be destroyed
│
│ on .terraform/modules/kms/main.tf line 27:
│ 27: resource "google_kms_crypto_key" "key" {
│
│ Resource module.kms.google_kms_crypto_key.key has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable
│ lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.
当出现此错误时,其他资源的应用不会生效,因此需要解决。
将prevent_destroy设为true。
Terraform之所以不能删除Cloud KMS的密钥,正如错误信息所述,是因为它进行资源的重建。
查看模块文档后,发现有一个名为”prevent_destroy”的参数,因此进行附加。
module "kms" {
source = "terraform-google-modules/kms/google"
version = "~> 1.2"
project_id = "sample_project"
location = "global"
keyring = "sample_key_ring"
keys = ["key_terraform", "key_manual"]
set_owners_for = []
key_rotation_period = "157680000s" # 追加
}
$ terraform plan
....
│ Error: Instance cannot be destroyed
│
│ on .terraform/modules/kms/main.tf line 27:
│ 27: resource "google_kms_crypto_key" "key" {
│
│ Resource module.kms.google_kms_crypto_key.key has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable
│ lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.
错误减少了一个,但是同样的错误发生了。
Terraform正在尝试重新创建手动创建的密钥“key_manual”,
似乎认为即使名称相同,Terraform设置和实际密钥也是不同的。
将key_rotation_period(密钥轮换周期)与tf文件保持一致也无效。
在GCP控制台上使用terraform创建的”key_terraform”与现有内容没有差异。
编辑tfstate文件
在调查的过程中,我找到了以下stackoverflow的帖子。
就像在这里所说的那样,似乎只有编辑放置在GCS上的state文件的选项了。
在下载的state文件中,我们将比较“key_terraform”和“key_manual”的设置值。
在进行备份的同时,我进行了针对”key_terraform”的编辑。
然后,再次执行terraform plan命令。
$ terraform plan
....
│ No changes. Your infrastructure matches the configuration.
终于,没有差分了,已经反映出来了!
根据Stack Overflow的评论所述,虽然可以使Cloud KMS的密钥无法使用并销毁,但完全删除似乎不可行,因此不适合在terraform重新创建的设计中使用。
在GCP中,由于无法立即重新创建拥有相同名称的实例,比如CloudSQL,因此在这种情况下,可能需要采取避免删除的措施,或直接编辑状态文件。