DEV Community

iapilgrim
iapilgrim

Posted on

Deploy Azure SQL with Private Endpoint and Test Connectivity from AKS

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 Private DNS Zone
  • Verify connectivity from Kubernetes using debugging pods

The goal is to allow AKS pods to securely connect to Azure SQL using private networking only.

Diagram

1. Define Environment Variables

First define reusable 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
Enter fullscreen mode Exit fullscreen mode

2. Create Resource Groups

Create resource groups to organize infrastructure.

az group create --name $RG_NETWORK --location $LOCATION
az group create --name $RG_OVERLAY --location $LOCATION
az group create --name $RG_UNDERLAY --location $LOCATION
Enter fullscreen mode Exit fullscreen mode

3. Create Virtual Network

Create a VNet that will host:

  • AKS nodes
  • Private endpoints
  • Services
az network vnet create \
  --resource-group $RG_NETWORK \
  --name $VNET_NAME \
  --address-prefix 10.0.0.0/16
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

5. Deploy AKS Cluster (Azure CNI Overlay)

Create the AKS cluster.

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
Enter fullscreen mode Exit fullscreen mode

6. Connect kubectl to the Cluster

Retrieve credentials.

az aks get-credentials \
  --resource-group $RG_OVERLAY \
  --name $AKS_OVERLAY
Enter fullscreen mode Exit fullscreen mode

Verify cluster status.

kubectl get nodes -o wide
kubectl get pods -o wide
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

8. Create Azure SQL Server

Generate a unique name.

SQL_SERVER=aks-lab-sql-$RANDOM
Enter fullscreen mode Exit fullscreen mode

Create SQL server.

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

Ensure provider is registered.

az provider register --namespace Microsoft.Sql
az provider show --namespace Microsoft.Sql --query "registrationState"
Enter fullscreen mode Exit fullscreen mode

9. Create SQL Database

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

Retrieve the SQL resource ID.

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

echo $SQL_ID
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

11. Verify Private Endpoint IP

Get network interface ID.

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

echo $NIC_ID
Enter fullscreen mode Exit fullscreen mode

Retrieve private IP.

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

Example output:

10.0.4.4
Enter fullscreen mode Exit fullscreen mode

12. Test Network from AKS Pod

Launch a debugging pod.

Image:
nicolaka/netshoot

kubectl run net-test \
  --image=nicolaka/netshoot \
  -it --rm -- bash
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

15. Verify DNS Resolution from AKS

Run another debug pod.

kubectl run net-test \
  --image=nicolaka/netshoot \
  -it --rm -- bash
Enter fullscreen mode Exit fullscreen mode

Test DNS:

nslookup <your-sql-server>.database.windows.net
Enter fullscreen mode Exit fullscreen mode

Expected result:

10.0.4.4
Enter fullscreen mode Exit fullscreen mode

16. Connect to Azure SQL

Run SQL client.

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

Connect using sqlcmd.

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

If successful you will see:

1>
Enter fullscreen mode Exit fullscreen mode

This means you are connected to the SQL server.

Example query:

SELECT @@VERSION;
GO
Enter fullscreen mode Exit fullscreen mode

Final Architecture

AKS Pod
   │
   │ DNS Query
   ▼
Private DNS Zone
(privatelink.database.windows.net)
   │
   ▼
Private Endpoint (10.0.4.4)
   │
   ▼
Azure SQL Database
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)