如何使用 Terraform 为 Azure PublicIP 指定 PTR

How to specify PTR for Azure PublicIP with Terraform

我正在 Azure 托管的 DNS 区域中设置别名记录以指向 K8s 集群的 public(出口)IP,如下所示:

data "azurerm_dns_zone" "example" {
    name                = "example.com"
}

locals {
    egress_id             = tolist(azurerm_kubernetes_cluster.k8s.network_profile.0.load_balancer_profile.0.effective_outbound_ips)[0]
    egress_name           = reverse(split("/", local.egress_id))[0]
    egress_resource_group = reverse(split("/", local.egress_id))[4]
}

resource "azurerm_dns_a_record" "k8s" {
    name                = var.dns_prefix
    zone_name           = data.azurerm_dns_zone.example.name
    resource_group_name = data.azurerm_dns_zone.example.resource_group_name
    ttl                 = 300
    target_resource_id  = local.egress_id
}

output "ptr_command" {
    value = "az network public-ip update --name ${local.egress_name} --resource-group ${local.egress_resource_group} --reverse-fqdn ${var.dns_prefix}.example.com --dns-name ${var.dns_prefix}-${local.egress_name}"
}

这行得通,并且(只是为了证明它行得通)我还可以使用输出块生成的显式 API 命令添加 PTR 记录以进行反向查找——但我可以让 terraform 执行此操作吗那作为申请的一部分? (一个问题是它必须在创建 A 记录之后发生,因为 Azure 将检查它是否指向正确的 IP)。

(k8s 出口不需要 PTR 记录,我听到你说,但是像传出 SMTP 服务器这样的东西确实需要正确的反向查找)。

我最后做的是向 DNS 记录资源添加一个 local-exec 配置器——但是一个使用显式 CLI 命令修改 public IP 的配置器。这不是一个好的解决方案,因为它不是您要看的地方,但至少顺序是正确的。此外,我认为只有在您 az login 授予 Terraform 访问您的 Azure 帐户的权限时,我的操作方式才有效,但我确信您可以配置 az 以在其他情况下使用与 Terraform 相同的凭据.

这是一个带有显式 azurerm_public_ip 资源的工作示例,说明了另一个第 22 条军规:在下一次应用时,Terraform 将看到 reverse_fqdn 属性并尝试将其删除,除非您告诉它没关系。 (在 OP 中,public IP 是由 azurerm_kubernetes_cluster 资源创建的,Terraform 不存储其完整状态)。

data "azurerm_dns_zone" "example" {
        name                = "example.com"
}

resource "random_id" "domain_label" {
        byte_length = 31 # 62 hex digits.
}

resource "azurerm_public_ip" "example" {
        lifecycle {
                # reverse_fqdn can only be set after a DNS record has
                # been created, so we do it in a provisioner there.
                # Do not try to change it back, please.
                ignore_changes = [reverse_fqdn]
        }

        name = "example"
        location = azurerm_resource_group.example.location
        resource_group_name = azurerm_resource_group.example.name
        allocation_method = "Static"
        domain_name_label = "x${random_id.domain_label.hex}"
}

resource "azurerm_dns_a_record" "example" {
        name                = "example"
        zone_name           = data.azurerm_dns_zone.example.name
        resource_group_name = data.azurerm_dns_zone.example.resource_group_name
        ttl                 = 300
        target_resource_id  = azurerm_public_ip.example.id

        provisioner "local-exec" {
                command = "az network public-ip update --name ${azurerm_public_ip.example.name} --resource-group ${azurerm_resource_group.example.name} --reverse-fqdn example.example.com"
        }
}

我仍然有一个问题,如果 Terraform 替换使用与 public IP 关联的网络接口的 VM,A 记录上的 target_resource_id 属性似乎消失了。但另一个应用解决了这个问题。