This project demonstrates how to containerize a Python Flask application and deploy it to Azure using Infrastructure as Code (Bicep) and GitHub Actions.
First, I developed and tested the application locally:
# Build the container
docker build -t myapp .
# Run and test locally
docker run -p 5000:5000 myapp
# Test in browser: http://localhost:5000
After confirming the container works, I built the infrastructure in steps:
-
Created
main.bicep
with basic resource structure:- Key Vault
- Container Registry
- Web App
-
Developed individual module files in
/modules
:key-vault.bicep
: Stores ACR credentials securelycontainer-registry.bicep
: Hosts our container imagesweb-app.bicep
: Runs our containerized application
Created .github/workflows/workflow.yaml
with three main stages:
-
Infrastructure Deployment Stage
- Deploys all Bicep templates
- Creates/updates Azure resources
- Sets up RBAC permissions
-
Run Tests Stage
- Builds the Docker image
- Runs tests on the container
- Exits with error if tests fail
-
Container Build & Push Stage
- Builds the Docker image
- Tags with git SHA
- Pushes to Azure Container Registry
-
Web App Deployment Stage
- Pulls latest image from ACR
- Deploys to Azure Web App
- Updates container configuration
- Azure Subscription
- GitHub Account
- Docker Desktop
- Azure CLI
-
Fork/Clone the Repository
-
Update Parameters Replace all instances of
dkumlin
with your identifier in:// main.parameters.json { "keyVaultName": { "value": "yourname-kv" }, "containerRegistryName": { "value": "yourname-cr" }, "webAppName": { "value": "yourname-webapp" } }
-
Configure GitHub Secrets Add to your repository:
AZURE_CREDENTIALS
AZURE_SUBSCRIPTION
-
Update Workflow Variables In
.github/workflows/workflow.yaml
:env: KEY_VAULT_NAME_DEV: "yourname-kv" CONTAINER_REGISTRY_SERVER_URL_DEV: "yournamecr.azurecr.io" IMAGE_NAME_DEV: "yourname-app" WEB_APP: "yourname-webapp"
-
Deploy
- Push to main branch
- GitHub Actions will handle the deployment
├── .github/workflows/
│ └── workflow.yaml # CI/CD pipeline
├── modules/
│ ├── key-vault.bicep # Key Vault infrastructure
│ ├── container-registry.bicep # ACR infrastructure
│ └── web-app.bicep # Web App infrastructure
├── main.bicep # Main infrastructure template
├── main.parameters.json # Infrastructure parameters
└── Dockerfile # Container image definition
-
Resource Name Conflicts
- Ensure all resource names are unique
- Update parameters with your unique identifiers
-
Container Registry Access
- Verify Key Vault contains correct ACR credentials
- Check service principal has proper permissions
-
Web App Deployment
- Check container logs in Azure Portal
- Verify container image exists in ACR
- Confirm Web App configuration matches container
# Check container locally
docker build -t myapp .
docker run -p 5000:5000 myapp