Skip to content

This repository contains deployment manifests and configuration for running the SAIF (Secure AI Foundations) application on Azure Local in disconnected operations mode. The deployment includes a 3-tier containerized application with local monitoring and SQL Server VM backend.

Notifications You must be signed in to change notification settings

jonathan-vella/saif-aldo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SAIF on Azure Local - Disconnected Operations Deployment Guide

Azure Local Kubernetes License

Overview

This repository contains deployment manifests and configuration for running the SAIF (Secure AI Foundations) application on Azure Local in disconnected operations mode. The deployment includes a 3-tier containerized application with local monitoring and SQL Server VM backend.

Architecture

graph TB
    subgraph "Azure Local - Disconnected Operations"
        subgraph "AKS Arc Cluster"
            Web[Web Frontend<br/>PHP 8.2<br/>2 replicas]
            API[API Backend<br/>FastAPI Python<br/>2 replicas]
            Ingress[NGINX Ingress<br/>Controller]
            
            subgraph "Monitoring Stack"
                Prom[Prometheus<br/>Metrics]
                Graf[Grafana<br/>Dashboards]
            end
            
            Ingress --> Web
            Ingress --> API
            API --> Prom
            Web --> Prom
            Prom --> Graf
        end
        
        subgraph "Infrastructure"
            ACR[Local Azure<br/>Container Registry]
            SQL[SQL Server VM<br/>SQL Authentication]
        end
        
        Web --> API
        API --> SQL
        AKS --> ACR
    end
    
    User[User] --> Ingress
    
    style User fill:#f96,stroke:#333,color:#000
    style Web fill:#0078D4,stroke:#005A9E,color:#fff
    style API fill:#0078D4,stroke:#005A9E,color:#fff
    style SQL fill:#CC2927,stroke:#A52A2A,color:#fff
    style Prom fill:#E6522C,stroke:#C63928,color:#fff
    style Graf fill:#F46800,stroke:#D15D00,color:#fff
    style ACR fill:#0089D6,stroke:#006BB8,color:#fff
    style Ingress fill:#009639,stroke:#007A2F,color:#fff
Loading

Key Features

  • Disconnected Operations: No dependency on Azure cloud services
  • SQL Authentication: Uses SQL Server authentication (Entra ID not supported in disconnected mode)
  • Local Monitoring: Prometheus & Grafana for metrics and dashboards
  • Local Container Registry: Pre-loaded images in Azure Container Registry
  • Static Networking: Configured for Azure Local logical networks
  • High Availability: 2 replicas each for web and API pods

Prerequisites

Azure Local Environment

  • Azure Local cluster deployed with disconnected operations enabled
  • AKS Arc cluster created (see boilerplates/aks-arc/create-cluster.md)
  • Supported Kubernetes versions: 1.27.7, 1.27.9, 1.28.5, 1.28.9, 1.29.2, 1.29.4 (recommended)

SQL Server

  • SQL Server VM deployed on Azure Local (see boilerplates/sql-server/sql-vm-setup.md)
  • SQL Server 2022 (Standard or Enterprise)
  • SQL Server Authentication enabled
  • Database: saifdb
  • User: saifadmin with appropriate permissions

Container Images

Tools

  • kubectl configured with AKS Arc cluster credentials
  • Azure CLI with AKS Arc extensions
  • PowerShell 7+ (for deployment scripts)

Repository Structure

graph LR
    Root[saif-aldo] --> K8s[kubernetes/]
    Root --> Boot[boilerplates/]
    Root --> Reg[container-registry/]
    Root --> SQL[sql-scripts/]
    Root --> Docs[docs/]
    
    K8s --> Manifests[manifests/]
    K8s --> Config[config/]
    
    Manifests --> Web[web/]
    Manifests --> API[api/]
    Manifests --> Mon[monitoring/]
    
    Config --> NS[namespace.yaml]
    Config --> CM[configmap.yaml]
    Config --> Sec[secret.yaml]
    
    Boot --> AKS[aks-arc/]
    Boot --> SQLBoot[sql-server/]
    
    style Root fill:#0078D4,stroke:#005A9E,color:#fff
    style K8s fill:#326CE5,stroke:#2A5DC7,color:#fff
    style Boot fill:#FFB900,stroke:#D99E00,color:#000
    style Reg fill:#0089D6,stroke:#006BB8,color:#fff
    style SQL fill:#CC2927,stroke:#A52A2A,color:#fff
Loading

Deployment Checklist

