获取 terraform 中可能的出站 ip 地址列表

Get a list of possible outbound ip addresses in terraform

我正在尝试使用 terraform 中的 azure 函数应用程序的导出来获取可能的出站 ip 地址,我可以将这些地址添加到防火墙的白名单中

返回的参数为逗号分隔的ips字符串。

我试过在 terraform 中使用 split 函数,但它没有给出列表,它给出了一个不能用作列表的界面。我试过使用局部作用域在它周围添加方括号,但还是一样。

让我补充一下,这是 terraform 11 而不是 12。

resource "azurerm_key_vault" "keyvault" {
  name                        = "${var.project_name}-${var.environment}-kv"
  location                    = "${azurerm_resource_group.environment.location}"
  resource_group_name         = "${azurerm_resource_group.environment.name}"
  enabled_for_disk_encryption = true
  tenant_id                   = "${var.tenant_id}"
  sku_name                    = "standard"

  network_acls {
    bypass         = "AzureServices"
    default_action = "Deny"
    ip_rules       = "${split(",", azurerm_function_app.function.possible_outbound_ip_addresses)}"
  }

  tags = {
    asset-code    = "${var.storage_tags["asset_code"]}"
    module-code   = "${var.storage_tags["module_code"]}"
    environment   = "${var.environment}"
    instance-code = "${var.storage_tags["instance_code"]}"
    source        = "terraform"
  }
}

返回错误 "ip_rules must be a list"。

谢谢

如果是var.string是1.2.3.4,5.6.7.8-

split(',', var.string)[0] 应该将 1.2.3.4 作为字符串返回给您。没有例子你的问题很难。

我认为您在这里看到的是典型的 Terraform 0.11 设计缺陷:当一个值在计划时未知时(因为它只会在应用期间决定),Terraform 0.11 无法正确跟踪类型信息它。

因为 possible_outbound_ip_addresses 在计划时是一个未知值,所以 split 与该字符串的结果也是未知的。由于 Terraform 不跟踪该结果的类型信息,因此提供者 SDK 代码拒绝该未知值,因为它不是列表。

要在 Terraform 0.11 中解决此问题,需要使用 -target 参数进行初始 运行,以便 Terraform 可以专注于首先创建函数(并因此分配其出站 IP 地址),然后一旦知道该字符串,就单独处理该字符串:

terraform apply -target=azurerm_function_app.function
terraform apply # to complete the rest of the work that -target excluded

Terraform 0.12 通过跟踪已知值和未知值的类型信息解决了这个限制,因此在 Terraform 0.12 中,split 函数会看到您给它一个未知字符串并接受它是正确输入的,并且然后它将 return 一个未知的 字符串列表 作为结果的占位符,最终将在应用阶段确定。

这是我如何获取可能的 IP 列表的示例

创建数据源,然后创建本地变量

app_services = [ "app1", "app2", "app3" ]

data "azurerm_app_service" "outbound_ips" {
  count                = length(var.app_services)
  name                 = var.app_services[count.index]
  resource_group_name  = var.server_resource_group_name
}

locals {
  apps_outbound_ips = distinct(flatten(concat(data.azurerm_app_service.outbound_ips.*.possible_outbound_ip_address_list)))
}

你也不必使用数据源,如果你正在构建资源,只需使用输出而不是数据源,在我的例子中,我在单独构建我的应用程序时使用数据源。

对我来说完美无缺,并以 local.apps_outbound_ips

的形式生成字符串列表(字符串是应用程序服务/功能应用程序集的每个唯一出站 IP)

尽情享受吧:)