AZURE PRIVATE LINK → STACKIT · ARCHITECTURE
Azure Private Link and private networking on STACKIT
Azure Private Link gives a managed service a private address in your virtual network. STACKIT managed services do not offer that: you reach them on their own endpoint, restricted by an access list, or you scope a few of them to a Network Area, or you run the service inside your network. StackToIT classifies every private endpoint as REDESIGN; this page shows what that means and how to choose.
Two private endpoints and a DNS zone, assessed
A demo estate written for this page and assessed by StackToIT on 4 November 2026: a hub network, a storage account and a SQL server with public access off, two private endpoints and a privatelink zone. Left: the privatelink zone, its network link and the blob endpoint from the input (main.tf lines 61 to 90). Right: how assessment.json records the endpoints, the zone, the network and a subnet (id plus class, confidence and target service of each result, values as written).
resource "azurerm_private_dns_zone" "blob" {
name = "privatelink.blob.core.windows.net"
resource_group_name = azurerm_resource_group.net.name
}
resource "azurerm_private_dns_zone_virtual_network_link" "blob" {
name = "blob-hub"
resource_group_name = azurerm_resource_group.net.name
private_dns_zone_name = azurerm_private_dns_zone.blob.name
virtual_network_id = azurerm_virtual_network.hub.id
}
resource "azurerm_private_endpoint" "blob" {
name = "pe-docs-blob"
location = azurerm_resource_group.net.location
resource_group_name = azurerm_resource_group.net.name
subnet_id = azurerm_subnet.endpoints.id
private_service_connection {
name = "psc-docs-blob"
private_connection_resource_id = azurerm_storage_account.docs.id
subresource_names = ["blob"]
is_manual_connection = false
}
private_dns_zone_group {
name = "blob"
private_dns_zone_ids = [azurerm_private_dns_zone.blob.id]
}
}[
{
"id": "azurerm_private_endpoint.blob",
"result": {
"class": "REDESIGN",
"confidence": "LOW",
"target": {
"service": "none — no Private Link equivalent"
}
}
},
{
"id": "azurerm_private_endpoint.sql",
"result": {
"class": "REDESIGN",
"confidence": "LOW",
"target": {
"service": "none — no Private Link equivalent"
}
}
},
{
"id": "azurerm_private_dns_zone.blob",
"result": {
"class": "RECONFIGURE",
"confidence": "LOW",
"target": {
"service": "not needed (belongs to Private Link)"
}
}
},
{
"id": "azurerm_virtual_network.hub",
"result": {
"class": "RECONFIGURE",
"confidence": "MEDIUM",
"target": {
"service": "STACKIT project networking / Network Area (SNA)"
}
}
},
{
"id": "azurerm_subnet.endpoints",
"result": {
"class": "RECONFIGURE",
"confidence": "MEDIUM",
"target": {
"service": "STACKIT network"
}
}
}
]The endpoint becomes a decision
Both endpoints are REDESIGN with LOW confidence and no target, because STACKIT managed services have no private-link endpoints. The run writes no Terraform for them, and the references they held to the storage account, the SQL server and the subnet are for a person to re-make in the redesign.
The zone goes with its endpoints
The privatelink zone only resolves private endpoints of Azure services, so the run lists it as not needed on STACKIT.
Subnets stay, the network disappears
Each subnet becomes a STACKIT network with the same prefix. The virtual network itself has no counterpart, and the run advises adding a Network Area only if networks must route to each other privately.
What the services get instead
The same run, the same input. The storage account and the SQL server are still migrated; their private reach is the open question. Verbatim resource blocks, one pane per file; the review comments above each block are left out here.
resource "azurerm_storage_account" "docs" {
name = "stplatformdocsgwc"
resource_group_name = azurerm_resource_group.net.name
location = azurerm_resource_group.net.location
account_tier = "Standard"
account_replication_type = "LRS"
public_network_access_enabled = false
}
resource "azurerm_mssql_server" "core" {
name = "sql-platform-core"
resource_group_name = azurerm_resource_group.net.name
location = azurerm_resource_group.net.location
version = "12.0"
administrator_login = "coreadmin"
administrator_login_password = var.sql_admin_password
public_network_access_enabled = false
}resource "stackit_objectstorage_bucket" "docs" {
project_id = var.project_id
name = "stplatformdocsgwc"
}resource "stackit_sqlserverflex_instance" "core" {
project_id = var.project_id
name = "sql-platform-core"
flavor_id = var.core_flavor_id
storage = {
class = var.sqlserverflex_storage_class
size = var.core_storage_size
}
backup_schedule = "0 2 * * *"
network = {
acl = var.core_allowed_cidrs
}
version = "2022"
retention_days = 30
}variable "core_allowed_cidrs" {
type = list(string)
description = "CIDRs allowed to reach azurerm_mssql_server.core. The source used VNet integration, private endpoints or no firewall rule the ACL can take; list the STACKIT network prefixes of the clients."
}The access list has no default
The variable for the allowed CIDRs states that the source used private endpoints, and asks you to list the STACKIT network prefixes of the clients.
The public switch has no counterpart
The draft notes for the SQL server that the public-network switch is not carried and that clients reach the instance through its ACL either way. It also explains the version: 12.0 on Azure is an API version, so the draft takes SQL Server 2022 from the region catalogue.
Buckets need a restriction decision
The run warns that bucket policies can restrict source IP addresses but no network-scoped condition is documented. STACKIT’s reference of bucket-policy condition keys confirms it (as of November 2026): aws:SourceIp, aws:username, s3:delimiter, s3:max-keys and s3:prefix, with no network or endpoint key. Decide how the buckets are restricted or they are reachable from the internet for anyone holding credentials.
Four ways to replace a private endpoint
| Option | How it works on STACKIT | Trade-off |
|---|---|---|
| Access list on the service endpoint | The service has its own hostname and address; the ACL admits the ranges you list, on top of predefined STACKIT ranges | Simple and available now; the service keeps a reachable address and clients must have stable source ranges |
| Network Area scope | PostgreSQL Flex and SQLServer Flex take an access scope SNA, and a KMS key takes the same attribute | Private address, but an opt-in for enabled accounts that may still change, and not offered by every service |
| Service inside your network | Run the database or broker on servers or on SKE | Full control of the address, but you operate patching, backups and failover |
| Network Area between your networks | Projects of an organization are connected at the network level, with routing that updates itself | Solves network-to-network traffic, not the reach of a managed service |
Options as the run and the cited STACKIT pages describe them. No option carries Azure's per-service endpoint approval; that workflow has no equivalent.
What each unit became in the run
| Azure resource | STACKIT target | Class |
|---|---|---|
| SQL logical server | SQLServer Flex instance | Replatform |
| Storage account | Object Storage bucket | Replatform |
| Virtual network | No resource: each subnet becomes a network | Reconfigure |
| Subnets (apps, endpoints) | STACKIT network with the same prefix | Reconfigure |
| Private DNS zone | Not needed | Reconfigure |
| Private endpoint, blob | None: no private-link equivalent | Redesign |
| Private endpoint, SQL | None: no private-link equivalent | Redesign |
Eight units, four drafted, two needing no resource and two left for the architect, as the run's console summary states.
How to decide
Is a private address mandatory?
If a rule says the service must have no reachable address, the ACL options fall short. Check the Network Area scope for that service, or run it inside your network.
Can you name the clients?
An ACL needs source ranges. Where clients sit behind changing addresses, list the network prefixes of the STACKIT networks they run in.
Who needs the name to resolve?
Azure resolves a service name to a private address through a privatelink zone. STACKIT DNS provides public authoritative DNS, and the run says private names need a DNS server of your own.
Is the traffic network to network?
That is a Network Area question, not an endpoint one. Traffic between regions currently travels only over the public internet, according to the STACKIT page.
Which public switch did you rely on?
Azure notes a private endpoint does not by itself restrict public access. Your source turned it off; on STACKIT the ACL does that job.
Questions network teams ask
Is there a STACKIT private endpoint?
No. The run states that STACKIT managed services have no private-link endpoints and classifies the Azure ones as REDESIGN with no target.
What replaces the privatelink DNS zone?
Nothing is generated. STACKIT DNS provides public authoritative DNS; names that must resolve privately need a DNS server of your own.
Does a Network Area give a database a private address?
For PostgreSQL Flex and SQLServer Flex an access scope SNA exists, as an opt-in for enabled accounts that may still change. Ask for it before you rely on it.
What changes for the clients?
They connect to a new hostname instead of a privatelink name, from a source range that is on the ACL. The run lists the networks it drafted as the places to start.
Sources
Your next move: STACKIT.
Tell us about your estate. We show you what StackToIT delivers for it: target architecture, Terraform artifacts and a structured migration plan.