Before starting deployment, ensure you have:

  • Azure Local cluster deployed in disconnected mode
  • AKS Arc cluster created (Kubernetes 1.27.7 - 1.29.4)
  • SQL Server VM deployed with SQL authentication enabled
  • Local Azure Container Registry accessible
  • Docker installed for building images
  • kubectl configured with AKS Arc credentials
  • Azure CLI installed with aksarc extension
  • PowerShell 7+ installed
  • Network connectivity between AKS Arc and SQL Server VM
  • SQL Server credentials ready (username/password)

Quick Start

1. Configure Environment

# Clone repository (if not already done)
git clone <repository-url>
cd saif-aldo

# Get AKS Arc credentials
az aksarc get-credentials \
  --resource-group <your-rg> \
  --name <your-aks-cluster> \
  --admin

# Verify cluster access
kubectl get nodes

2. Prepare Container Images

# Pre-load and push images to local registry
cd container-registry
.\prepare-images.ps1

# Select option 5 for full workflow (Build and Export)

3. Deploy SQL Database

# Deploy database schema
cd ..\sql-scripts

$password = Read-Host "Enter SQL password" -AsSecureString

.\deploy-database.ps1 `
  -SqlServerInstance "sql-server-vm.local" `
  -Username "saifadmin" `
  -Password $password

4. Update Configuration

Edit kubernetes/config/configmap.yaml:

data:
  SQL_SERVER: "sql-server-vm.local"  # Update with actual SQL Server hostname/IP
  SQL_DATABASE: "saifdb"

Edit kubernetes/config/secret.yaml:

stringData:
  SQL_USERNAME: "saifadmin"
  SQL_PASSWORD: "YourSecurePassword"  # Update with actual password

Tip: If you need Base64-encoded values instead of stringData, use:

# Base64 encode credentials
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("your-sql-server.local"))
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("saifdb"))
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("saifadmin"))
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("YourSecurePassword"))

5. Deploy to Kubernetes

cd ..\kubernetes

# Create namespace and configuration
kubectl apply -f config/namespace.yaml
kubectl apply -f config/configmap.yaml
kubectl apply -f config/secret.yaml

# Deploy application
kubectl apply -f manifests/api/
kubectl apply -f manifests/web/

# Deploy monitoring
kubectl apply -f manifests/monitoring/

# Verify deployment
kubectl get pods -n saif
kubectl get services -n saif

Deployment Workflow

flowchart TD
    Start([Start Deployment]) --> CheckPrereq{Prerequisites<br/>Met?}
    CheckPrereq -->|No| FixPrereq[Fix Prerequisites]
    FixPrereq --> CheckPrereq
    CheckPrereq -->|Yes| PrepImages[Prepare Container Images]
    
    PrepImages --> Build[Build SAIF Images]
    Build --> Export[Export to TAR Files]
    Export --> Transfer[Transfer to Disconnected]
    Transfer --> Load[Load Images]
    Load --> Push[Push to Local ACR]
    
    Push --> DeploySQL[Deploy SQL Database]
    DeploySQL --> InitDB[Initialize Database Schema]
    
    InitDB --> UpdateConfig[Update Kubernetes Config]
    UpdateConfig --> CreateNS[Create Namespace]
    CreateNS --> CreateCM[Apply ConfigMap]
    CreateCM --> CreateSec[Apply Secrets]
    
    CreateSec --> DeployAPI[Deploy API Pods]
    DeployAPI --> DeployWeb[Deploy Web Pods]
    DeployWeb --> DeployMon[Deploy Monitoring]
    
    DeployMon --> Verify{All Pods<br/>Running?}
    Verify -->|No| Troubleshoot[Troubleshoot Issues]
    Troubleshoot --> Verify
    Verify -->|Yes| TestApp[Test Application]
    
    TestApp --> Success([Deployment Complete])
    
    style Start fill:#4CAF50,stroke:#2E7D32,color:#fff
    style Success fill:#4CAF50,stroke:#2E7D32,color:#fff
    style CheckPrereq fill:#FFC107,stroke:#F57C00,color:#000
    style Verify fill:#FFC107,stroke:#F57C00,color:#000
    style Troubleshoot fill:#F44336,stroke:#C62828,color:#fff
Loading

Accessing the Application

Get Service URLs

# Get web frontend URL
kubectl get service saif-web -n saif

# Get API service URL
kubectl get service saif-api -n saif

# Get Grafana dashboard URL
kubectl get service grafana -n saif

Test Connectivity

# Test API health check
kubectl run -it --rm test --image=curlimages/curl --restart=Never -n saif -- \
  curl http://saif-api:8000/api/healthcheck

# Test web frontend
kubectl run -it --rm test --image=curlimages/curl --restart=Never -n saif -- \
  curl http://saif-web/

Monitoring

Access Prometheus

# Port-forward to Prometheus
kubectl port-forward -n saif svc/prometheus-server 9090:9090

# Open http://localhost:9090

Access Grafana

# Port-forward to Grafana
kubectl port-forward -n saif svc/grafana 3000:3000

# Open http://localhost:3000
# Default credentials: admin/admin (change on first login)

Monitoring Architecture

graph LR
    subgraph "Application Pods"
        API[API Pods]
        Web[Web Pods]
    end
    
    subgraph "Monitoring Stack"
        Prom[Prometheus]
        Store[Time Series DB]
        Graf[Grafana]
        Dash[Dashboards]
    end
    
    API -->|/metrics| Prom
    Web -->|/metrics| Prom
    Prom --> Store
    Store --> Graf
    Graf --> Dash
    
    User[User] --> Graf
    
    style API fill:#0078D4,stroke:#005A9E,color:#fff
    style Web fill:#0078D4,stroke:#005A9E,color:#fff
    style Prom fill:#E6522C,stroke:#C63928,color:#fff
    style Graf fill:#F46800,stroke:#D15D00,color:#fff
    style User fill:#f96,stroke:#333,color:#000
Loading

Troubleshooting

Pod Status Issues

# Check pod status
kubectl get pods -n saif

# Get pod logs
kubectl logs -n saif <pod-name>

# Describe pod for events
kubectl describe pod -n saif <pod-name>

Image Pull Issues

# Verify ACR secret
kubectl get secret acr-secret -n saif

# Test image pull
kubectl run test --image=<registry>/saif/api:latest --image-pull-policy=IfNotPresent -n saif

SQL Connectivity Issues

# Test SQL connection from pod
kubectl run -it --rm sqltest --image=mcr.microsoft.com/mssql-tools --restart=Never -n saif -- /bin/bash

# Inside pod
/opt/mssql-tools/bin/sqlcmd -S sql-server-vm.local -U saifadmin -P 'password' -Q "SELECT @@VERSION"

DNS Resolution Issues

# Test DNS from pod
kubectl run -it --rm dnstest --image=busybox --restart=Never -n saif -- nslookup sql-server-vm.local

# If DNS fails, update /etc/hosts or use IP address directly

Maintenance

Update Application Images

# Build new version
cd container-registry
.\prepare-images.ps1

# Update deployment
kubectl set image deployment/saif-api api=<registry>/saif/api:v2 -n saif
kubectl set image deployment/saif-web web=<registry>/saif/web:v2 -n saif

# Monitor rollout
kubectl rollout status deployment/saif-api -n saif
kubectl rollout status deployment/saif-web -n saif

Scale Application

# Scale API pods
kubectl scale deployment saif-api --replicas=3 -n saif

# Scale web pods
kubectl scale deployment saif-web --replicas=3 -n saif

Backup Database

-- Run on SQL Server VM
BACKUP DATABASE [saifdb] 
TO DISK = 'E:\SQLBackups\saifdb_full.bak'
WITH INIT, COMPRESSION;

Security Considerations

In Disconnected Mode

  • ✅ No Microsoft Entra ID (use SQL authentication)
  • ✅ Secrets stored in Kubernetes secrets (consider encryption at rest)
  • ✅ Network policies to restrict pod-to-pod communication
  • ✅ SQL Server authentication with strong passwords
  • ✅ Local monitoring (no Azure Monitor telemetry)

Recommendations

  1. Rotate SQL credentials regularly
  2. Enable Kubernetes RBAC for access control
  3. Use NetworkPolicies to restrict traffic
  4. Encrypt secrets at rest in etcd
  5. Regular security updates for container images
  6. Monitor security events in Prometheus/Grafana

Limitations

Disconnected Operations Constraints

  • No Microsoft Entra ID: Must use local authentication
  • No Azure Monitor: Use Prometheus/Grafana instead
  • No Key Vault: Secrets managed in Kubernetes
  • No Managed Identity: Use service accounts and credentials
  • No App Insights: Local logging and monitoring only
  • ⚠️ GPU not supported in disconnected AKS
  • ⚠️ CLI-based management (portal limitations)

References

Official Documentation

Project Documentation

Original SAIF Application

Contributing

Contributions are welcome! Please ensure:

  1. All diagrams use Mermaid format
  2. No dependencies on Azure cloud services
  3. Testing in disconnected environment
  4. Documentation updates included

License

MIT License - see LICENSE file for details

Support

For issues and questions:

  1. Check Troubleshooting section
  2. Review official documentation
  3. Open an issue in this repository

Note: This deployment is optimized for Azure Local in disconnected operations mode. For cloud-based deployments, refer to the original SAIF repository.

About

This repository contains deployment manifests and configuration for running the SAIF (Secure AI Foundations) application on Azure Local in disconnected operations mode. The deployment includes a 3-tier containerized application with local monitoring and SQL Server VM backend.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published