|
| 1 | +# Vacation Planner on Azure Container Instances |
| 2 | + |
| 3 | +A sample application demonstrating how to deploy a containerized Flask web app using four Azure services: |
| 4 | + |
| 5 | +- **Azure Blob Storage** — Stores vacation activities as JSON blobs |
| 6 | +- **Azure Key Vault** — Stores the storage connection string as a secret |
| 7 | +- **Azure Container Registry (ACR)** — Hosts the Docker container image |
| 8 | +- **Azure Container Instances (ACI)** — Runs the containerized application |
| 9 | + |
| 10 | +## Architecture |
| 11 | + |
| 12 | +``` |
| 13 | +┌──────────────┐ store conn ┌──────────────┐ env vars ┌──────────────┐ |
| 14 | +│ Storage │ ──── string ────► │ KeyVault │ ─────────► │ ACI │ |
| 15 | +│ Account │ │ (secrets) │ │ (container │ |
| 16 | +└──────────────┘ └──────────────┘ │ group) │ |
| 17 | + ▲ │ │ |
| 18 | + │ read/write activities │ │ |
| 19 | + └────────────────────────────────────────────────────────┤ │ |
| 20 | + │ │ |
| 21 | +┌──────────────┐ image pull │ │ |
| 22 | +│ ACR │ ────────────────────────────────────────────► │ │ |
| 23 | +│ (registry) │ (registry credentials) └──────────────┘ |
| 24 | +└──────────────┘ |
| 25 | +``` |
| 26 | + |
| 27 | +**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. |
| 28 | + |
| 29 | +**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). |
| 30 | + |
| 31 | +## Prerequisites |
| 32 | + |
| 33 | +- [LocalStack](https://docs.localstack.cloud/getting-started/installation/) |
| 34 | +- [Docker](https://docs.docker.com/get-docker/) |
| 35 | +- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) |
| 36 | +- [azlocal](https://pypi.org/project/azlocal/) (`pip install azlocal`) |
| 37 | +- [Terraform](https://developer.hashicorp.com/terraform/downloads) (optional, for Terraform deployment) |
| 38 | + |
| 39 | +## Quick Start |
| 40 | + |
| 41 | +```bash |
| 42 | +# Start LocalStack Azure |
| 43 | +IMAGE_NAME=localstack/localstack-azure-alpha localstack start -d |
| 44 | +localstack wait -t 60 |
| 45 | + |
| 46 | +# Login |
| 47 | +azlocal login |
| 48 | +azlocal start_interception |
| 49 | + |
| 50 | +# Deploy all services |
| 51 | +cd python |
| 52 | +bash scripts/deploy.sh |
| 53 | + |
| 54 | +# Validate the deployment (includes stop/start/restart lifecycle tests) |
| 55 | +bash scripts/validate.sh |
| 56 | +``` |
| 57 | + |
| 58 | +## Alternative Deployments |
| 59 | + |
| 60 | +### Bicep |
| 61 | + |
| 62 | +```bash |
| 63 | +cd python |
| 64 | +bash bicep/deploy.sh |
| 65 | +``` |
| 66 | + |
| 67 | +### Terraform |
| 68 | + |
| 69 | +```bash |
| 70 | +cd python |
| 71 | +bash terraform/deploy.sh |
| 72 | +``` |
| 73 | + |
| 74 | +## Cleanup |
| 75 | + |
| 76 | +```bash |
| 77 | +# Removes all resources created by deploy.sh |
| 78 | +bash scripts/cleanup.sh |
| 79 | +``` |
| 80 | + |
| 81 | +## Application |
| 82 | + |
| 83 | +The 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. |
| 84 | + |
| 85 | +### Endpoints |
| 86 | + |
| 87 | +| Route | Method | Description | |
| 88 | +|-------|--------|-------------| |
| 89 | +| `/` | GET | View all activities | |
| 90 | +| `/` | POST | Add or update an activity | |
| 91 | +| `/delete/<id>` | POST | Delete an activity | |
| 92 | +| `/update/<id>` | GET | Edit an activity | |
| 93 | +| `/health` | GET | Health check | |
| 94 | + |
| 95 | +### Environment Variables |
| 96 | + |
| 97 | +| Variable | Description | |
| 98 | +|----------|-------------| |
| 99 | +| `AZURE_STORAGE_CONNECTION_STRING` | Blob Storage connection string (from Key Vault) | |
| 100 | +| `BLOB_CONTAINER_NAME` | Name of the blob container for activities | |
| 101 | +| `LOGIN_NAME` | Username for the activity list (default: "paolo") | |
| 102 | + |
| 103 | +## Scripts |
| 104 | + |
| 105 | +| Script | Description | |
| 106 | +|--------|-------------| |
| 107 | +| `scripts/deploy.sh` | Deploys Storage, Key Vault, ACR, and ACI with env vars and DNS label | |
| 108 | +| `scripts/validate.sh` | Validates all resources and exercises ACI lifecycle (get, list, logs, exec, stop, start, restart) | |
| 109 | +| `scripts/cleanup.sh` | Removes all resources created by deploy.sh | |
| 110 | +| `bicep/deploy.sh` | Deploys all resources using a Bicep template | |
| 111 | +| `terraform/deploy.sh` | Deploys all resources using Terraform | |
| 112 | + |
| 113 | +## ACI Features Demonstrated |
| 114 | + |
| 115 | +| Feature | Script | |
| 116 | +|---------|--------| |
| 117 | +| Container group create | deploy.sh | |
| 118 | +| Public IP + ports | deploy.sh | |
| 119 | +| Environment variables | deploy.sh | |
| 120 | +| Registry credentials (ACR) | deploy.sh | |
| 121 | +| CPU / memory resources | deploy.sh | |
| 122 | +| DNS name label / FQDN | deploy.sh | |
| 123 | +| Container get / list | validate.sh | |
| 124 | +| Container logs | validate.sh | |
| 125 | +| Container exec | validate.sh | |
| 126 | +| Stop / Start / Restart | validate.sh | |
0 commit comments