Azure Networking Terraform Guide

Azure Private Endpoint Terraform

This page explains how to deploy Azure Private Endpoint with Terraform using Azure-specific private-access patterns, including the private endpoint resource, private service connection, subnet placement, DNS zone group linkage, and real-world Azure PaaS connectivity design. Microsoft’s current Terraform quickstart for private endpoints shows this pattern with a private DNS zone and SQL Database example. :contentReference[oaicite:1]{index=1}

Instead of treating this as only a code snippet page, this guide explains how azurerm_private_endpoint maps to real Azure private connectivity architecture, what engineers usually get wrong around DNS and subresources, and how to structure reusable infrastructure as code for Private Link consumption. :contentReference[oaicite:2]{index=2}

Main Terraform resource

The core resource is azurerm_private_endpoint, which is usually deployed together with private DNS zone resources or linked to preexisting private DNS zones. :contentReference[oaicite:3]{index=3}

Best fit

Ideal when you want repeatable private access from Azure VNets to supported Azure PaaS, partner, or customer services over Azure Private Link. :contentReference[oaicite:4]{index=4}

Common challenge

Most mistakes come from wrong subresource names, incomplete DNS design, or assuming the endpoint alone is enough without private DNS integration. :contentReference[oaicite:5]{index=5}

Primary resource azurerm_private_endpoint Main Terraform resource for consumer-side private service access.
Best for Private Azure PaaS access Version-controlled private connectivity for supported services.
Key building blocks PE, subnet, DNS zone group Private DNS is one of the most important deployment parts.
Related services Private DNS, VNets, Private Link Private Endpoint works as part of a broader Azure private access design.

What is Azure Private Endpoint Terraform?

Azure Private Endpoint Terraform means defining Azure’s private-connectivity consumer resource as infrastructure as code instead of building it manually in the portal. The core Terraform resource is azurerm_private_endpoint, and Microsoft’s current quickstart pairs it with private DNS resources because name resolution is a core part of making the endpoint usable. :contentReference[oaicite:7]{index=7}

In simple terms, Terraform lets you define how a service becomes privately reachable from your VNet, while keeping the endpoint, DNS, and naming reusable, reviewable, and consistent across environments.
Infrastructure as Code Private IP connectivity Private DNS integration Azure Private Link Repeatable environments Production-ready patterns

Why Terraform is used for Azure Private Endpoint

Private Endpoint may look small in the portal, but it affects subnet design, DNS, approval workflows, and service consumption architecture. Terraform helps engineering teams standardize private access patterns, document subresource selection, and keep DNS linkage consistent across development, test, and production deployments. :contentReference[oaicite:8]{index=8}

Consistency

The same private connectivity pattern can be deployed across environments without rebuilding DNS and endpoint decisions by hand.

Reviewability

Engineers can review subresource names, endpoint placement, and DNS linkage in pull requests before deployment.

Safer architecture

Terraform reduces drift and makes it easier to keep private service access aligned with network and security design.

Azure Private Endpoint Terraform explained with the 5 Ws + How

This keeps the page useful for beginners, working engineers, and interview learners who want practical Azure private connectivity understanding.

What

Terraform-based deployment of Azure Private Endpoint using the AzureRM provider.

Why

To manage private access to Azure services in a repeatable and reviewable way.

When

Use it when workloads must reach supported services over private IP instead of public endpoints.

Where

Inside Azure resource groups and subnets, using a private endpoint NIC and usually linked private DNS configuration. :contentReference[oaicite:9]{index=9}

Who

DevOps engineers, platform teams, cloud engineers, security teams, and architects designing private service access.

How

Terraform declares the private endpoint, private service connection, and often DNS zone group resources, and Azure builds the private access path accordingly. :contentReference[oaicite:10]{index=10}

Prerequisites before writing the Terraform

Private Endpoint design starts with service architecture. A clean Terraform deployment needs more than one resource: you need the target supported service, the right subnet, the correct subresource name, and a DNS strategy that works for the consumers of that service. :contentReference[oaicite:11]{index=11}

