Skip to main content

Azure Deployment

Deploy Optimal Platform to Microsoft Azure using AKS (Azure Kubernetes Service).

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│ AZURE SUBSCRIPTION │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ RESOURCE GROUP │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ VNET (10.0.0.0/8) │ │ │
│ │ │ │ │ │
│ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ AKS CLUSTER │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ │
│ │ │ │ │ System │ │ User │ │ User │ │ │ │ │
│ │ │ │ │ Node Pool │ │ Node Pool │ │ Node Pool │ │ │ │ │
│ │ │ │ │ (Zone 1) │ │ (Zone 2) │ │ (Zone 3) │ │ │ │ │
│ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ └─────────────────────────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Azure DB │ │ Azure Cache │ │ Blob │ │ │
│ │ │ PostgreSQL │ │ for Redis │ │ Storage │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Azure DNS │ │ Key Vault │ │ Azure │ │
│ │ │ │ │ │ Monitor │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Prerequisites

  • Azure CLI (az)
  • Terraform 1.5+
  • kubectl
  • Helm 3.x

Deployment Steps

1. Configure Azure

# Login to Azure
az login

# Set subscription
az account set --subscription "Your Subscription Name"

# Register required providers
az provider register --namespace Microsoft.ContainerService
az provider register --namespace Microsoft.KeyVault

2. Configure Terraform

cd infra/terraform/azure

# Copy example configuration
cp terraform.tfvars.example terraform.tfvars

Edit terraform.tfvars:

# Azure Configuration
subscription_id = "your-subscription-id"
location = "eastus"
environment = "production"

# Resource Group
resource_group_name = "optimal-production-rg"

# Cluster Configuration
cluster_name = "optimal-production"
kubernetes_version = "1.28"

# Node Pools
system_node_pool = {
name = "system"
vm_size = "Standard_D4s_v3"
node_count = 3
zones = ["1", "2", "3"]
}

user_node_pool = {
name = "application"
vm_size = "Standard_D8s_v3"
min_count = 3
max_count = 10
zones = ["1", "2", "3"]
}

# Domain (optional)
domain_name = "yourdomain.com"

3. Deploy Infrastructure

# Initialize Terraform
terraform init

# Review plan
terraform plan

# Apply (takes ~15-20 minutes)
terraform apply

4. Configure kubectl

# Get AKS credentials
az aks get-credentials \
--resource-group optimal-production-rg \
--name optimal-production

# Verify connection
kubectl get nodes

5. Deploy Platform

cd ../../..

# Deploy platform
helm upgrade --install optimal-platform k8s/helm-charts/optimal-platform \
--namespace optimal-system \
--create-namespace \
-f k8s/helm-charts/optimal-platform/values-production.yaml \
--set global.domain=yourdomain.com

6. Configure DNS

# Get Load Balancer IP
kubectl get svc -n ingress-nginx ingress-nginx-controller \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}'

# Create DNS zone (if needed)
az network dns zone create \
--resource-group optimal-production-rg \
--name yourdomain.com

# Create A record
az network dns record-set a add-record \
--resource-group optimal-production-rg \
--zone-name yourdomain.com \
--record-set-name portal \
--ipv4-address <LOAD_BALANCER_IP>

Azure Services Used

ServicePurposeConfiguration
AKSKubernetes clusterMulti-zone
Azure Database for PostgreSQLDatabaseFlexible Server
Azure Cache for RedisCachePremium tier
Blob StorageBackup storageLRS/GRS
Azure DNSDNS managementOptional
Key VaultSecrets managementRBAC enabled
Azure MonitorMonitoringContainer Insights

Production Configuration

High Availability

# values-production.yaml
global:
highAvailability: true

portal:
replicas: 3
podDisruptionBudget:
minAvailable: 2

# Zone redundancy
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule

Azure Database for PostgreSQL

postgresql:
enabled: false # Use Azure PostgreSQL instead

externalDatabase:
host: optimal-db.postgres.database.azure.com
port: 5432
database: optimal
sslMode: require
existingSecret: azure-db-credentials

Key Vault Integration

# Use Azure Key Vault for secrets
csi:
enabled: true
secrets-store:
azure:
enabled: true
keyvaultName: optimal-keyvault
tenantId: your-tenant-id

Azure AD Integration

# Azure AD for authentication
keycloak:
identityProviders:
azure:
enabled: true
tenantId: your-tenant-id
clientId: your-client-id

Security

Azure Policy

Enable Azure Policy for AKS:

az aks enable-addons \
--addons azure-policy \
--name optimal-production \
--resource-group optimal-production-rg

Private Cluster

# terraform.tfvars
private_cluster_enabled = true
private_dns_zone_id = "/subscriptions/.../privateDnsZones/privatelink.eastus.azmk8s.io"

Network Security

# Network Security Groups
network_security_rules = {
allow-https = {
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
port = 443
}
}

Monitoring

Azure Monitor / Container Insights

Container Insights is automatically enabled:

# View logs
az monitor log-analytics query \
--workspace optimal-workspace \
--analytics-query "ContainerLog | take 100"

Application Insights

# Enable Application Insights
applicationInsights:
enabled: true
connectionString: ${APP_INSIGHTS_CONNECTION_STRING}

Government Cloud

For Azure Government:

# terraform.tfvars
environment = "usgovernment"
location = "usgovvirginia"

Cleanup

# Delete platform
helm uninstall optimal-platform -n optimal-system

# Delete infrastructure
cd infra/terraform/azure
terraform destroy

Troubleshooting

AKS Node Issues

# Check node pool status
az aks nodepool show \
--resource-group optimal-production-rg \
--cluster-name optimal-production \
--name application

# Scale node pool
az aks nodepool scale \
--resource-group optimal-production-rg \
--cluster-name optimal-production \
--name application \
--node-count 5

Azure PostgreSQL Connection

# Test connectivity
az postgres flexible-server connect \
--name optimal-db \
--admin-user optimal_admin \
--admin-password <password>