【问题标题】:terraform resource block loopterraform 资源块循环
【发布时间】:2022-01-26 11:38:41
【问题描述】:

我正在使用google_access_context_manager_service_perimeter 提供程序在 GCP 中设置 VPC 服务控制。在这个资源中,在status 块中,我必须以"projects/123456789" 的格式将谷歌项目列表指定为resources 值。我想将项目编号放在一个变量中并创建类似的东西。

variable "project_numbers_to_protect" {
  type = list(any)
  default = [
    "123456",
    "456789",
    "894321"
  ]
}

我可以如下引用变量。

resources = ["projects/${var.project_numbers_to_protect[0]}",
             "projects/${var.project_numbers_to_protect[1]}",
             "projects/${var.project_numbers_to_protect[2]}"]

但在我的生产案例中,列表中有大量项目,我正在寻找动态引用它的选项。我尝试了count 选项,但没有成功。

count = var.project_numbers_to_protect
resources = ["projects/${var.project_numbers_to_protect[count.index]}"]

错误信息

vpc-sc-module $ terraform validate
╷
│ Error: Reference to "count" in non-counted context
│
│   on vpc-sc-copy.tf line 16, in resource "google_access_context_manager_service_perimeter" "regular_service_perimeter":
│   16:     resources = ["projects/${var.project_numbers_to_protect[count.index]}"]
│
│ The "count" object can only be used in "module", "resource", and "data" blocks, and only when the "count" argument is set.
╵

感谢任何帮助。谢谢。

完整代码

vpc-sc-copy.tf

resource "google_access_context_manager_service_perimeter" "regular_service_perimeter" {
  parent                    = "accessPolicies/${var.access_context_manager_policy_number}"
  name                      = "accessPolicies/${var.access_context_manager_policy_number}/servicePerimeters/${var.perimeter_name}"
  perimeter_type            = var.perimeter_type
  title                     = var.perimeter_name
  use_explicit_dry_run_spec = false
  status {
    restricted_services = var.restricted_services
    ## Below two lines works.
    # resources = ["projects/${var.project_numbers_to_protect[0]}",
    #   "projects/${var.project_numbers_to_protect[1]}",]
    ## Below option doesn't work
    count = var.project_numbers_to_protect
    resources = ["projects/${var.project_numbers_to_protect[count.index]}"]
    ingress_policies {
      ingress_from {
        identity_type = "ANY_IDENTITY"

        sources {
          access_level = "*"
        }
      }

      ingress_to {
        resources = [
            "*"
          ]
        dynamic "operations" {
          for_each = var.ingress_rule1_service_name
          content {
            service_name = operations.value
            method_selectors {
              method = "*"
            }
          }
        }


      }
    }
    egress_policies {
      egress_from {
        identities = ["serviceAccount:service-${var.project_number_to_protect}@gcp-sa-aiplatform-cc.iam.gserviceaccount.com"]
      }
      egress_to {
        resources = [
          "projects/${var.egress_rule1_project_number}"
        ]
        operations {
          service_name = "storage.googleapis.com"
          dynamic "method_selectors" {
            for_each = var.egress_rule1_methods
            content {
              method = method_selectors.value
            }
          }
        }
      }
    }
    egress_policies {
      egress_from {
        identity_type = "ANY_IDENTITY"
      }
      egress_to {
        resources = [
          "projects/${var.egress_rule2_project_number}"
        ]
        operations {

          service_name = "storage.googleapis.com"
          dynamic "method_selectors" {
            for_each = var.egress_rule2_methods
            content {
              method = method_selectors.value
            }
          }
        }
      }
    }


  }
}

vars.tf 的相关部分

variable "project_numbers_to_protect" {
  type = list(any)
  default = [
    "123456",
    "456789",
    "894321"
  ]
}

【问题讨论】:

  • 您使用count 的完整上下文是什么?你得到什么错误?
  • @Marcin vpc-sc-module $ terraform validate ╷ │ Error: Reference to "count" in non-counted context │ │ on vpc-sc-copy.tf line 16, in resource "google_access_context_manager_service_perimeter" "regular_service_perimeter": │ 16: resources = ["projects/${var.project_numbers_to_protect[count.index]}"] │ │ The "count" object can only be used in "module", "resource", and "data" blocks, and only when the "count" argument is set. ╵ vpc-sc-module $
  • 请用正确格式的错误和代码块更新问题。您的google_access_context_manager_service_perimeter 的完整源代码是什么?
  • @Marcin 我刚刚添加了完整的资源块和变量定义。谢谢。

标签: google-cloud-platform terraform terraform-provider-gcp


【解决方案1】:

正如错误所写,您不能以您想要的方式使用count。相反,它应该是:

resource "google_access_context_manager_service_perimeter" "regular_service_perimeter" {
  parent                    = "accessPolicies/${var.access_context_manager_policy_number}"
  name                      = "accessPolicies/${var.access_context_manager_policy_number}/servicePerimeters/${var.perimeter_name}"
  perimeter_type            = var.perimeter_type
  title                     = var.perimeter_name
  use_explicit_dry_run_spec = false
  status {
    restricted_services = var.restricted_services





    resources = [for project_number in var.project_numbers_to_protect:
                 "projects/${project_number}" ]





    ingress_policies {
      ingress_from {
        identity_type = "ANY_IDENTITY"

        sources {
          access_level = "*"
        }
      }

      ingress_to {
        resources = [
            "*"
          ]
        dynamic "operations" {
          for_each = var.ingress_rule1_service_name
          content {
            service_name = operations.value
            method_selectors {
              method = "*"
            }
          }
        }


      }
    }
    egress_policies {
      egress_from {
        identities = ["serviceAccount:service-${var.project_number_to_protect}@gcp-sa-aiplatform-cc.iam.gserviceaccount.com"]
      }
      egress_to {
        resources = [
          "projects/${var.egress_rule1_project_number}"
        ]
        operations {
          service_name = "storage.googleapis.com"
          dynamic "method_selectors" {
            for_each = var.egress_rule1_methods
            content {
              method = method_selectors.value
            }
          }
        }
      }
    }
    egress_policies {
      egress_from {
        identity_type = "ANY_IDENTITY"
      }
      egress_to {
        resources = [
          "projects/${var.egress_rule2_project_number}"
        ]
        operations {

          service_name = "storage.googleapis.com"
          dynamic "method_selectors" {
            for_each = var.egress_rule2_methods
            content {
              method = method_selectors.value
            }
          }
        }
      }
    }


  }
}

【讨论】:

  • 效果很好。谢谢。
猜你喜欢
  • 2021-10-04
  • 2021-12-08
  • 2020-01-21
  • 2017-09-17
  • 2021-12-27
  • 2021-11-25
  • 1970-01-01
  • 2021-10-06
  • 1970-01-01
相关资源
最近更新 更多