在地形中识别正确的变量类型

Identifying correct variable type in terraform

我正在使用下面的 gcp terraform module 创建一个 gcp firewall 规则,使用 terraform

https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_firewall

我需要一些帮助来为防火墙规则中的 allow 参数定义正确的 data type

参数值的例子可以如下

    fw_dst_tags                 = "http,https"   
    fw_allow   =  [{
                       protocol = "tcp"
                       ports    = ["80"]
                   }]

为此,我创建了一个变量类型 pf list(object),如下所示

    variable "target_tags" {
         type = list
        }

    variable "allow" {
         type = list(object({
         protocol = string,
         ports    = list(string,)
       }))
      }

但失败并出现以下错误

Error: Unsupported argument
│
│  on ../../modules/fw/fw.tf line 12, in resource "google_compute_firewall" "main":
│   12:     allow  = var.allow
│
│ An argument named "allow" is not expected here. Did you mean to define a block of type "allow"?

有助于为以下类型的值识别正确的变量

     fw_allow   =  [{
                       protocol = "tcp"
                       ports    = ["80"]
                   }]

The documentation for google_compute_firewall 对此不是很清楚,但它确实提到 allow 是一个 块类型 而不是一个简单的参数:

The allow block supports:

  • protocol - (Required) The IP protocol to which this rule applies. The protocol type is required when creating a firewall rule. This value can either be one of the following well known protocol strings (tcp, udp, icmp, esp, ah, sctp, ipip, all), or the IP protocol number.
  • ports - (Optional) An optional list of ports to which this rule applies. This field is only applicable for UDP or TCP protocol. Each entry must be either an integer or a range. If not specified, this rule applies to connections through any port. Example inputs include: ["22"], ["80","443"], and ["12345-12349"].

即使提供程序文档对此不够清楚,如果给定的是单数名称而不是复数名称,您通常也可以假设特定名称是块类型,但预计会有多个该类型的对象。在这种情况下,每个对象都表示为该类型的单独块。然而,这种启发式在这种情况下并没有真正帮助,因为 allow 是一个动词而不是名词,因此它作为参数名称和块类型名称同样有效。

您可以在 Terraform 文档部分 Arguments and Blocks. For your purposes here though you're looking specifically for the syntax to dynamically declare zero or more allow blocks based on the number of elements in your var.allow value. For this you'll need dynamic blocks 中阅读有关块的更多信息,这些块是用于将多个块动态声明为一种宏或模板的语法结构。

  dynamic "allow" {
    for_each = var.allow
    content {
      protocol = allow.value.protocol
      ports    = allow.value.ports
    }
  }

上面说应该为var.allow的每个元素生成一个allow块,并且每个块内应该有protocolports参数使用 var.allow 的元素中的相应属性进行填充。然后,Terraform 将在将配置传递给 validation/planning:

的提供者之前用真正的 allow 块替换它
  allow {
    protocol = "tcp"
    ports    = ["80"]
  }