Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/run-samples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,16 @@ jobs:
ACTIVATE_PRO: "1"
DNS_ADDRESS: "0"

- name: Install Azure Functions Core Tools
# Required for publishing function app samples to the emulator.
- name: Install lstk CLI
# Required by run-samples.sh to proxy Azure CLI calls to the emulator
# via `lstk az` (replaces the deprecated azlocal wrapper).
# https://github.com/localstack/lstk
run: |
MAX_RETRIES=3
DELAY=15
for i in $(seq 1 $MAX_RETRIES); do
echo "Attempt $i/$MAX_RETRIES..."
npm install -g azure-functions-core-tools@4 --unsafe-perm true && break
npm install -g @localstack/lstk && break
if [ "$i" -eq "$MAX_RETRIES" ]; then
echo "All $MAX_RETRIES attempts failed"
exit 1
Expand All @@ -191,6 +193,7 @@ jobs:
sleep $DELAY
DELAY=$((DELAY * 2))
done
command -v lstk

- name: Install MSSQL ODBC and Tools
# Required for the 'web-app-sql-database' sample which uses 'sqlcmd' to
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This repository contains comprehensive sample projects demonstrating how to deve
### Required Tools
- [Docker](https://docs.docker.com/get-docker/): Container runtime for LocalStack
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli): Azure command-line interface
- [azlocal CLI](https://azure.localstack.cloud/user-guides/sdks/az/): LocalStack Azure CLI wrapper
- [lstk CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/): LocalStack command-line interface (proxies the Azure CLI via `lstk az`)
- [jq](https://jqlang.org/): JSON processor for scripting

### Infrastructure as Code
Expand Down Expand Up @@ -79,12 +79,13 @@ Follow the comprehensive setup guide in [LocalStack for Azure Quick Start](./doc
## Documentation

- [LocalStack for Azure Documentation](https://docs.localstack.cloud/azure/)
- [Azure CLI with LocalStack](https://azure.localstack.cloud/user-guides/sdks/az/)
- [lstk CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/)
- [lstk GitHub repository](https://github.com/localstack/lstk)
- [Supported Azure Services](https://azure.localstack.cloud/references/coverage/)

## Contributing

Contributions are welcome! Please read our [Contributing Guidelines](CONTRIBUTING.md) before submitting pull requests.
Contributions are welcome!

1. Fork the repository
2. Create a feature branch
Expand Down
9 changes: 3 additions & 6 deletions docs/LOCALSTACK.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview
You can emulate selected Azure services locally using the LocalStack Azure Docker image. Before you begin, you must export a valid `LOCALSTACK_AUTH_TOKEN`, which unlocks Azure emulation features.
Refer to the LocalStack Auth Token documentation (e.g. the [Auth Token guide](https://docs.localstack.cloud/references/auth-token/)) to obtain your token and set it as an environment variable.
Refer to the LocalStack Auth Token documentation (e.g. the [Auth Token guide](https://docs.localstack.cloud/getting-started/auth-token/)) to obtain your token and set it as an environment variable.

## Prerequisites
- Docker installed and running
Expand Down Expand Up @@ -36,7 +36,7 @@ IMAGE_NAME=localstack/localstack-azure localstack start -d
localstack wait -t 60

# Route all Azure CLI calls to the LocalStack Azure emulator
azlocal start-interception
lstk az start-interception
```

This:
Expand Down Expand Up @@ -164,7 +164,4 @@ $Env:LOCALSTACK_AUTH_TOKEN = "<your_auth_token>"
- Explore available Azure service endpoints through the LocalStack documentation
- Script integration tests against `http://localhost:4566`
- Combine with Terraform / SDK clients pointing to the LocalStack endpoint

---

Let me know if you’d like an expanded example (e.g. adding a specific Azure service workflow or integrating with a dev container).
- Proxy the Azure CLI to the emulator with [`lstk az`](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/), or run `lstk az start-interception` to intercept all `az` calls (see the [lstk GitHub repository](https://github.com/localstack/lstk))
2 changes: 0 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ dependencies = [
"azure-core",
"python-dotenv",
"localstack",
"azlocal",
"terraform-local",
]

[project.optional-dependencies]
Expand Down
1 change: 0 additions & 1 deletion requirements-runtime.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ azure-mgmt-cosmosdb
azure-core
python-dotenv
localstack
azlocal
38 changes: 19 additions & 19 deletions run-samples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ set -euo pipefail
# Requirements:
# - Docker
# - Python 3.12+
# - .NET 9.0+
# - .NET 10.0+
# - Node.js & npm
# - Azure CLI (az)
# - LocalStack CLI
# - Terraform CLI
# - azlocal & terraform-local (pip install azlocal terraform-local)
# - Azure Functions Core Tools (func)
# - Azure Functions Core Tools (func)
# - lstk CLI (https://github.com/localstack/lstk)
# - jq & zip (sudo apt-get install jq zip)
# - MSSQL Tools (sqlcmd)
# - LOCALSTACK_AUTH_TOKEN environment variable
Expand Down Expand Up @@ -104,10 +102,8 @@ fi
# 3. Check for required tools
command -v localstack >/dev/null 2>&1 || { echo >&2 "localstack CLI is required but not installed. Aborting."; exit 1; }
command -v az >/dev/null 2>&1 || { echo >&2 "az CLI is required but not installed. Aborting."; exit 1; }
command -v azlocal >/dev/null 2>&1 || { echo >&2 "azlocal is required but not installed. Run 'pip install azlocal'. Aborting."; exit 1; }
#command -v tflocal >/dev/null 2>&1 || { echo >&2 "tflocal is required but not installed. Run 'pip install terraform-local'. Aborting."; exit 1; }
command -v lstk >/dev/null 2>&1 || { echo >&2 "lstk is required but not installed. See https://github.com/localstack/lstk#installation. Aborting."; exit 1; }
command -v terraform >/dev/null 2>&1 || { echo >&2 "terraform CLI is required but not installed. Aborting."; exit 1; }
command -v func >/dev/null 2>&1 || { echo >&2 "Azure Functions Core Tools (func) is required but not installed. Aborting."; exit 1; }

if [ -z "${LOCALSTACK_AUTH_TOKEN:-}" ]; then
echo "Error: LOCALSTACK_AUTH_TOKEN is not set. It is required for the Azure emulator."
Expand All @@ -129,17 +125,20 @@ if [ -n "${AZURE_CONFIG_DIR:-}" ]; then
mkdir -p "$AZURE_CONFIG_DIR"
fi

if command -v azlocal >/dev/null 2>&1; then
echo "[DEBUG] azlocal command found, attempting login..."
azlocal login || true
echo "[DEBUG] Starting azlocal interception..."
azlocal start-interception
if command -v lstk >/dev/null 2>&1; then
echo "[DEBUG] Starting lstk az interception..."
lstk az start-interception
# With interception active, the standard az CLI targets the emulator directly.
# The `lstk az` proxy is intentionally not used below: it requires a one-time
# Azure CLI integration setup that is not available on headless CI runners.
echo "[DEBUG] Logging in..."
az login --service-principal -u any-app -p any-pass --tenant any-tenant || true
echo "[DEBUG] Setting default subscription..."
azlocal account set --subscription "00000000-0000-0000-0000-000000000000" || true
echo "[DEBUG] Checking azlocal account status..."
azlocal account show --query "{Environment:environmentName, Subscription:id}" --output json 2>&1 || echo "[DEBUG] azlocal account show failed"
az account set --subscription "00000000-0000-0000-0000-000000000000" || true
echo "[DEBUG] Checking az account status..."
az account show --query "{Environment:environmentName, Subscription:id}" --output json 2>&1 || echo "[DEBUG] az account show failed"
else
echo "[DEBUG] azlocal not found, using standard az login with service principal..."
echo "[DEBUG] lstk not found, using standard az login with service principal..."
az login --service-principal -u any-app -p any-pass --tenant any-tenant || true
echo "[DEBUG] Checking az account status..."
az account show --query "{Environment:environmentName, Subscription:id}" --output json 2>&1 || echo "[DEBUG] az account show failed"
Expand Down Expand Up @@ -196,13 +195,14 @@ for (( i=START; i<START+COUNT; i++ )); do

# Clean up Azure resources to prevent state pollution between tests
echo "Cleaning up Azure resources in LocalStack..."
if command -v azlocal >/dev/null 2>&1; then
RG_LIST=$(azlocal group list --query "[].name" -o tsv 2>/dev/null || echo "")
if command -v lstk >/dev/null 2>&1; then
# Interception is active (started above), so plain az targets the emulator.
RG_LIST=$(az group list --query "[].name" -o tsv 2>/dev/null || echo "")
if [[ -n "$RG_LIST" ]]; then
echo "$RG_LIST" | while read -r rg; do
if [[ -n "$rg" ]]; then
echo " - Deleting resource group: $rg"
azlocal group delete --name "$rg" --yes --no-wait 2>/dev/null || true
az group delete --name "$rg" --yes --no-wait 2>/dev/null || true
fi
done
sleep 2
Expand Down
16 changes: 11 additions & 5 deletions samples/aci-blob-storage/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The following diagram illustrates the architecture of the solution:
- [LocalStack](https://docs.localstack.cloud/getting-started/installation/)
- [Docker](https://docs.docker.com/get-docker/)
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli)
- [azlocal](https://pypi.org/project/azlocal/) (`pip install azlocal`)
- [lstk](https://github.com/localstack/lstk) (`brew install localstack/tap/lstk` or `npm install -g @localstack/lstk`)
- [Terraform](https://developer.hashicorp.com/terraform/downloads) (optional, for Terraform deployment)

## Quick Start
Expand All @@ -32,10 +32,10 @@ IMAGE_NAME=localstack/localstack-azure localstack start -d
localstack wait -t 60

# Route all Azure CLI calls to the LocalStack Azure emulator
azlocal start-interception
lstk az start-interception

# Deploy all services
cd python
cd samples/aci-blob-storage/python
bash scripts/deploy.sh

# Validate the deployment (includes stop/start/restart lifecycle tests)
Expand All @@ -47,14 +47,14 @@ bash scripts/validate.sh
### Bicep

```bash
cd python
cd samples/aci-blob-storage/python
bash bicep/deploy.sh
```

### Terraform

```bash
cd python
cd samples/aci-blob-storage/python
bash terraform/deploy.sh
```

Expand Down Expand Up @@ -111,3 +111,9 @@ The Vacation Planner is a Flask web application with a Bootstrap UI that lets us
| Container logs | validate.sh |
| Container exec | validate.sh |
| Stop / Start / Restart | validate.sh |

## References

- [LocalStack for Azure Documentation](https://docs.localstack.cloud/azure/)
- [lstk CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/)
- [lstk GitHub repository](https://github.com/localstack/lstk)
8 changes: 5 additions & 3 deletions samples/aci-blob-storage/python/bicep/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ This directory contains the Bicep template and a deployment script for provision
- [Docker](https://docs.docker.com/get-docker/): Container runtime required for LocalStack
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli): Azure command-line interface
- [Bicep extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-bicep): VS Code extension for Bicep language support
- [azlocal CLI](https://azure.localstack.cloud/user-guides/sdks/az/): LocalStack Azure CLI wrapper
- [lstk CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/): LocalStack command-line interface (proxies the Azure CLI via `lstk az`)
- [jq](https://jqlang.org/): JSON processor for scripting

### Installing azlocal CLI
### Installing lstk CLI

```bash
pip install azlocal
brew install localstack/tap/lstk # or: npm install -g @localstack/lstk
```

## Architecture Overview
Expand Down Expand Up @@ -60,3 +60,5 @@ bash scripts/cleanup.sh
- [Azure Bicep Documentation](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/)
- [Bicep Language Reference](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions)
- [LocalStack for Azure Documentation](https://docs.localstack.cloud/azure/)
- [lstk CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/)
- [lstk GitHub repository](https://github.com/localstack/lstk)
10 changes: 6 additions & 4 deletions samples/aci-blob-storage/python/scripts/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# Azure CLI Deployment

This directory includes Bash scripts for deploying and testing the ACI Vacation Planner sample using the `azlocal` CLI. Refer to the [ACI Blob Storage](../README.md) guide for details about the sample application.
This directory includes Bash scripts for deploying and testing the ACI Vacation Planner sample using the `lstk` CLI. Refer to the [ACI Blob Storage](../README.md) guide for details about the sample application.

## Prerequisites

- [LocalStack for Azure](https://docs.localstack.cloud/azure/): Local Azure cloud emulator for development and testing
- [Docker](https://docs.docker.com/get-docker/): Container runtime required for LocalStack
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli): Azure command-line interface
- [azlocal CLI](https://azure.localstack.cloud/user-guides/sdks/az/): LocalStack Azure CLI wrapper
- [lstk CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/): LocalStack command-line interface (proxies the Azure CLI via `lstk az`)

### Installing azlocal CLI
### Installing lstk CLI

```bash
pip install azlocal
brew install localstack/tap/lstk # or: npm install -g @localstack/lstk
```

## Architecture Overview
Expand Down Expand Up @@ -49,3 +49,5 @@ bash scripts/cleanup.sh

- [Azure CLI Documentation](https://docs.microsoft.com/en-us/cli/azure/)
- [LocalStack for Azure Documentation](https://docs.localstack.cloud/azure/)
- [lstk CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/)
- [lstk GitHub repository](https://github.com/localstack/lstk)
8 changes: 5 additions & 3 deletions samples/aci-blob-storage/python/terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ This directory contains Terraform modules and a deployment script for provisioni
- [Terraform](https://developer.hashicorp.com/terraform/downloads): Infrastructure as Code tool
- [Docker](https://docs.docker.com/get-docker/): Container runtime required for LocalStack
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli): Azure command-line interface
- [azlocal CLI](https://azure.localstack.cloud/user-guides/sdks/az/): LocalStack Azure CLI wrapper
- [lstk CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/): LocalStack command-line interface (proxies the Azure CLI via `lstk az`)

### Installing azlocal CLI
### Installing lstk CLI

```bash
pip install azlocal
brew install localstack/tap/lstk # or: npm install -g @localstack/lstk
```

## Architecture Overview
Expand Down Expand Up @@ -67,3 +67,5 @@ rm -rf .terraform terraform.tfstate terraform.tfstate.backup .terraform.lock.hcl

- [Terraform Azure Provider](https://registry.terraform.io/providers/hashicorp/azurerm/latest)
- [LocalStack for Azure Documentation](https://docs.localstack.cloud/azure/)
- [lstk CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/)
- [lstk GitHub repository](https://github.com/localstack/lstk)
10 changes: 9 additions & 1 deletion samples/aci-blob-storage/python/terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ resource "azurerm_resource_group" "example" {
name = local.resource_group_name
location = var.location
tags = var.tags

lifecycle {
# deploy.sh pre-creates this resource group with `az group create` (untagged) and
# imports it into the Terraform state. Ignoring tag drift avoids an in-place
# resource-group update on the next apply, which azurerm >= 4.x issues as a PATCH
# request that the LocalStack Azure emulator does not implement yet.
ignore_changes = [tags]
}
}

# Create a storage account
Expand Down Expand Up @@ -48,7 +56,7 @@ resource "azurerm_key_vault" "example" {
location = azurerm_resource_group.example.location
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
enable_rbac_authorization = true
rbac_authorization_enabled = true
tags = var.tags

lifecycle {
Expand Down
2 changes: 1 addition & 1 deletion samples/aci-blob-storage/python/terraform/providers.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=4.14.0"
version = "=4.81.0"
}
}
}
Expand Down
Loading