Common prerequisites

  • Azure subscription and Terraform AzureRM provider
  • Resource group
  • Virtual network and subnet for the private endpoint
  • Supported target service
  • Correct target subresource name
  • Private DNS zone plan

Production planning items

  • Whether endpoint approval is manual or automatic
  • Whether DNS is shared across hub-and-spoke or hybrid environments
  • Whether one or multiple subresources are required
  • Whether private endpoint network policies on the subnet need review
  • Whether the service public endpoint posture is changing too
  • How on-premises or peered VNet clients will resolve the private name
The biggest prerequisite is DNS intent. Many Private Endpoint deployments fail not because the endpoint resource is wrong, but because name resolution still points to the public path. :contentReference[oaicite:12]{index=12}

Terraform resource model for Azure Private Endpoint

Private Endpoint Terraform is centered on one main resource, but the working deployment usually includes private DNS zone resources and a DNS zone group. The provider also documents subnet considerations, including private endpoint network policy settings at the subnet resource level. :contentReference[oaicite:13]{index=13}

Terraform resource or block Azure concept Purpose
azurerm_private_endpoint Private endpoint Creates the consumer-side private IP connection object
private_service_connection Private Link connection settings Defines the target resource and subresource connection
private_dns_zone_group DNS linkage Associates the endpoint with one or more private DNS zones
azurerm_private_dns_zone Private DNS zone Provides private name resolution for the service
azurerm_private_dns_zone_virtual_network_link VNet DNS linkage Lets the VNet use the private DNS zone
azurerm_subnet Endpoint subnet Hosts the private endpoint NIC and related policy settings

Recommended code structure

For real projects, do not scatter private endpoint logic through random files. Private connectivity affects network, DNS, and application behavior, so even a small endpoint benefits from clean module structure.

terraform/
├── main.tf
├── variables.tf
├── outputs.tf
├── providers.tf
├── terraform.tfvars
└── modules/
    └── private-endpoint/
        ├── main.tf
        ├── variables.tf
        └── outputs.tf

Root module

Connects shared network resources, naming, and the target service being consumed privately.

Reusable child module

Encapsulates the private endpoint, DNS zone group, and required supporting resources so multiple environments stay consistent.

Variables and outputs

Keep names, target IDs, subresource names, DNS zones, and subnet identifiers separated from the main logic.

Terraform example for Azure Private Endpoint

This example follows the current Microsoft quickstart shape: it creates a VNet, subnet, private DNS zone, DNS VNet link, and a private endpoint with a DNS zone group. The sample below uses Azure SQL Database because that is what Microsoft’s current quickstart demonstrates. :contentReference[oaicite:14]{index=14}

Terraform starter example
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 4.0.0"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg" {
  name     = "rg-private-endpoint-prod-san-1"
  location = "South Africa North"
}

resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-private-endpoint-prod-san-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  address_space       = ["10.60.0.0/16"]
}

resource "azurerm_subnet" "pe_subnet" {
  name                 = "snet-private-endpoint-prod-san-1"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.60.10.0/24"]

  private_endpoint_network_policies = "Disabled"
}

resource "azurerm_mssql_server" "sql" {
  name                         = "sqlpeprod001"
  resource_group_name          = azurerm_resource_group.rg.name
  location                     = azurerm_resource_group.rg.location
  version                      = "12.0"
  administrator_login          = "sqladminuser"
  administrator_login_password = "P@ssword1234!"
}

resource "azurerm_mssql_database" "db" {
  name      = "appdb"
  server_id = azurerm_mssql_server.sql.id
  sku_name  = "Basic"
}

resource "azurerm_private_dns_zone" "sql_dns" {
  name                = "privatelink.database.windows.net"
  resource_group_name = azurerm_resource_group.rg.name
}

resource "azurerm_private_dns_zone_virtual_network_link" "sql_dns_link" {
  name                  = "sql-dns-link-prod"
  resource_group_name   = azurerm_resource_group.rg.name
  private_dns_zone_name = azurerm_private_dns_zone.sql_dns.name
  virtual_network_id    = azurerm_virtual_network.vnet.id
}

