【问题标题】:Identifying correct variable type in terraform在 terraform 中识别正确的变量类型
【发布时间】:2021-09-26 08:34:09
【问题描述】:

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

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"]
                   }]

【问题讨论】:

  • 什么是fw_allow?它不在链接的文档中。

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


【解决方案1】:

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

allow 块支持:

  • protocol - (必需)此规则适用的 IP 协议。创建防火墙规则时需要协议类型。该值可以是以下众所周知的协议字符串之一(tcp、udp、icmp、esp、ah、sctp、ipip、all)或 IP 协议号。
  • ports - (可选)适用此规则的端口的可选列表。该字段仅适用于 UDP 或 TCP 协议。每个条目必须是整数或范围。如果未指定,则此规则适用于通过任何端口的连接。示例输入包括:["22"]、["80","443"] 和 ["12345-12349"]。

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

您可以在 Terraform 文档部分 Arguments and Blocks 中阅读有关块的更多信息。出于您的目的,尽管您正在寻找专门用于根据 var.allow 值中的元素数量动态声明零个或多个 allow 块的语法。为此,您需要 dynamic blocks,它是用于将多个块动态声明为一种宏或模板的语法结构。

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

上面说应该为var.allow的每个元素生成一个allow块,并且在每个块内应该有protocolports参数使用来自@元素的相应属性填充987654338@。然后,在将配置传递给提供者进行验证/规划之前,Terraform 将用真正的 allow 块替换它:

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

【讨论】:

  • 非常感谢您的澄清。这是一个很好的答案。
猜你喜欢
  • 2015-10-23
  • 1970-01-01
  • 2016-08-25
  • 2020-05-18
  • 2022-01-26
  • 1970-01-01
  • 2021-09-27
  • 2020-11-05
  • 1970-01-01
相关资源
最近更新 更多