Welcome to the Scaling Cloud course! This repository is your hands-on guide to building, containerizing, and scaling modern web applications using Docker, Azure Container Registry (ACR), Azure Container Apps, and Infrastructure as Code (IaC) with Bicep.
By the end of this course, you will be able to:
- Develop and containerize a web application using Docker.
- Securely push and manage container images in a private Azure Container Registry (ACR).
- Automate infrastructure deployment using Azure Bicep and GitHub Actions.
- Deploy and scale applications to Azure Container Apps.
- Manage traffic and high availability with Azure Traffic Manager.
This course is structured around the AKF Scale Cube, a model for analyzing and improving the scalability of products.
- X-Axis (Horizontal Duplication): Cloning the application and data behind a load balancer. We cover this in Lab 3 by running multiple replicas of our container.
- Y-Axis (Functional Decomposition): Splitting the application into smaller services/microservices. While our demo app is simple, containerization (Lab 1) is the first step towards this architecture.
- Z-Axis (Data Partitioning): Splitting data and customers, often by geography. Lab 4 and 5 explore this by using Azure Front Door to route traffic globally, laying the foundation for geo-partitioning.
Before we start, ensure you have the following accounts. Both offer free tiers perfect for this course.
- GitHub Account:
- Sign up for GitHub.
- This is where your code and workflows will live.
- Azure Account:
- Create a free Azure Account.
- Azure gives you $200 credit for the first 30 days and 12 months of popular free services.
We need a few CLI tools to interact with the cloud.
- Fork this Repository:
- Click the Fork button at the top right of this page.
- Why? This creates a complete copy of the project under your own GitHub account.
- Clone Your Fork:
- Download your new personal copy to your computer:
# Replace <your-username> with your GitHub username git clone git@github.com:<your-username>/scalecloud.git cd scalecloud
- Enable Github Workflows:
- Navigate to the
Actionstab in your forked repository and enable Github workflows.
- Navigate to the
We have provided a script to verify your local environment (Git, Docker) is ready for Lab 1 and Lab 2.
- Navigate to the
infrafolder:cd infra - Run the Local Setup Script:
- Mac/Linux:
./setup-local.sh
- Windows:
./setup-local.ps1
- Mac/Linux:
This script will check if you have the necessary tools installed. If anything is missing, it will let you know what to install (Docker, Git, VS Code).
If you are on multiple-user machine (like a school or work laptop) and cannot install the Azure CLI (az) or GitHub CLI (gh) because of admin restrictions, try one of these methods:
Option 1 (Recommended): Scoop Scoop is a command-line installer for Windows that installs programs to your user folder, bypassing admin requirements.
# 1. Install Scoop
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
# 2. Install Tools
scoop install gh
scoop install azure-cliOption 2: Manual "Portable" Install You can download "portable" ZIP versions of these tools, unzip them, and add them to your user path.
- Azure CLI: Download from Official MS Docs (ZIP).
- GitHub CLI: Download
..._windows_amd64.zipfrom GitHub Releases.
We use a setup script to configure the connection between GitHub and Azure. This is required for Lab 3, 4, and 5.
-
Prerequisites:
- Ensure you have Azure CLI and GitHub CLI installed.
- Login:
az login gh auth login
-
Configure your environment:
-
Edit /config.env: Review the
<changeme>environment variables in theconfig.envfile; the rest can be kept as-is.# 1. Azure Resource Settings RG_NAME="rg-scalingcloud-lab" # Resource Group Name LOCATION="swedencentral" # Azure Region ACR_NAME="<changeme>" # Registry Name (Must be globally unique!) # 2. GitHub Settings GH_ORG="<changeme>" # Your GitHub Username/Org GH_REPO="scalingcloud" # Your Repository Name GH_BRANCH="main" # Your Branch (usually main or master)
-
-
Run the Cloud Setup Script:
- Mac/Linux:
cd infra ./setup-cloud.sh - Windows:
cd infra .\setup-cloud.ps1
- Mac/Linux:
This script will automate the creation of Identities, Role Assignments, and Configuration.
If you cannot install tools locally, you can run the entire course directly in your browser using GitHub Codespaces.
- Start Codespace:
- Click the Code green button -> Codespaces -> Create codespace on main.
- This spins up a remote machine with Docker, Azure CLI, and GitHub CLI pre-installed (defined in
.devcontainer).
- Login inside Codespace:
- Open the terminal (Ctrl+`).
unset GITHUB_TOKEN(Crucial: Removes the default restricted token).az login(Follow the device code prompt).gh auth login(Select GitHub.com, SSH, and your key).
- Run Setup Scripts:
- Local Setup (for Lab 1/2):
cd infra && ./setup-local.sh - Cloud Setup (for Lab 3+):
cd infra && ./setup-cloud.sh
- Local Setup (for Lab 1/2):
If you prefer to understand what setup-cloud.sh does under the hood, or want to do it manually, here is the step-by-step process it performs:
- Verifies that
azandghCLIs are installed and logged in. - Loads variables from your
config.envfile.
- Creates an Azure Resource Group to hold all shared infrastructure (like the Container Registry).
- Infrastructure Identity: Creates an Azure User-Assigned Managed Identity. This identity is used by GitHub Actions to deploy infrastructure (Bicep).
- Role Assignment: Assigns the
Ownerrole to this identity on the Resource Group, allowing it to create and manage resources. - Federation: Establishes a trust relationship (OIDC) between the Identity and your GitHub repository's
mainbranch. This eliminates the need for storing passwords.
- Sets the following secrets in your GitHub repo:
AZURE_SUBSCRIPTION_IDAZURE_TENANT_IDAZURE_CLIENT_ID_INFRA(The ID of the identity we just created)
- Runs
main.bicepto deploy the Azure Container Registry and other core resources. - App Identities: The Bicep deployment creates separate identities for the Application (Push/Pull).
- App Secrets: The script fetches the
App Push IdentityClient ID and saves it asAZURE_CLIENT_IDin GitHub Secrets.
- Finally, it saves your configuration (Resource names, Location) as GitHub Variables so your workflows can reference them automatically.
If you cannot run the scripts or prefer to click through the Azure Portal and GitHub UI, follow these steps:
-
Create Resource Group:
- Go to Azure Portal -> Resource groups -> Create.
- Name it (e.g.,
rg-scalingcloud-shared) and select a region.
-
Create Managed Identity (Infra):
- Search for Managed Identities -> Create.
- Name:
id-github-infra. Resource Group:rg-scalingcloud-shared. - Assign Role: Go to your Resource Group -> Access control (IAM) -> Add role assignment.
- Role:
Owner. Assign to:Managed Identity-> Selectid-github-infra.
-
Federate Identity (OIDC):
- Go to the Managed Identity
id-github-infra-> Federated credentials -> Add credential. - Scenario: GitHub Actions deploying Azure resources.
- Organization:
your-github-username. Repository:scalecloud. Branch:main. - Name:
github-federation.
- Go to the Managed Identity
-
Create Container Registry:
- Search for Container registries -> Create.
- Name: Unique name (e.g.,
sodalabs001). Resource Group:rg-scalingcloud-shared. SKU:Basic.
-
Configure GitHub Secrets:
- Go to your GitHub Repo -> Settings -> Secrets and variables -> Actions.
- Add New repository secret:
AZURE_CLIENT_ID_INFRA: Client ID ofid-github-infra.AZURE_TENANT_ID: Tenant ID from Azure Active Directory.AZURE_SUBSCRIPTION_ID: Your Subscription ID.
-
Configure GitHub Variables:
- Go to Variables tab -> New repository variable.
- Add variables from your
config.env(e.g.,RG_NAME,ACR_NAME,LOCATION).
This repository uses GitHub Actions to automate "Lab" setups. Instead of manually clicking in the portal, you will run workflows that deploy infrastructure code (Bicep) for you.
CRITICAL: Push Lab 1 First! Labs 3, 4, and 5 depend on the container image from Lab 1. Before running any lab deployment:
- Navigate to
lab1/code. - Make a small change (or just push the folder).
- Ensure the
Build and push applicationworkflow runs successfully. Without this, your Azure Container Apps will fail to start because they cannot find the image.
The workflow Lab Bicep Deployment handles the infrastructure creation for Labs 3, 4, and 5.
- Navigate to the Actions tab in your GitHub repository.
- Select Lab Bicep Deployment from the left sidebar.
- Click Run workflow.
- Enter the Lab Number: In the input field (e.g.,
lab3,lab4), type the folder name of the lab you want to deploy. - Click the green Run workflow button.
Effect: This triggers a job that logs into Azure, creates a resource group (e.g., rg-scalingcloud-lab3), and deploys the resources defined in that lab's lab.bicep file.
When you make changes to the application code in lab1/:
- Push your changes to the
mainbranch. - The
Build and push applicationworkflow will automatically start. - It builds your Docker image, logs into ACR, and pushes the new version.
- Your compliant Azure Container Apps will pull the new image and update automatically.
Cloud resources cost money. Always tear down your labs when you are done.
- Go to Actions -> Delete Azure Resource Group.
- Run the workflow.
- This script finds all resource groups tagged with
Project=scalingCloudLaband deletes them.
Run the nuke script in your terminal to delete all lab groups instantly:
- Mac/Linux:
./infra/nuke.sh
- Windows:
./infra/nuke.ps1
(Or run manually via CLI commands below)
az group list --tag Project=scalingCloudLab --query "[].name" -o tsv | \
xargs -I {} az group delete --name {} --yes --no-waitHere is a quick overview of the most important files in this repository:
This folder contains the core setup for the course environment.
setup-local.sh/setup-local.ps1: Checks if your local environment (Git, Docker) is ready.setup-cloud.sh/setup-cloud.ps1: The "one-click" cloud setup script. It configures Azure Resources, Identities, and GitHub Secrets.config.env: The configuration file where you define your custom names (Registry name, Location, Resource Groups).main.bicep: The core Infrastructure-as-Code template. It deploys persistent shared resources like the Azure Container Registry (ACR) and Managed Identities.nuke.sh/nuke.ps1: A "clean slate" utility (Bash/PowerShell). WARNING: This script deletes all Resource Groups created by this course to stop costs.
Automation pipelines that run in GitHub Actions.
infra.yml: Automatically deploys changes to the core infrastructure (infra/main.bicep) when you push tomain.build-and-deploy-app.yml: Triggered by changes inlab1/. It builds the Docker image, pushes it to ACR, and updates the Container App.lab-bicep-deploy.yml: A manual workflow (Workflow Dispatch) used to deploy specific lab infrastructure (e.g., "Deploy Lab 3").tare-down-workflow.yml: A manual workflow to delete lab resource groups directly from GitHub.
lab1/: Contains the source code for the Node.js application and its Dockerfile.lab3/-lab5/: Contains the Bicep templates (lab.bicep) for advanced scaling scenarios (Replicas, Traffic Manager, Front Door).