This repository contains comprehensive sample projects demonstrating how to develop and test Azure cloud applications locally using LocalStack for Azure. Each sample provides complete infrastructure-as-code templates, application code, and deployment instructions for seamless local development.
Note
Azure Kubernetes Service (AKS) samples and tutorials live in a separate repository, localstack-samples/aks-samples. It covers cluster provisioning, application deployments backed by Azure data services, and standalone walkthroughs of individual AKS capabilities such as network policies, KEDA autoscaling, the Gateway API, and the Key Vault CSI driver. Everything there runs unchanged against both Azure and the emulator.
- Docker: Container runtime for LocalStack
- Azure CLI: Azure command-line interface
- lstk CLI: LocalStack command-line interface (proxies the Azure CLI via
lstk az) - jq: JSON processor for scripting
- Azure Storage Explorer: GUI for Azure Storage
- Azure Functions Core Tools: Local function development
Each sample is a self-contained project with its own README, Azure CLI scripts and, where applicable, Bicep and Terraform deployments that target both real Azure and the LocalStack for Azure emulator. The language of each implementation is shown in parentheses; the web-app samples share the same Vacation Planner application and come in a Python (Flask) and a .NET 10 (ASP.NET Core Razor Pages) version.
| Sample | Description |
|---|---|
| Function App with Storage (.NET) | A gaming scoreboard built on Azure Functions (isolated worker): HTTP triggers record player scores in Table Storage, publish messages to Queue Storage and write game-session summaries to Blob Storage, all against the emulated storage account. |
| Function App with Front Door (Python) | Two Python Function Apps serving a small Catalog API, published through an Azure Front Door (Standard) endpoint: the edge picks an origin by priority, matches the more specific of two routes, caches what the origin allows, and runs a rule set that stamps a response header, rewrites /shop to /catalog and redirects a retired path without calling the origin at all. |
| API Management with Function App (Python) | A Python Function App serving a small Inventory API, published through an Azure API Management (Consumption) gateway: clients present a product-scoped subscription key, and the API policy injects a shared secret from a secret named value, enforces a rate limit, strips the key and answers CORS preflights before the request reaches the function; deployable with Azure CLI scripts, Terraform and Bicep. |
| Function App with Managed Identities (Python) | A serverless text processor: an Azure Functions app reads text blobs from an input container, converts them to uppercase and writes the result to an output container, authenticating to the storage account with a managed identity instead of keys. |
| Function App with Service Bus (.NET) | An Azure Functions app on an App Service plan that exchanges messages through Service Bus queues: an HTTP trigger sends greetings and a queue trigger consumes them, connecting with either a connection string or a managed identity. |
| Web App with Cosmos DB for MongoDB API (Python, .NET) | The Vacation Planner single-page web app on an Azure Web App with regional VNet integration, storing activities in the activities collection of an Azure Cosmos DB for MongoDB account reached through a private endpoint. |
| Web App with CosmosDB for NoSQL API (Python, .NET) | The Vacation Planner single-page web app on an Azure Web App, storing activities as JSON items in the activities container of an Azure Cosmos DB for NoSQL database partitioned by user; deployed with Azure CLI scripts. |
| Web App with Managed Identities (Python, .NET) | The Vacation Planner single-page web app on an Azure Web App, storing each activity as a blob in an activities container and accessing Blob Storage through a user-assigned or system-assigned managed identity rather than connection strings. |
| Web App with SQL Database (Python, .NET) | The Vacation Planner single-page web app on an Azure Web App, storing activities in an Azure SQL Database. The connection string and the HTTPS certificate are read from Azure Key Vault, and an API endpoint verifies the Key Vault certificate. |
| Web App with PostgreSQL Database (Python, .NET) | The Vacation Planner single-page web app on an Azure Web App, storing activities in an Azure Database for PostgreSQL flexible server injected into a virtual network (delegated subnet and private DNS zone), with the database and application user created by the deploy scripts. |
| Web App with App Configuration and Key Vault (Python, .NET) | The Vacation Planner single-page web app on an Azure Web App, storing activities in an Azure Database for PostgreSQL flexible server and reading its connection settings from an Azure App Configuration store whose secrets are Key Vault references, authenticating to both stores with a user-assigned managed identity through private endpoints. |
| Web App with MySQL Database (Python, .NET) | The Vacation Planner single-page web app on an Azure Web App, storing activities in an Azure Database for MySQL flexible server injected into a virtual network, using TLS-only connections, with the database and application user created by the deploy scripts. |
| Web App with Custom Docker Image (Python, .NET) | A web app that runs a custom container image built locally and pushed to Azure Container Registry; the web app pulls it with a managed identity (AcrPull) through a VNet-integrated network and reports its image and host name on /api/status. |
| ACI with Blob Storage (Python) | A containerized Flask web app on Azure Container Instances, with its image in Azure Container Registry, its secrets in Key Vault and its data in Blob Storage. |
| Container Apps with Blob Storage (Python) | A guestbook web app on Azure Container Apps pulled from Azure Container Registry that persists entries in Blob Storage and exercises secrets, revisions, replicas and scale rules. |
| Azure Service Bus with Spring Boot (Java) | A Java Spring Boot application that sends and receives Service Bus messages through the Spring Cloud Azure Service Bus Stream Binder. |
| URL Shortener (Python) | Linklet, a Flask URL shortener on an Azure Web App with an event-driven Azure Functions worker, composing Web App, Functions, Storage, Key Vault, Service Bus and PostgreSQL into a single causal chain. |
| Event Hubs Fraud Detection Pipeline (Python) | A streaming platform in miniature: payments ingested into Event Hubs over AMQP, Kafka and HTTPS, validated against Schema Registry, archived with Capture, scored by an Event Hubs-triggered Function App and shown on a Web App dashboard, with secrets in Key Vault. |
| Event Hubs Cold-Path Automation (Python) | A cold-chain monitoring pipeline in which Event Hubs Capture raises Microsoft.EventHub.CaptureFileCreated events to an Event Grid system topic; a subscription delivers them into a second event hub and an Event Hubs-triggered Function App decodes each Avro archive into per-device summaries. |
Each sample project is organized by Azure service and includes:
- Infrastructure templates (Bicep/Terraform) and/or Bash installation scripts.
- Application code with best practices
- Step-by-step deployment guides and tutorials.
- Optionally, testing and validation scripts.
To validate all samples locally, you can run the same test suite used in the CI. This script will start LocalStack, configure the Azure CLI cloud profile, and execute the deployment and test scripts for each sample.
cd localstack-azure-samples
# Set your LOCALSTACK_AUTH_TOKEN
export LOCALSTACK_AUTH_TOKEN=<your-token>
# Or create a .env file:
# echo "LOCALSTACK_AUTH_TOKEN=<your-token>" > .env
./run-samples.shSome samples run natively on arm64 (Apple Silicon, arm64 CI runners); the rest depend on
container images Microsoft publishes for amd64 alone, so there is no arm64 image to pull.
| Sample | Native amd64 | Native arm64 | Backing image |
|---|---|---|---|
function-app-* |
✅ | ✅ | built from a multi-arch python / node / dotnet base |
api-management-function-app |
✅ | ✅ | the API Management gateway runs inside the emulator; its Function App backend is built from the multi-arch python base |
web-app-custom-image |
✅ | ✅ | the image the sample builds itself |
aci-blob-storage |
✅ | ✅ | the image the sample builds itself |
container-apps-blob-storage |
✅ | ✅ | the image the sample builds itself |
web-app-* (code deployment) |
✅ | emulated | mcr.microsoft.com/oryx/<platform> |
eventhubs |
✅ | emulated | deploys a dashboard web app (Oryx, as above) |
servicebus/java |
✅ | emulated | mcr.microsoft.com/azure-app-service/java |
web-app-sql-database |
✅ | emulated | mcr.microsoft.com/mssql/server |
"emulated" does not mean broken. The emulator never pins --platform, so on an arm64 host
Docker pulls the amd64 image and runs it under whatever emulation the runtime provides. Docker
Desktop on Apple Silicon does this via Rosetta, so these samples do work on a Mac — just more
slowly. They fail only on an arm64 host with no emulation registered, such as GitHub's
ubuntu-*-arm runners, which is why CI schedules only the natively-supported samples on arm64.
run-samples.sh warns when it runs one of these on an arm64 host; set SKIP_AMD64_ONLY=1 to skip
them instead. The authoritative list lives in ARM64_SAMPLE_DIRS in run-samples.sh;
the CI matrix is generated from it, so adding a sample there is all that is needed to have it
covered natively on both architectures.
Note: Function Apps on
arm64were fixed by localstack-pro#8102 and work on the currentlocalstack/localstack-azure:latest. If you pin an older emulator image, expect every Function App deployment to fail with a misleading500 ... No route to host: those images unpackamd64Azure Functions Core Tools into anarm64image, so the host process cannot run.
If you encounter errors like invalid option name or : command not found when running on Linux/WSL, it's likely due to Windows-style line endings (CRLF). You can fix this by running:
find . -name "*.sh" -exec sed -i 's/\r$//' {} +Or by installing and using dos2unix.
The scripts are written for Bash and run unchanged on Linux, macOS and WSL. They also run on Windows from Git Bash or from an MSYS2 shell (for example MINGW64 or UCRT64), provided you first turn off the automatic path conversion of these shells and make them drop the carriage returns Windows programs print:
export MSYS_NO_PATHCONV=1
set -o igncr
export SHELLOPTSWhen Git Bash or an MSYS2 shell starts a Windows program such as the Azure CLI, it rewrites every argument that looks like an absolute POSIX path into a Windows path. Azure values that only look like paths are rewritten too, and the commands that receive them fail:
--partition-key-path /usernamereachesazasC:/Program Files/Git/username, so creating the Cosmos DB container fails with an invalid partition key path error.- Resource IDs such as
/subscriptions/<subscription-id>/resourceGroups/..., passed to--scope,--idsand similar options, become paths under the shell's installation folder, for exampleC:/Program Files/Git/subscriptions/.... - Paths such as the Front Door
--origin-path /apiare rewritten the same way.
With MSYS_NO_PATHCONV=1 set, these values reach the Azure CLI exactly as written.
The scripts convert the paths of the local files they hand to Windows programs, such as the temporary files read by curl and jq, with cygpath when it is available, so they keep working with the variable set.
They also hand curl the Windows NUL device instead of /dev/null for the responses they discard, because the variable stops these shells from making that conversion too.
On Linux and macOS cygpath does not exist, and the paths are left unchanged.
Windows programs such as the Azure CLI and jq also end every line they print with a carriage return, which Bash keeps when a script captures their output with $(...) or read.
A name or an ID read from az ... --output tsv then carries an invisible \r, and the next command that receives it fails, for example with ResourceNotFound for a resource that exists.
set -o igncr makes these shells drop carriage returns from $(...) and read, and export SHELLOPTS passes the option on to the scripts you start.
mapfile keeps them even then, so the scripts that fill an array from the Azure CLI strip them with tr -d '\r'.
Tips:
- To apply these settings in every new Git Bash window, add the three lines to
~/.bash_profile, or to~/.bashrcif your.bash_profilesources it. echo $MSYSTEMprints a value such asMINGW64only in these shells.- Any value turns the conversion off,
0included; rununset MSYS_NO_PATHCONVto turn it back on, andset +o igncrto keep carriage returns again. - WSL runs Linux and needs none of these settings.
- When you write a script that passes a local file to
az,curl,jq,python,dockerorzip, convert its path with thenative_pathhelper the existing scripts define; Git Bash ships nozip, and azip.exebuilt for Windows needs the converted path too. - To discard what a Windows program writes to a file, such as
curl -o, pass it"$(null_device)"rather than/dev/null, as the existing scripts do. Shell redirections such as> /dev/nullneed no change. - A launcher written as a shell script that hands its own paths to a Windows program, such as Maven's
mvn, needs the conversion: run it as(unset MSYS_NO_PATHCONV; mvn ...), as the Service Bus sample does. Setting the variable to an empty value is not enough, because any value turns the conversion off.
Follow the comprehensive setup guide in LocalStack for Azure Quick Start to configure your LocalStack for Azure development environment.
Contributions are welcome!
- Fork the repository
- Create a feature branch
- Add your sample with complete documentation
- Submit a pull request
This project is licensed under the MIT LICENSE.
- Issues: GitHub Issues
- LocalStack Support: Support Portal
- Community: LocalStack Discuss
Please give a ⭐ to this repository, if you find these samples helpful for your Azure local development workflow!