Summary: This is a terraform module that I use to deploy a private endpoint for resources in Azure.
Date: 8 February 2025
Read the post to learn more about private endpoints and:
Private endpoints are a way to connect to a resource in Azure privately. This means that the resource is not exposed to the public internet. Instead, the resource is connected to a virtual network and can only be accessed from within that network. To accomplish this, a private endpoint is assigned a network interface card (NIC) that is connected to the virtual network. The network card gets assigned an IP address and a DNS name that can be used to connect to the resource. The private endpoint is connected to the resource.
Note the following tips should you start working with private endpoints:
The module for the Private Endpoint is defined over three files:
Notice the following:
resource "azurerm_private_endpoint" "private_endpoint" { name = var.name location = var.location resource_group_name = var.resource_group_name subnet_id = var.subnet_id tags = var.tags custom_network_interface_name = "nic-${var.name}" private_service_connection { name = "${var.name}-serviceconnection" private_connection_resource_id = var.private_connection_resource_id is_manual_connection = var.is_manual_connection subresource_names = try([var.subresource_name], null) request_message = try(var.request_message, null) } private_dns_zone_group { name = var.private_dns_zone_group_name private_dns_zone_ids = var.private_dns_zone_group_ids } dynamic "ip_configuration" { for_each = { for i, ip_config in var.ip_configurations : ip_config.private_ip_address => { index = i, member_name = ip_config.member_name } } content { name = "${var.name}-ipconfig-${ip_configuration.value.index}" private_ip_address = ip_configuration.key subresource_name = var.subresource_name member_name = ip_configuration.value.member_name } } lifecycle { ignore_changes = [ ] } }
output "id" { description = "Specifies the resource id of the private endpoint." value = azurerm_private_endpoint.private_endpoint.id } output "nic_name" { description = "Specifies the name of the private endpoint nic." value = azurerm_private_endpoint.private_endpoint.custom_network_interface_name } output "private_dns_zone_group" { description = "Specifies the private dns zone group of the private endpoint." value = azurerm_private_endpoint.private_endpoint.private_dns_zone_group } output "private_dns_zone_configs" { description = "Specifies the private dns zone(s) configuration" value = azurerm_private_endpoint.private_endpoint.private_dns_zone_configs }
Note that most of the descriptions are copied from the terraform registry.
variable "name" { description = "(Required) Specifies the name of the private endpoint. Changing this forces a new resource to be created." type = string } variable "resource_group_name" { description = "(Required) The name of the resource group. Changing this forces a new resource to be created." type = string } variable "private_connection_resource_id" { description = "(Required) Specifies the resource id of the private link service" type = string } variable "location" { description = "(Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created." type = string } variable "subnet_id" { description = "(Required) Specifies the resource id of the subnet" type = string } variable "private_dns_zone_group_name" { description = "(Required) Specifies the Name of the Private DNS Zone Group. Changing this forces a new private_dns_zone_group resource to be created." type = string } variable "private_dns_zone_group_ids" { description = "(Required) Specifies the list of Private DNS Zones to include within the private_dns_zone_group." type = list(string) } variable "ip_configurations" { description = "(Optional) Specifies the static IP addresses within the private endpoint's subnet to be used. Changing this forces a new resource to be created." default = [] type = list(object({ private_ip_address = string, member_name = string })) } variable "is_manual_connection" { description = "(Optional) Specifies whether the private endpoint connection requires manual approval from the remote resource owner." type = string default = false } variable "subresource_name" { description = "(Optional) Specifies a subresource name which the Private Endpoint is able to connect to." type = string default = null } variable "request_message" { description = "(Optional) Specifies a message passed to the owner of the remote resource when the private endpoint attempts to establish the connection to the remote resource." type = string default = null } variable "tags" { description = "(Optional) Specifies the tags of the network security group" default = {} }