A sample application demonstrating how to deploy a containerized Flask web app using four Azure services:
- Azure Blob Storage — Stores vacation activities as JSON blobs
- Azure Key Vault — Stores the storage connection string as a secret
- Azure Container Registry (ACR) — Hosts the Docker container image
- Azure Container Instances (ACI) — Runs the containerized application
┌──────────────┐ store conn ┌──────────────┐ env vars ┌──────────────┐
│ Storage │ ──── string ────► │ KeyVault │ ─────────► │ ACI │
│ Account │ │ (secrets) │ │ (container │
└──────────────┘ └──────────────┘ │ group) │
▲ │ │
│ read/write activities │ │
└────────────────────────────────────────────────────────┤ │
│ │
┌──────────────┐ image pull │ │
│ ACR │ ────────────────────────────────────────────► │ │
│ (registry) │ (registry credentials) └──────────────┘
└──────────────┘
Deployment flow: The deploy script creates Storage and Key Vault first, stores the storage connection string as a secret, creates ACR and pushes the container image, then creates an ACI container group that pulls from ACR with the secrets injected as environment variables.
At runtime: The Flask app reads the storage connection string from its environment, connects to Blob Storage, and provides a web UI for managing vacation activities (add, edit, delete).
- LocalStack
- Docker
- Azure CLI
- azlocal (
pip install azlocal) - Terraform (optional, for Terraform deployment)
# Start LocalStack Azure
IMAGE_NAME=localstack/localstack-azure-alpha localstack start -d
localstack wait -t 60
# Login
azlocal login
azlocal start_interception
# Deploy all services
cd python
bash scripts/deploy.sh
# Validate the deployment (includes stop/start/restart lifecycle tests)
bash scripts/validate.shcd python
bash bicep/deploy.shcd python
bash terraform/deploy.sh# Removes all resources created by deploy.sh
bash scripts/cleanup.shThe Vacation Planner is a Flask web application with a Bootstrap UI that lets users manage vacation activities. Activities are stored as JSON blobs in Azure Blob Storage, organized by username.
| Route | Method | Description |
|---|---|---|
/ |
GET | View all activities |
/ |
POST | Add or update an activity |
/delete/<id> |
POST | Delete an activity |
/update/<id> |
GET | Edit an activity |
/health |
GET | Health check |
| Variable | Description |
|---|---|
AZURE_STORAGE_CONNECTION_STRING |
Blob Storage connection string (from Key Vault) |
BLOB_CONTAINER_NAME |
Name of the blob container for activities |
LOGIN_NAME |
Username for the activity list (default: "paolo") |
| Script | Description |
|---|---|
scripts/deploy.sh |
Deploys Storage, Key Vault, ACR, and ACI with env vars and DNS label |
scripts/validate.sh |
Validates all resources and exercises ACI lifecycle (get, list, logs, exec, stop, start, restart) |
scripts/cleanup.sh |
Removes all resources created by deploy.sh |
bicep/deploy.sh |
Deploys all resources using a Bicep template |
terraform/deploy.sh |
Deploys all resources using Terraform |
| Feature | Script |
|---|---|
| Container group create | deploy.sh |
| Public IP + ports | deploy.sh |
| Environment variables | deploy.sh |
| Registry credentials (ACR) | deploy.sh |
| CPU / memory resources | deploy.sh |
| DNS name label / FQDN | deploy.sh |
| Container get / list | validate.sh |
| Container logs | validate.sh |
| Container exec | validate.sh |
| Stop / Start / Restart | validate.sh |