我们正在测试可重用的地形模块来创建GCP资源,同样我们可以使用count变量来实现。现在,我们面临着一个挑战,那就是淘汰/摧毁其中一/两个被创造出来的资源。同时销毁先前创建的资源,使其他资源被重新创建。
Terraform will perform the following actions:
# google_service_account.sa_npe_policy[1] must be replaced
-/+ resource "google_service_account" "sa_npe_policy" {
~ account_id = "sa-test13" -> "sa-test11" # forces replacement
~ display_name = "sa-test13" -> "sa-test11"
~ email = "sa-test13@gcp-prj-npe.iam.gserviceaccount.com" -> (known after apply)
~ id = "projects/gcp-prj-npe/serviceAccounts/sa-tegcp-prj-npe.iam.gserviceaccount.com" -> (known after apply)
~ name = "projects/gcp-prj-npe/serviceAccounts/sa-test13@gcp-prj-npe.iam.gserviceaccount.com" -> (known after apply)
project = "gcp-prj-npe"
~ unique_id = "111295737867502004228" -> (known after apply)
}
# google_service_account.sa_npe_policy[2] will be created
+ resource "google_service_account" "sa_npe_policy" {
+ account_id = "sa-test13"
+ display_name = "sa-test13"
+ email = (known after apply)
+ id = (known after apply)
+ name = (known after apply)
+ project = "gcp-prj-npe"
+ unique_id = (known after apply)
}
Plan: 2 to add, 0 to change, 1 to destroy.
在这里,我们试图删除sa-test11,它正在影响下一个资源sa-test13,以sa-test11取代。
我们正在寻找没有重新创建/替换已经创建的资源,我们需要删除中间的任何一个资源。
尽管您发布的输出表明您正在尝试添加第三个资源而不是删除一个资源,但我将尝试解释您可以采取的一般方法。
假设您的初始代码如下所示,现在您想要删除satest12
:
variable "sa_name" {
type = list(string)
default = ["satest11", "satest12", "satest13"]
}
resource "google_service_account" "sa_npe_policy" {
count = length(var.sa_name)
account_id = var.sa_name[count.index]
display_name = var.sa_name[count.index]
project = "gcp-prj-npe"
}
如果您只是从列表中删除"satest12"
, Terraform将建议您删除satest12
和satest13
,然后重新创建satest13
。
为什么?
Terraform内部存储你的资源的状态,你的每个资源将被分配一个内部地址。satest12
的地址是google_service_account.sa_npe_policy[1]
,satest13
的地址是google_service_account.sa_npe_policy[2]
。现在,如果您删除"satest12"
,资源列表只包含两个元素,因此satest13
将获得地址google_service_account.sa_npe_policy[1]
。
Terraform -不知什么原因-无法识别资源已经存在于另一个地址,所以它建议删除两个资源并创建一个。
你怎么能规避呢?
幸运的是,Terraform为我们提供了操纵其内部状态的方法。因此,在删除"satest12"
之后,不要立即执行terraform apply
。而不是执行
tf state mv 'google_service_account.sa_npe_policy[1]' 'google_service_account.choose_an_unused_name'
tf state mv 'google_service_account.sa_npe_policy[2]' 'google_service_account.sa_npe_policy[1]'
这样你
- 将
satest12
重设为未使用的地址 - 将
satest13
重设为satest12
先前使用的地址
如果你现在运行terraform apply
, Terraform会意识到没有必要重新创建satest13
,只会破坏satest12
。