簡體   English   中英

Terraform: for_each 一個一個

[英]Terraform : for_each one by one

我在 terraform 上創建了一個模塊,這個模塊創建了aws_servicecatalog_provisioned_product資源。
當我從根調用這個模塊時,我使用 for_each 來運行一個對象列表。
該模塊運行此對象列表並並行創建aws_servicecatalog_provisioned_product資源。
有沒有辦法一個一個地創建資源? 我希望模塊將等待第一次迭代完成並在之后創建下一次迭代。

我正在使用 terraform 創建資源的templatefile文件depends on順序,然后 terraform 一個一個地創建資源。

這是代碼:

locals {

     expanded_accounts = [ 
      {
          AccountEmail                           = example1@example.com
          AccountName                         = example1
          ManagedOrganizationalUnit           = example_ou1
          SSOUserEmail                        = example1@example.com
          SSOUserFirstName                    = Daniel
          SSOUserLastName                     = Wor
          ou_id                               = ou_id1
      },
      {
          AccountEmail                           = example2@example.com
          AccountName                         = example2
          ManagedOrganizationalUnit           = example_ou2
          SSOUserEmail                        = example2@example.com
          SSOUserFirstName                    = Ben
          SSOUserLastName                     = John
          ou_id                               = ou_id2
     }
     ]

  previous_resource = [
    for acc in local.expanded_accounts :
    acc.AccountName
  ]

     resources = { res = local.expanded_accounts, previous = concat([""], local.previous_resource)
}

resource "local_file" "this" {
  content              = templatefile("./provisioned_accounts.tpl", local.resources)
  filename             = "./generated_provisioned_accounts.tf"
  directory_permission = "0777"
  file_permission      = "0777"

  lifecycle {
    ignore_changes = [directory_permission, file_permission, filename]
  }
}

provisioned_accounts.tpl配置:

%{ for acc in res }
resource "aws_servicecatalog_provisioned_product" "${acc.AccountName}" {
  name                     = "${acc.AccountName}"
  product_id               = replace(data.local_file.product_name.content, "\n", "")
  provisioning_artifact_id = replace(data.local_file.pa_name.content, "\n", "")
  

  provisioning_parameters {
    key   = "SSOUserEmail"
    value = "${acc.SSOUserEmail}"
  }
  provisioning_parameters {
    key   = "AccountEmail"
    value = "${acc.AccountEmail}"
  }
  provisioning_parameters {
    key   = "AccountName"
    value = "${acc.AccountName}"
  }
  provisioning_parameters {
    key   = "ManagedOrganizationalUnit"
    value = "${acc.ManagedOrganizationalUnit} (${acc.ou_id})"
  }
  provisioning_parameters {
    key   = "SSOUserLastName"
    value = "${acc.SSOUserLastName}"
  }
  provisioning_parameters {
    key   = "SSOUserFirstName"
    value = "${acc.SSOUserFirstName}"
  }

  timeouts {
    create = "60m"
  }

%{if index != 0 }
  depends_on = [aws_servicecatalog_provisioned_product.${previous[index]}]
%{ endif }

}

%{~ endfor ~}

有沒有辦法一個一個地創建資源?

可悲的是,沒有這種方法,除非您刪除for_each並使用depends_on分別創建所有模塊。

TF 不是一種過程語言,它總是會為for_eachcount並行做一些事情。

如果要確保一個接一個地創建它們,則必須刪除for_each並為每個元素使用depends_on

如果您只想在其他資源之前配置第一個資源:

僅分離第一個資源並將for_each用於剩余資源。 您可以使用depends_on放置顯式依賴項,以使剩余資源依賴於第一個資源。 因為for_each需要一個setmap ,所以這個輸入需要一些修改才能排除第一個資源的配置。

如果您確實需要一個一個地配置資源,一種更激進的方法是使用-parallelism=1運行apply命令。 這會將並行供應的資源數量減少到 1。這將適用於整個項目。 我不建議這樣做,因為它會大大增加應用程序的運行時間。

為什么要讓它等待之前的創建? Terraform 依賴於提供者知道可以並行發生的事情,並將在可能的地方並行運行。

如果我願意的話,在應用操作之前設置並行度將是我如何限制它的人為性,因為它是一種技術解決方法,可以讓您的 Terraform 代碼易於閱讀。

TF_CLI_ARGS_apply="-parallelism=1"
terraform apply

如果您發現這會減慢所有 Terraform 的創建速度,但您需要一次部署一個特定的資源集,那么可能是時候將這些特定資源分解到它們自己的 Terraform 配置目錄中,並在不同的步驟中應用它再次使用並行度設置資源的 rest。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM