Skip to content

Azure Custom Domain Setup for n0.sorcha.dev

Guide for configuring the Peer Service (Hub Node) with custom domain


Overview

The Azure Peer Service is deployed as n0.sorcha.dev (the primary hub node). This document explains how to configure the custom domain and DNS records.


Peer Service Configuration

The Peer Service knows it's n0.sorcha.dev through these environment variables:

bicep
{
  name: 'PeerService__NodeId'
  value: 'n0.sorcha.dev'
}
{
  name: 'PeerService__PublicAddress'
  value: peerService.properties.configuration.ingress.fqdn
}
{
  name: 'PeerService__CentralNode__IsCentralNode'
  value: 'true'
}
{
  name: 'PeerService__CentralNode__ValidateHostname'
  value: 'false'  // Set to 'true' only after DNS is configured
}
{
  name: 'PeerService__CentralNode__Priority'
  value: '0'  // Primary hub node
}

Step 1: Get Azure Container App Default URL

First, get the default Azure Container Apps URL:

bash
# Get the peer service FQDN
az containerapp show \
  --name peer-service \
  --resource-group sorcha \
  --query properties.configuration.ingress.fqdn \
  --output tsv

Example output:

peer-service.nicegrass-12345678.uksouth.azurecontainerapps.io

Step 2: Add Custom Domain to Container App

Prerequisites

  • You own the domain sorcha.dev
  • You have access to DNS management for sorcha.dev

Add Custom Domain

bash
# Add custom domain (requires TXT record for verification)
az containerapp hostname add \
  --hostname n0.sorcha.dev \
  --resource-group sorcha \
  --name peer-service

This will prompt you to add a TXT record for domain verification.


Step 3: DNS Configuration

Add a CNAME record in your DNS provider:

Type:  CNAME
Name:  n0
Value: peer-service.nicegrass-12345678.uksouth.azurecontainerapps.io
TTL:   300 (or 3600)

Option B: A Record (If CNAME not supported at apex)

  1. Get the Container App Environment static IP:
bash
# Get environment static IP
az containerapp env show \
  --name sorcha-env-prod \
  --resource-group sorcha \
  --query properties.staticIp \
  --output tsv
  1. Add A record:
Type:  A
Name:  n0
Value: <static-ip-address>
TTL:   300

TXT Record for Verification

Azure requires domain verification. Add this TXT record:

bash
# Get verification code
az containerapp hostname list \
  --name peer-service \
  --resource-group sorcha \
  --query "[?name=='n0.sorcha.dev'].bindingType" \
  --output tsv

Add TXT record:

Type:  TXT
Name:  asuid.n0
Value: <verification-code-from-azure>
TTL:   300

Step 4: Bind Certificate

Azure Container Apps supports managed certificates (free):

bash
# Add managed certificate (Let's Encrypt)
az containerapp hostname bind \
  --hostname n0.sorcha.dev \
  --resource-group sorcha \
  --name peer-service \
  --environment sorcha-env-prod \
  --validation-method CNAME

This automatically provisions and renews SSL/TLS certificates.


Step 5: Verify Configuration

Test DNS Resolution

bash
# Check DNS propagation
nslookup n0.sorcha.dev

# Check with dig (Linux/Mac)
dig n0.sorcha.dev

# Check with PowerShell
Resolve-DnsName n0.sorcha.dev

Expected result: Should resolve to Azure Container Apps IP or CNAME

Test HTTPS Access

bash
# Test HTTPS endpoint
curl https://n0.sorcha.dev/health

# Test gRPC endpoint (if applicable)
grpcurl n0.sorcha.dev:443 list

Check Container App Logs

bash
az containerapp logs show \
  --name peer-service \
  --resource-group sorcha \
  --tail 50 | grep -i "NodeId\|n0.sorcha.dev\|central"

Expected log messages:

[INF] Node type detected: Hub Node
[INF] NodeId: n0.sorcha.dev
[INF] Hostname: n0.sorcha.dev
[INF] Node validated as hub node

Step 6: Enable Hostname Validation (Production)

Once DNS is working, enable hostname validation for added security:

bash
# Update Container App environment variable
az containerapp update \
  --name peer-service \
  --resource-group sorcha \
  --set-env-vars "PeerService__CentralNode__ValidateHostname=true"

# Restart to apply
az containerapp restart \
  --name peer-service \
  --resource-group sorcha

What this does:

  • Validates that the container's hostname matches the expected pattern (*.sorcha.dev)
  • Prevents accidental misconfiguration
  • Ensures the node is running in the correct environment

Complete DNS Configuration for Sorcha

For a complete production setup with all hub nodes:

HostnameTypeValuePurpose
n0.sorcha.devCNAMEpeer-service.*.uksouth.azurecontainerapps.ioPrimary hub node (Azure UK South)
n1.sorcha.devCNAMEpeer-service.*.eastus.azurecontainerapps.ioSecondary hub node (Azure East US)
n2.sorcha.devCNAMEpeer-service.*.westeurope.azurecontainerapps.ioTertiary hub node (Azure West Europe)
asuid.n0TXT<verification-code>Domain verification (Azure)
asuid.n1TXT<verification-code>Domain verification (Azure)
asuid.n2TXT<verification-code>Domain verification (Azure)

Note: Currently only n0 is deployed. n1 and n2 are reserved for future multi-region deployment.


Troubleshooting

Problem: DNS Not Resolving

Check:

  1. DNS records are correctly added
  2. TTL has expired (wait 5-10 minutes)
  3. Use a different DNS server: nslookup n0.sorcha.dev 8.8.8.8

Solution:

