This guide covers two deployment scenarios:
- LOCAL TESTING - Backend runs on your machine, frontend for testing
- AZURE PRODUCTION - Frontend on Azure Static Web Apps, backend stays local (or can be moved to Azure later)
# Install Azure CLI
# Download from: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows
# Install Azure Functions Core Tools
npm install -g azure-functions-core-tools@4 --unsafe-perm=true
# Install Azure Static Web Apps CLI
npm install -g @azure/static-web-apps-cli
# Verify installations
az --version
func --version
swa --version- ✅ Azure Subscription (with credits/payment method)
- ✅ Azure OpenAI Service (or OpenAI API key)
- ✅ Resource Group
- ✅ Storage Account (for CSV data)
- ✅ Function App (for backend - needed later)
- ✅ Static Web App (for frontend hosting)
- Code must be pushed to GitHub (for Static Web App CI/CD)
- Generate GitHub Personal Access Token: https://github.com/settings/tokens
This script creates all necessary Azure resources and uploads your data.
cd c:\mygit\CriticalPath-AI-E2
.\scripts\deploy-azure.ps1The script will prompt for:
- Azure Subscription ID
- Resource Group name (e.g.,
criticalpath-rg) - Azure Region (e.g.,
eastus) - Function App name (e.g.,
cp-api-func) - Storage Account name (e.g.,
cpapistg) - Static Web App name (e.g.,
cp-app-swa) - Azure OpenAI API Key
- Azure OpenAI Endpoint
- GitHub Repository URL
- GitHub Personal Access Token
Output: Connection string (save this in a safe place!)
Keep your backend running on your machine while hosting the frontend on Azure.
cd c:\mygit\CriticalPath-AI-E2
.\scripts\run-local.ps1What this does:
- Creates Python virtual environment
- Installs dependencies
- Prompts for API keys (Azure OpenAI or OpenAI)
- Starts Azure Functions emulator on
http://localhost:7071
Terminal output example:
================================================
Starting CriticalPath AI - Local Development
================================================
Frontend: http://localhost:8080
Backend API: http://localhost:7071/api
Press Ctrl+C to stop
# Test projects endpoint
curl http://localhost:7071/api/projects
# Test session creation
curl -X POST http://localhost:7071/api/session `
-Headers @{"Content-Type"="application/json"} `
-Body '{"proj_id":"P01-1"}'-
Push code to GitHub:
cd c:\mygit\CriticalPath-AI-E2 git add . git commit -m "Deploy to Azure" git push origin main
-
Azure will automatically:
- Detect the push
- Build the app (GitHub Actions workflow)
- Deploy to Static Web App
- Get a public URL (e.g.,
https://cp-app-swa.azurestaticapps.net)
-
Verify deployment:
- Check GitHub Actions: https://github.com/YOUR-USERNAME/CriticalPath-AI-E2/actions
- Wait for workflow to complete
- Visit the Static Web App URL
cd c:\mygit\CriticalPath-AI-E2
# Deploy all frontend files
swa deploy .\frontend `
--env production `
--deployment-token <your-swa-deployment-token>Your frontend needs to know where the backend is.
- Frontend auto-detects
localhostand routes tohttp://localhost:7071 - No changes needed!
The staticwebapp.config.json file handles routing:
{
"routes": [
{
"route": "/api/*",
"allowedRoles": ["anonymous"]
}
]
}This configuration proxies /api/* calls through Azure Static Web Apps.
The deployment script uploads CSV files automatically, but you can add more data later:
$storageAccount = "cpapistg" # Your storage account name
$container = "project-data"
$storageKey = "your-storage-key"
# Upload new CSV files
Get-ChildItem "data/*.csv" | ForEach-Object {
az storage blob upload `
--account-name $storageAccount `
--account-key $storageKey `
--container-name $container `
--name $_.Name `
--file $_.FullName
}Your Machine Azure Cloud
┌──────────────────────────┐ ┌────────────────────────┐
│ Frontend │ │ Azure OpenAI Service │
│ (http://localhost:8080) │────────►│ (API calls) │
│ │ │ │
│ Backend Functions Emulator │ Azure Blob Storage │
│ (http://localhost:7071) │────────►│ (CSV data) │
└──────────────────────────┘ └────────────────────────┘
Browser Azure Cloud
│ ┌─────────────────────────────────────┐
│ │ Static Web Apps (Frontend) │
├───────────────────►│ https://cp-app-swa.azurestaticapps │
│ │ │
│ │ /api/* → localhost:7071 (your PC) │
│ └─────────────────────────────────────┘
│ │
│ ▼
│ Your Machine
│ ┌────────────────────────────────────────┐
└─►│ Functions Emulator (Backend) │
│ http://localhost:7071 │
│ (via any Internet connection) │
└────────────────────────────────────────┘
- Backend running locally:
http://localhost:7071/api/projects - Frontend loaded: Visit Static Web App URL
- Load projects: Select a project in the dropdown
- Start session: Click "Start Session"
- Send message: Type a question and send
- Check console: Open browser DevTools (F12) → Console for errors
AZURE_OPENAI_API_KEY=<your-key>
AZURE_OPENAI_ENDPOINT=<your-endpoint>
AZURE_STORAGE_CONNECTION_STRING=<your-blob-connection>
OPENAI_MODEL=gpt-4o-mini
MAX_HISTORY_MESSAGES=20
Same as above, stored in Azure Key Vault / App Settings
- Never commit secrets - Use
.envfiles (add to.gitignore) - GitHub Tokens - Use fine-grained tokens with limited scopes
- Azure Keys - Store in Azure Key Vault, not in code
- CORS - Static Web Apps automatically handle CORS for /api routes
Solution: Backend not running. Run .\scripts\run-local.ps1 in another terminal.
Solution: This shouldn't happen on Azure, but for local testing, ensure backend is running.
Solution: Set environment variables before starting backend:
$env:AZURE_OPENAI_API_KEY = "your-key"
$env:AZURE_OPENAI_ENDPOINT = "your-endpoint"Solution: Make sure you're in the api folder:
cd api
func azure functionapp publish <function-app-name>Solution: Check GitHub Actions workflow output for build errors.
- Complete Step 1: Run
.\scripts\deploy-azure.ps1 - Start Testing: Run
.\scripts\run-local.ps1 - Deploy Frontend: Push to GitHub main branch
- Verify: Visit Static Web App URL and test endpoints
- (Optional) Move Backend to Azure: Run
.\scripts\deploy-functions.ps1later
| Component | Plan | Cost | Notes |
|---|---|---|---|
| Static Web Apps | Free | $0 | 1 free app per subscription |
| Function App | Consumption | Pay-per-call | ~$0.20 per million executions |
| Blob Storage | Standard LRS | ~$0.024/GB | Low cost for small data |
| Azure OpenAI | Pay-per-token | Varies | ~$0.003/1K input tokens |