Deploy Azure SQL with Private Endpoint and Test Connectivity from AKS

Published: (March 8, 2026 at 03:14 AM EDT)
6 min read
Source: Dev.to

Source: Dev.to

This tutorial demonstrates how to:

  • Create networking for AKS
  • Deploy an AKS cluster using Azure CNI Overlay
  • Deploy Azure SQL Database
  • Secure it using a Private Endpoint
  • Fix DNS resolution using a Private DNS Zone
  • Verify connectivity from Kubernetes using debugging pods

Goal: Allow AKS pods to securely connect to Azure SQL using private networking only.

Diagram

1. Define Environment Variables

LOCATION=southeastasia

RG_NETWORK=rg-aks-network
RG_OVERLAY=rg-aks-overlay
RG_UNDERLAY=rg-aks-underlay

VNET_NAME=vnet-aks-lab

SUBNET_OVERLAY=subnet-overlay
SUBNET_UNDERLAY=subnet-underlay

AKS_OVERLAY=aks-overlay
AKS_UNDERLAY=aks-underlay

2. Create Resource Groups

az group create --name $RG_NETWORK   --location $LOCATION
az group create --name $RG_OVERLAY   --location $LOCATION
az group create --name $RG_UNDERLAY  --location $LOCATION

3. Create Virtual Network

az network vnet create \
  --resource-group $RG_NETWORK \
  --name $VNET_NAME \
  --address-prefix 10.0.0.0/16

4. Create Subnets

Overlay subnet (AKS nodes)

az network vnet subnet create \
  --resource-group $RG_NETWORK \
  --vnet-name $VNET_NAME \
  --name $SUBNET_OVERLAY \
  --address-prefix 10.0.1.0/24

Underlay subnet

az network vnet subnet create \
  --resource-group $RG_NETWORK \
  --vnet-name $VNET_NAME \
  --name $SUBNET_UNDERLAY \
  --address-prefix 10.0.2.0/24

Retrieve subnet IDs

OVERLAY_SUBNET_ID=$(az network vnet subnet show \
  --resource-group $RG_NETWORK \
  --vnet-name $VNET_NAME \
  --name $SUBNET_OVERLAY \
  --query id -o tsv)

UNDERLAY_SUBNET_ID=$(az network vnet subnet show \
  --resource-group $RG_NETWORK \
  --vnet-name $VNET_NAME \
  --name $SUBNET_UNDERLAY \
  --query id -o tsv)

echo $OVERLAY_SUBNET_ID
echo $UNDERLAY_SUBNET_ID

5. Deploy AKS Cluster (Azure CNI Overlay)

az aks create \
  --resource-group $RG_OVERLAY \
  --name $AKS_OVERLAY \
  --location $LOCATION \
  --node-count 2 \
  --network-plugin azure \
  --network-plugin-mode overlay \
  --pod-cidr 192.168.0.0/16 \
  --service-cidr 172.16.0.0/16 \
  --dns-service-ip 172.16.0.10 \
  --vnet-subnet-id $OVERLAY_SUBNET_ID \
  --generate-ssh-keys

6. Connect kubectl to the Cluster

az aks get-credentials \
  --resource-group $RG_OVERLAY \
  --name $AKS_OVERLAY

Verify cluster status:

kubectl get nodes -o wide
kubectl get pods -o wide

7. Create Subnets for Services

Service subnet

az network vnet subnet create \
  --resource-group $RG_NETWORK \
  --vnet-name $VNET_NAME \
  --name subnet-service \
  --address-prefix 10.0.3.0/24

Private Endpoint subnet

az network vnet subnet create \
  --resource-group $RG_NETWORK \
  --vnet-name $VNET_NAME \
  --name subnet-private-endpoint \
  --address-prefix 10.0.4.0/24

8. Create Azure SQL Server

Generate a unique server name:

SQL_SERVER=aks-lab-sql-$RANDOM

Create the server:

az sql server create \
  --name $SQL_SERVER \
  --resource-group $RG_NETWORK \
  --location $LOCATION \
  --admin-user sqladmin \
  --admin-password 'StrongPass123!'

Ensure the provider is registered:

az provider register --namespace Microsoft.Sql
az provider show --namespace Microsoft.Sql --query "registrationState"

9. Create SQL Database

az sql db create \
  --resource-group $RG_NETWORK \
  --server $SQL_SERVER \
  --name demo-db \
  --service-objective Basic

Retrieve the SQL server resource ID:

SQL_ID=$(az sql server show \
  --name $SQL_SERVER \
  --resource-group $RG_NETWORK \
  --query id -o tsv)

echo $SQL_ID

10. Create Private Endpoint for Azure SQL

az network private-endpoint create \
  --name sql-private-endpoint \
  --resource-group $RG_NETWORK \
  --vnet-name $VNET_NAME \
  --subnet subnet-private-endpoint \
  --private-connection-resource-id $SQL_ID \
  --group-id sqlServer \
  --connection-name sqlConnection

