Using Terraform with Private Link enabled services

Terraform allows you to quickly provision cloud resources using a declarative language. If you are using Private Link to enable secure access from IaaS to PaaS resources, then you will need to have Terraform manage both a Private Endpoint to your PaaS resource and a Private DNS Zone. With the 2.0 version of the Terraform Azure backend, it is possible to create a Private Endpoint that also creates a Private DNS Zone.

This is important to have the Private Endpoint create the Private DNS Zone, because PaaS resources that are in multiple regions will have multiple DNS entries, usually one for each region the PaaS is in. Unfortunately, the Terraform Private Endpoint will not expose the private IP Addresses associated with the DNS entry in each region, so the approach below is the safest way to ensure your Private DNS Zone will be created with all the required DNS entries.

You can find the full example on my GitHub repo.

variable "tags" {
  type = map
}

variable "resource_group_name" {
    type = string
}

variable "location" {
    type = string
}

variable "vnet_id" {
    type = string
}

variable "subnet_id" {
    type = string
}

variable "ple_source_id" {
    type = string
}

variable "ple_connection_name" {
    type = string
}

variable "ple_subresource_names" {
    type = list
}

variable dns_name {
    type = string
}

# Create a Private DNS Zone for the PLE
resource "azurerm_private_dns_zone" "ple_dns_zone" {
  name                = var.dns_name
  resource_group_name = var.resource_group_name
  tags                = var.tags
}

# Link DNS Zone to the configured VNET
resource "azurerm_private_dns_zone_virtual_network_link" "dns_zone_vnet_link" {
  name                  = "vnet_link"
  resource_group_name   = var.resource_group_name
  private_dns_zone_name = azurerm_private_dns_zone.ple_dns_zone.name
  virtual_network_id    = var.vnet_id
  registration_enabled  = "false"
  tags                  = var.tags
}

# Create a PLE to the in the configured VNET and link the Private DNS Zone
resource "azurerm_private_endpoint" "ple" {
  name                 = var.ple_connection_name
  resource_group_name  = var.resource_group_name
  location             = var.location
  subnet_id            = var.subnet_id

  private_dns_zone_group {
    name                 = "private-dns-zone-group"
    private_dns_zone_ids = [azurerm_private_dns_zone.ple_dns_zone.id]
  }

  private_service_connection {
    name                           = var.ple_connection_name
    is_manual_connection           = false
    private_connection_resource_id = var.ple_source_id
    subresource_names              = var.ple_subresource_names
  }
}

# Output the resource id of the private endpoint
output "ple_id" {
  value = azurerm_private_endpoint.ple.id
}

# Output the resource id of the private dns zone
output "private_dns_id" {
  value = azurerm_private_dns_zone.ple_dns_zone.id
}
Previous
Previous

Using Managed Identities in a Java Azure Function

Next
Next

Fix for Python Requests lineage with Azure Application Insights