What You'll Build
You will deploy the cricket analytics API on Azure using Azure Container Apps (the Azure equivalent of AWS ECS Fargate / Cloud Run), configure Azure Blob Storage for data ingestion, set up Azure Application Insights for monitoring, and then compare the deployment experience, cost model and operational characteristics with the equivalent AWS deployment from M4. By the end, you will have hands-on experience with Azure's managed container platform and a concrete comparison of how the same workload looks across both clouds — the foundation of multi-cloud engineering fluency.
Prerequisites
- Azure CLI installed and authenticated — az login
- Azure subscription with permissions to create Container Apps, Storage Accounts and Application Insights
- Docker installed locally for building the container image
- Completed M5 Lessons 1-2: Azure Architecture and Azure Core Services
- The cricket API code from M4 Practice (or a simple Flask/FastAPI hello-world as substitute)
Setup — Resource Group and Container Registry
Create the resource group and Azure Container Registry (ACR — equivalent to AWS ECR). All resources in this exercise are grouped in one resource group so they can be deleted with a single command at the end.
#!/bin/bash
set -euo pipefail
RG='cricket-azure-lab'
LOCATION='centralindia'
ACR_NAME="cricketapilab$(date +%s | tail -c 6)"
echo '=== Creating resource group ==='
az group create --name "$RG" --location "$LOCATION"
echo
echo '=== Creating Azure Container Registry ==='
az acr create \
--resource-group "$RG" \
--name "$ACR_NAME" \
--sku Basic \
--admin-enabled true
ACR_URL="${ACR_NAME}.azurecr.io"
ACR_PASS=$(az acr credential show --name "$ACR_NAME" --query passwords[0].value --output tsv)
echo "ACR: ${ACR_URL}"
echo
echo '=== Build and push container image ==='
# Create minimal cricket API
mkdir -p /tmp/cricket_azure_api
cat > /tmp/cricket_azure_api/app.py << 'PYTHON'
from flask import Flask, jsonify
import os, datetime
app = Flask(__name__)
@app.route('/health')
def health():
return jsonify(status='healthy', region=os.environ.get('AZURE_REGION','unknown'), time=str(datetime.datetime.utcnow()))
@app.route('/api/score/<match_id>')
def get_score(match_id):
return jsonify(match_id=match_id, score='CSK: 180/4 (20 overs)', cloud='azure')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
PYTHON
cat > /tmp/cricket_azure_api/Dockerfile << 'DOCKERFILE'
FROM python:3.11-slim
WORKDIR /app
COPY app.py .
RUN pip install flask gunicorn
EXPOSE 8080
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]
DOCKERFILE
# Login and push to ACR
echo "$ACR_PASS" | docker login "$ACR_URL" --username "$ACR_NAME" --password-stdin
docker build -t "${ACR_URL}/cricket-api:v1" /tmp/cricket_azure_api/
docker push "${ACR_URL}/cricket-api:v1"
echo "Image pushed: ${ACR_URL}/cricket-api:v1"
# Save config
cat > /tmp/azure_lab.env << ENV
RG='${RG}'
LOCATION='${LOCATION}'
ACR_NAME='${ACR_NAME}'
ACR_URL='${ACR_URL}'
ACR_PASS='${ACR_PASS}'
ENV