Terraform以正确的顺序创建资源,但以错误的顺序破坏资源

时间:2020-02-03 17:40:19

标签: terraform

我有一个配置,该配置在azure中创建6个资源组,然后在它们上循环以为特定服务主体分配对这些资源组的贡献者访问权限。代码是这样的:

在运行Terraform之前自动生成

locals {
  pod_rg_key_list = ["non_regional_web_rg","regional_data_rg['centralus']","regional_data_rg['eastus2']","regional_web_rg['centralus']","regional_web_rg['eastus2']"]
  pod_rg_list = [azurerm_resource_group.non_regional_web_rg,azurerm_resource_group.regional_data_rg["centralus"],azurerm_resource_group.regional_data_rg["eastus2"],azurerm_resource_group.regional_web_rg["centralus"],azurerm_resource_group.regional_web_rg["eastus2"]]
}

main.tf

...
locals {
  injected_rg_key_list = ["cfg"]
  injected_rg_list     = [azurerm_resource_group.cfg]
  all_rg_key_list      = concat(local.pod_rg_key_list, local.injected_rg_key_list)
  all_rg_list          = concat(local.pod_rg_list, local.injected_rg_list)
}

resource "azurerm_role_assignment" "pod_sp_contributor_to_pod_rgs" {
  for_each = toset(local.all_rg_key_list)

  scope              = local.all_rg_list[index(local.all_rg_key_list, each.value)].id
  role_definition_id = data.azurerm_role_definition.contributor.id
  principal_id       = azuread_service_principal.sp.id
}
...

这是我发现让terraform创建角色分配而不会抱怨for_each由于动态bla-bla-bla而无法解析并建议使用-target运行terraform apply的唯一方法。

因此,它可以很好地创建角色分配。但是,当我运行销毁时,terraform首先销毁资源组,然后销毁角色分配,这是错误的,当然,它会失败。

更多上下文

通常,我的代码是自动化构建的一部分,该自动化构建采用基本配置,标识所有资源组,附加另一个terraform文件,然后在整个shebang上运行terraform。

因此,它标识资源组的方式是通过运行terraform plan -out main.tfplan并使用保证从头开始部署的变量。然后将计划转换为json并提取资源组地址。然后可以将它们注入到由构建添加的其他terraform代码中,然后再次运行terraform plan,最后运行terraform apply

因此我无法对depends_on语句进行硬编码,因为实际资源组的列表是由运行时的构建推导的。我还必须自动生成depends_on语句,这是我想避免的语句。我的理由-当前,所有自动生成的内容都只是局部变量,所有变量都在单独的文件中找到。如果我被迫自动生成depends_on语句,那么我将不得不打破这种分离。

我觉得必须有一种更好的方法来实现自己的目标。

编辑

因此,我更改了代码-将角色分配资源移至我要进行替换的文件中。这使我可以自动生成depends_on语句。这是新文件:

locals {
  pod_rg_key_list = ["non_regional_web_rg", "regional_data_rg['centralus']", "regional_data_rg['eastus2']", "regional_web_rg['centralus']", "regional_web_rg['eastus2']", "cfg"]
  pod_rg_list = [azurerm_resource_group.non_regional_web_rg, azurerm_resource_group.regional_data_rg["centralus"], azurerm_resource_group.regional_data_rg["eastus2"], azurerm_resource_group.regional_web_rg["centralus"], azurerm_resource_group.regional_web_rg["eastus2"], azurerm_resource_group.cfg]
}

### Grant Contributor access to the resource groups

data "azurerm_role_definition" "contributor" {
  name  = "Contributor"
  scope = "/subscriptions/${data.azurerm_subscriptions.sub.subscriptions.0.subscription_id}"
}

resource "azurerm_role_assignment" "pod_sp_contributor_to_pod_rgs" {
  for_each = toset(local.pod_rg_key_list)

  depends_on         = [azurerm_resource_group.non_regional_web_rg, azurerm_resource_group.regional_data_rg["centralus"], azurerm_resource_group.regional_data_rg["eastus2"], azurerm_resource_group.regional_web_rg["centralus"], azurerm_resource_group.regional_web_rg["eastus2"], azurerm_resource_group.cfg]
  scope              = local.pod_rg_list[index(local.pod_rg_key_list, each.value)].id
  role_definition_id = data.azurerm_role_definition.contributor.id
  principal_id       = azuread_service_principal.sp.id
}

但是它仍然不起作用:

Error: Invalid index

  on ..\..\modules\bootstrap\powershell.tf line 5, in locals:
   5:   pod_rg_list = [azurerm_resource_group.non_regional_web_rg, azurerm_resource_group.regional_data_rg["centralus"], azurerm_resource_group.regional_data_rg["eastus2"], azurerm_resource_group.regional_web_rg["centralus"], azurerm_resource_group.regional_web_rg["eastus2"], azurerm_resource_group.cfg]
    |----------------
    | azurerm_resource_group.regional_data_rg is object with no attributes

The given key does not identify an element in this collection value.


Error: Invalid index

  on ..\..\modules\bootstrap\powershell.tf line 5, in locals:
   5:   pod_rg_list = [azurerm_resource_group.non_regional_web_rg, azurerm_resource_group.regional_data_rg["centralus"], azurerm_resource_group.regional_data_rg["eastus2"], azurerm_resource_group.regional_web_rg["centralus"], azurerm_resource_group.regional_web_rg["eastus2"], azurerm_resource_group.cfg]
    |----------------
    | azurerm_resource_group.regional_data_rg is object with no attributes

The given key does not identify an element in this collection value.


Error: Invalid index

  on ..\..\modules\bootstrap\powershell.tf line 5, in locals:
   5:   pod_rg_list = [azurerm_resource_group.non_regional_web_rg, azurerm_resource_group.regional_data_rg["centralus"], azurerm_resource_group.regional_data_rg["eastus2"], azurerm_resource_group.regional_web_rg["centralus"], azurerm_resource_group.regional_web_rg["eastus2"], azurerm_resource_group.cfg]
    |----------------
    | azurerm_resource_group.regional_web_rg is object with no attributes

The given key does not identify an element in this collection value.


Error: Invalid index

  on ..\..\modules\bootstrap\powershell.tf line 5, in locals:
   5:   pod_rg_list = [azurerm_resource_group.non_regional_web_rg, azurerm_resource_group.regional_data_rg["centralus"], azurerm_resource_group.regional_data_rg["eastus2"], azurerm_resource_group.regional_web_rg["centralus"], azurerm_resource_group.regional_web_rg["eastus2"], azurerm_resource_group.cfg]
    |----------------
    | azurerm_resource_group.regional_web_rg is object with no attributes

The given key does not identify an element in this collection value.

请注意,它仅在破坏环境时才会损坏。

编辑2

使用各自的资源组销毁了实际的角色分配,但是我不明白为什么尽管depends_on发出了明确的信息,但terraform试图在资源组之后销毁它们。

1 个答案:

答案 0 :(得分:1)

当我发现我运行的是0.12.18版本而不是最新的0.12.20版本时,我几乎要向Terraform打开一个错误。升级到0.12.20解决了这个问题!

我检查了0.12.20的更改日志,并且自0.12.18退出以来没有发现任何相关性。但这是事实-使用0.12.20,而不使用0.12.18。