bash
# Force DNS cache flush (Windows)
ipconfig /flushdns

# Force DNS cache flush (Linux/Mac)
sudo systemd-resolve --flush-caches

Problem: Certificate Not Provisioning

Check:

bash
az containerapp hostname list \
  --name peer-service \
  --resource-group sorcha \
  --output table

Common issues:

  • TXT record not added or not propagated
  • CNAME/A record not pointing to correct target
  • Domain verification pending

Solution:

bash
# Remove and re-add hostname
az containerapp hostname delete \
  --hostname n0.sorcha.dev \
  --resource-group sorcha \
  --name peer-service

# Wait 5 minutes for DNS propagation

# Re-add with managed cert
az containerapp hostname bind \
  --hostname n0.sorcha.dev \
  --resource-group sorcha \
  --name peer-service \
  --environment sorcha-env-prod \
  --validation-method CNAME

Problem: "Hostname validation failed"

Symptoms: Peer Service logs show:

InvalidOperationException: IsCentralNode is true but hostname 'xyz' does not match expected pattern '*.sorcha.dev'

Solution:

bash
# Temporarily disable validation
az containerapp update \
  --name peer-service \
  --resource-group sorcha \
  --set-env-vars "PeerService__CentralNode__ValidateHostname=false"

# Verify DNS is working
curl https://n0.sorcha.dev/health

# Re-enable after DNS confirmed
az containerapp update \
  --name peer-service \
  --resource-group sorcha \
  --set-env-vars "PeerService__CentralNode__ValidateHostname=true"

Problem: Mixed HTTP/HTTPS Traffic

Check Container App ingress settings:

bash
az containerapp ingress show \
  --name peer-service \
  --resource-group sorcha

Ensure HTTPS only:

bash
az containerapp ingress update \
  --name peer-service \
  --resource-group sorcha \
  --allow-insecure false \
  --type external

Configuration Summary

Current Configuration (Development)

json
{
  "PeerService": {
    "NodeId": "n0.sorcha.dev",
    "PublicAddress": "peer-service.nicegrass-12345678.uksouth.azurecontainerapps.io",
    "Port": 5000,
    "CentralNode": {
      "IsCentralNode": true,
      "ExpectedHostnamePattern": "*.sorcha.dev",
      "ValidateHostname": false,
      "Priority": 0
    }
  }
}

Production Configuration (After DNS Setup)

json
{
  "PeerService": {
    "NodeId": "n0.sorcha.dev",
    "PublicAddress": "n0.sorcha.dev",
    "Port": 5000,
    "CentralNode": {
      "IsCentralNode": true,
      "ExpectedHostnamePattern": "*.sorcha.dev",
      "ValidateHostname": true,  // ✅ Enabled for security
      "Priority": 0
    }
  }
}

Automation Script

Save this as scripts/configure-peer-domain.ps1:

powershell
param(
    [Parameter(Mandatory=$true)]
    [string]$Hostname = "n0.sorcha.dev",

    [Parameter(Mandatory=$false)]
    [string]$ResourceGroup = "sorcha",

    [Parameter(Mandatory=$false)]
    [string]$ServiceName = "peer-service"
)

Write-Host "Configuring custom domain for Peer Service..." -ForegroundColor Cyan

# Get current FQDN
$currentFqdn = az containerapp show `
    --name $ServiceName `
    --resource-group $ResourceGroup `
    --query properties.configuration.ingress.fqdn `
    --output tsv

Write-Host "Current FQDN: $currentFqdn" -ForegroundColor Yellow

# Add custom hostname
Write-Host "Adding custom hostname: $Hostname" -ForegroundColor Cyan
az containerapp hostname add `
    --hostname $Hostname `
    --resource-group $ResourceGroup `
    --name $ServiceName

Write-Host ""
Write-Host "Next Steps:" -ForegroundColor Green
Write-Host "1. Add DNS CNAME record:" -ForegroundColor White
Write-Host "   Type: CNAME" -ForegroundColor Gray
Write-Host "   Name: n0" -ForegroundColor Gray
Write-Host "   Value: $currentFqdn" -ForegroundColor Gray
Write-Host ""
Write-Host "2. Add TXT record for verification (check Azure Portal)" -ForegroundColor White
Write-Host ""
Write-Host "3. After DNS propagates, bind certificate:" -ForegroundColor White
Write-Host "   az containerapp hostname bind --hostname $Hostname --resource-group $ResourceGroup --name $ServiceName --environment sorcha-env-prod --validation-method CNAME" -ForegroundColor Gray

Security Considerations

HTTPS Only

  • Always use HTTPS for custom domains
  • Managed certificates auto-renew
  • No manual certificate management needed

Hostname Validation

  • Enable after DNS is confirmed working
  • Prevents accidental deployment to wrong environment
  • Protects against DNS hijacking

Firewall Rules

  • Consider Azure Front Door or Application Gateway for additional security
  • Implement rate limiting for gRPC endpoints
  • Use Azure WAF for DDoS protection

Cost Impact

  • Custom Domain: Free (included with Container Apps)
  • Managed Certificate: Free (Let's Encrypt via Azure)
  • DNS: Depends on provider (~$1-5/month)
  • SSL/TLS Traffic: No additional cost

Next Steps

  1. ✅ Configure DNS CNAME record for n0.sorcha.dev
  2. ✅ Add TXT record for domain verification
  3. ✅ Bind managed certificate
  4. ✅ Test HTTPS access
  5. ✅ Enable hostname validation
  6. ✅ Update other peer nodes to connect to n0.sorcha.dev

Questions? See AZURE-DATABASE-INITIALIZATION.md for related Azure setup.

Released under the MIT License.