计划使用可重复使用的 TF 模块使用 .tfvars 文件创建 GCP 资源并且需要 post 销毁中间资源下一个资源不应重新创建

Planning to use reusable TF module to create GCP resource using .tfvars file and need post destroy of middle resource next resource shouldn't recreate

我们正在测试可重复使用的 terraform 模块来创建 GCP 资源,同样我们可以使用计数变量来实现。现在我们对中间创建的资源 decommission/destroy one/two 提出了挑战。同时销毁先前创建的资源,使其他资源重新创建。

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。

我们正在寻找的东西没有 recreate/replace 对于已经创建的资源,我们需要删除中间的任何一个资源。

尽管您发布的输出表明您正在尝试添加第三个资源而不是删除一个资源,但我将尝试解释您可以采用的一般方法。

假设您的初始代码看起来与以下类似,您现在想要删除 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 会建议您删除 satest12satest13 然后重新创建 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]'

你这样

  1. satest12 重新设置为一个未使用的地址
  2. 将地址 satest13 改为 satest12
  3. 之前使用的地址

如果你现在 运行 terraform apply,Terraform 将认识到没有必要重新创建 satest13 并且只会破坏 satest12.