resource "azurerm_private_endpoint" "sql_pe" {
  name                = "pe-sql-prod-san-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  subnet_id           = azurerm_subnet.pe_subnet.id

  private_service_connection {
    name                           = "psc-sql-prod-san-1"
    private_connection_resource_id = azurerm_mssql_server.sql.id
    subresource_names              = ["sqlServer"]
    is_manual_connection           = false
  }

  private_dns_zone_group {
    name                 = "pdzg-sql-prod"
    private_dns_zone_ids = [azurerm_private_dns_zone.sql_dns.id]
  }

  tags = {
    environment = "prod"
    service     = "sql-private-endpoint"
    owner       = "platform-team"
  }
}

output "private_endpoint_id" {
  value = azurerm_private_endpoint.sql_pe.id
}

output "private_endpoint_nic" {
  value = azurerm_private_endpoint.sql_pe.network_interface[0].id
}

Why this example matters

Microsoft’s quickstart explicitly combines the endpoint with private DNS because a private endpoint without working DNS often looks “deployed” but still does not behave privately for clients. :contentReference[oaicite:15]{index=15}

How the Terraform code maps to the real Azure service

Many engineers can paste Terraform, but not everyone understands how each resource changes Azure behavior. This section makes the mapping clear.

Subnet placement

azurerm_subnet defines where Azure will place the private endpoint NIC inside your VNet.

Policy behavior

The subnet resource documents private_endpoint_network_policies, which is an important subnet-level setting to review when hosting private endpoints. :contentReference[oaicite:16]{index=16}

Target resource mapping

private_connection_resource_id points to the supported service, while subresource_names picks the exact endpoint target such as sqlServer.

Approval model

is_manual_connection controls whether the connection is expected to follow a manual approval workflow.

DNS linkage

private_dns_zone_group associates the endpoint to the private DNS zone so supported names resolve to the private IP path.

Consumer-side NIC

The provider documents Private Endpoint as a managed resource that exposes a NIC, which is why the output can reference the created network interface. :contentReference[oaicite:17]{index=17}

DNS zone group model

This is one of the most important Private Endpoint topics. Microsoft’s current docs say it is important to correctly configure DNS settings so the private endpoint IP resolves for the fully qualified service name, and they provide separate DNS integration guidance because this is such a common source of deployment issues. :contentReference[oaicite:18]{index=18}

Client Workload
      |
      v
+-----------------------------------+
| Azure VNet                        |
| Private DNS Zone linked to VNet   |
+-----------------------------------+
                 |
                 v
+-----------------------------------+
| Azure Private Endpoint            |
| Private IP NIC in subnet          |
+-----------------------------------+
                 |
                 v
+-----------------------------------+
| Azure Private Link-enabled        |
| target service                    |
+-----------------------------------+

Why the DNS zone group matters

It ties the endpoint to the private DNS zone in a way that helps the VNet resolve the service name to the private endpoint path.

Why engineers get this wrong

Some teams create the endpoint successfully but skip the private DNS linkage, so clients continue resolving the public endpoint instead.

If you remember only one Private Endpoint Terraform lesson, remember this: a deployed private endpoint without working DNS is often not a usable private endpoint deployment. :contentReference[oaicite:19]{index=19}

Subresources matter more than people expect

The current provider and Microsoft service documentation make it clear that the private endpoint connects to a specific subresource of the target service. Storage is one of the best examples because blob, file, queue, and table can each matter separately depending on what the workload uses. :contentReference[oaicite:20]{index=20}

Why subresource names matter

The private endpoint can exist, but if the subresource is wrong, the application may still fail because it is reaching the wrong service component.

Why this becomes a production issue

Teams often test only one path, but real applications may depend on multiple service components that each need their own private endpoint and DNS mapping.

Real-world Azure Private Endpoint Terraform use cases

Practical examples make this page useful and avoid generic Terraform content by grounding private endpoints in real Azure service-consumption scenarios.

Private SQL access