11. Verify Private Endpoint IP

NIC_ID=$(az network private-endpoint show \
  --name sql-private-endpoint \
  --resource-group $RG_NETWORK \
  --query "networkInterfaces[0].id" \
  -o tsv)

echo $NIC_ID

Retrieve the private IP address:

az network nic show \
  --ids $NIC_ID \
  --query "ipConfigurations[0].privateIpAddress" \
  -o tsv
az network private-dns zone create \
  --resource-group $RG_NETWORK \
  --name "privatelink.database.windows.net"

Link the DNS zone to the VNet:

az network private-dns link vnet create \
  --resource-group $RG_NETWORK \
  --zone-name "privatelink.database.windows.net" \
  --name sql-dns-link \
  --virtual-network $VNET_NAME \
  --registration-enabled false

Create an A record that points to the private endpoint IP:

PRIVATE_IP=$(az network private-endpoint show \
  --name sql-private-endpoint \
  --resource-group $RG_NETWORK \
  --query "customDnsConfigs[0].ipAddresses[0]" \
  -o tsv)

az network private-dns record-set a add-record \
  --resource-group $RG_NETWORK \
  --zone-name "privatelink.database.windows.net" \
  --record-set-name $SQL_SERVER \
  --ipv4-address $PRIVATE_IP

13. Test Connectivity from AKS

Deploy a debugging pod:

apiVersion: v1
kind: Pod
metadata:
  name: sql-test
spec:
  containers:
  - name: curl
    image: mcr.microsoft.com/azure-cli
    command: ["sleep"]
    args: ["infinity"]

Apply the manifest:

kubectl apply -f sql-test.yaml

Enter the pod:

kubectl exec -it sql-test -- /bin/bash

Inside the pod, test the connection:

# Install sqlcmd (optional)
apt-get update && apt-get install -y mssql-tools unixodbc-dev

# Connect using the private DNS name
/opt/mssql-tools/bin/sqlcmd -S $SQL_SERVER.privatelink.database.windows.net,1433 \
  -U sqladmin -P 'StrongPass123!' -Q "SELECT TOP (1) name FROM sys.databases;"

If the query returns a result, the private networking is working correctly.

14. Clean‑up (Optional)

az group delete --name $RG_NETWORK   --yes --no-wait
az group delete --name $RG_OVERLAY   --yes --no-wait
az group delete --name $RG_UNDERLAY  --yes --no-wait

Congratulations! You have successfully set up an AKS cluster that connects securely to an Azure SQL Database using private endpoints and Azure CNI Overlay networking.

Retrieve Private IP

az network nic show \
  --ids $NIC_ID \
  --query "ipConfigurations[0].privateIPAddress" \
  -o tsv

Example output

10.0.4.4

12. Test Network from AKS Pod

Launch a debugging pod using the nicolaka/netshoot image:

kubectl run net-test \
  --image=nicolaka/netshoot \
  -it --rm -- bash

Inside the pod you can test DNS and networking.

13. Test SQL Client Pod

Run a SQL client container:

kubectl run sql-client \
  --image=mcr.microsoft.com/mssql-tools \
  -it --rm -- bash

14. Create Private DNS Zone

Azure SQL private endpoints require DNS mapping.

Create the private DNS zone:

az network private-dns zone create \
  --resource-group $RG_NETWORK \
  --name privatelink.database.windows.net

Link the DNS zone to the virtual network:

az network private-dns link vnet create \
  --resource-group $RG_NETWORK \
  --zone-name privatelink.database.windows.net \
  --name sql-dns-link \
  --virtual-network $VNET_NAME \
  --registration-enabled false

Attach the private endpoint to the DNS zone:

az network private-endpoint dns-zone-group create \
  --resource-group $RG_NETWORK \
  --endpoint-name sql-private-endpoint \
  --name sql-zone-group \
  --private-dns-zone privatelink.database.windows.net \
  --zone-name sql

15. Verify DNS Resolution from AKS

Run another debug pod:

kubectl run net-test \
  --image=nicolaka/netshoot \
  -it --rm -- bash

Test DNS resolution:

nslookup .database.windows.net

Expected result

10.0.4.4

16. Connect to Azure SQL

Run the SQL client pod:

kubectl run sql-client \
  --image=mcr.microsoft.com/mssql-tools \
  -it --rm -- bash

Connect using sqlcmd:

sqlcmd \
  -S aks-lab-sql-31445.database.windows.net \
  -U sqladmin \
  -P 'StrongPass123!' \
  -d demo-db

If successful you will see:

1>

You are now connected to the SQL server.

Example query

SELECT @@VERSION;
GO

Final Architecture

AKS Pod

   │ DNS Query

Private DNS Zone
(privatelink.database.windows.net)


Private Endpoint (10.0.4.4)


Azure SQL Database

✅ You now have Azure SQL accessible privately from AKS pods.

0 views
Back to Blog

Related posts

Read more »