A private application subnet uses Terraform to create a private endpoint for Azure SQL Database so application traffic stays on private network paths. Microsoft’s quickstart uses SQL Database as the canonical example. :contentReference[oaicite:21]{index=21}

Storage over private IP

Terraform creates one or more private endpoints for Storage subresources so internal workloads can use blob or file privately without public exposure patterns.

Hub-and-spoke shared DNS

A platform team standardizes private endpoint and private DNS zone modules across shared Azure environments so app teams consume PaaS privately and consistently. :contentReference[oaicite:22]{index=22}

Terraform vs manual Azure portal deployment

Both approaches can work, but Terraform becomes more valuable as private connectivity architecture grows and must remain consistent across environments.

Approach Best for Strength Weakness
Terraform Repeatable production deployments Version control, consistency, reviewable changes Requires structure and code discipline
Azure Portal One-off testing or learning Fast for initial exploration Hard to reproduce accurately across environments
A strong engineering pattern is to understand Private Endpoint once in the portal, then move the final design into Terraform so the private service-access architecture is managed as code.

Best practices

Practical guidance is what turns a Terraform page from a snippet page into a real engineering reference.

Treat DNS as first-class architecture

Plan the private DNS zone, VNet links, and hybrid forwarding model from the start. :contentReference[oaicite:23]{index=23}

Use the exact correct subresource

Check the service documentation carefully instead of guessing the subresource name.

Tag endpoints clearly

Ownership, environment, and service purpose should always be obvious because private endpoints affect real connectivity behavior.

Keep subnet placement deliberate

Private endpoints should live in subnets that fit your network governance and naming standards.

Design for approval workflow

Know whether the target service expects manual approval and who owns that approval step.

Review public endpoint posture too

Private connectivity design is strongest when the service’s public access model is reviewed alongside it.

Common mistakes

Platform-specific mistakes are what make this page practical instead of generic. These are the things teams commonly get wrong with Private Endpoint Terraform.

Skipping DNS zone linkage

Engineers create the private endpoint but never link the correct private DNS zone, so applications keep resolving the public endpoint. :contentReference[oaicite:24]{index=24}

Using the wrong subresource name

The endpoint exists, but the application still fails because the service component being consumed is not the one the endpoint targets.

Assuming one endpoint covers everything

Some services need multiple private endpoints for different subresources or different architecture patterns.

Ignoring subnet policy settings

Teams sometimes forget that the hosting subnet has private endpoint policy behavior that may need explicit review. :contentReference[oaicite:25]{index=25}

No hybrid DNS plan

Peered VNet and on-premises consumers do not magically resolve private endpoint names without intentional DNS integration. :contentReference[oaicite:26]{index=26}

No ownership of approval state

A pending private endpoint connection can sit in place while teams assume the problem is networking instead of approval workflow.

Frequently asked questions

FAQ sections help capture real search intent and make the page more complete for working engineers and learners.

What Terraform resource creates Azure Private Endpoint?

The main Terraform resource is azurerm_private_endpoint. :contentReference[oaicite:27]{index=27}

Do I need private DNS with Azure Private Endpoint?

In most real deployments, yes. Microsoft’s current docs emphasize correct DNS integration so the service name resolves to the private endpoint IP. :contentReference[oaicite:28]{index=28}

What Terraform block links the endpoint to private DNS?

The private_dns_zone_group block inside azurerm_private_endpoint is commonly used for that linkage. :contentReference[oaicite:29]{index=29}

Does Microsoft’s current Terraform quickstart for private endpoint use Azure SQL?

Yes. The current quickstart uses a private endpoint connected to Azure SQL Database, along with a private DNS zone. :contentReference[oaicite:30]{index=30}

Can private endpoints work with peered VNets or on-premises networks?

Yes, but Microsoft’s current guidance makes clear that DNS integration must be designed correctly for those scenarios. :contentReference[oaicite:31]{index=31}

Where do I review subnet policy behavior for private endpoints?

The AzureRM subnet resource documents private_endpoint_network_policies, which is the relevant subnet-level setting to review. :contentReference[oaicite:32]{index=32}