From 7598fbe86b475b9e359dc33344a75f6ce1679d68 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 6 Jan 2026 13:33:57 +0000 Subject: [PATCH 01/42] Test CI pipeline on feature branch --- .gitattributes | 4 + .github/workflows/run-samples.yml | 166 ++++++++++++++++++ README.md | 28 +++ cleanup.sh | 38 ++++ run-samples.sh | 87 +++++++++ .../python/scripts/.last_deploy_all.env | 10 ++ ...azure-storage-explorer.png:Zone.Identifier | Bin 25 -> 0 bytes 7 files changed, 333 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/workflows/run-samples.yml create mode 100644 cleanup.sh create mode 100644 run-samples.sh create mode 100644 samples/function-app-front-door/python/scripts/.last_deploy_all.env delete mode 100644 samples/function-app-managed-identity/python/images/azure-storage-explorer.png:Zone.Identifier diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e3e2de9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.sh text eol=lf +*.yml text eol=lf +*.bicep text eol=lf +*.tf text eol=lf diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml new file mode 100644 index 0000000..0b859ab --- /dev/null +++ b/.github/workflows/run-samples.yml @@ -0,0 +1,166 @@ +name: Samples CI + +# Control how many workflows can run at the same time. +# This ensures that only one pull request triggered run is executed at a time, +# saving resources and avoiding potential race conditions in the CI environment. +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +on: + push: + branches: [ '**' ] + pull_request: + branches: [ main ] + workflow_dispatch: + +# Centralized environment variables for consistency across the workflow. +env: + IMAGE_NAME: "localstack/localstack-azure-alpha" + DEFAULT_TAG: "latest" + # Check whether the current job was kicked off by a pull request. + IS_PR: ${{ github.event_name == 'pull_request' }} + +jobs: + scripts: + # Use sharding to parallelize the test execution. + # This divides the total number of samples into multiple parallel jobs, + # significantly reducing the total time taken for the CI to complete. + name: "Run Test Scripts (amd64) — Part ${{ matrix.shard }} of ${{ matrix.splits }}" + strategy: + fail-fast: false + matrix: + shard: [1, 2] + splits: [2] + runs-on: ubuntu-latest + + # Environment variables specific to the LocalStack emulator and Azure CLI. + env: + LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} + # Required for Microsoft SQL Server emulator to accept the license agreement. + DOCKER_FLAGS: "-e MSSQL_ACCEPT_EULA=Y" + # Bypassing strict SSL verification for LocalStack's self-signed certificates. + # This is critical for .NET tools like the Azure Functions Core Tools. + PERMIT_ALL_CERTIFICATES: "true" + AZURE_CLI_DISABLE_CONNECTION_VERIFICATION: "1" + # Use DNS_ADDRESS=0 to avoid DNS resolution issues in the detached container. + DNS_ADDRESS: "0" + + steps: + - name: Checkout repo + # clones the repository into the runner's workspace. + uses: actions/checkout@v4 + + - name: Set up Python + # Installs the Python runtime. Version 3.12 is chosen for compatibility with the samples. + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Set up .NET + # Installs the .NET SDK. Version 9.0 is required for the C# based samples. + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0' + + - name: Login to Docker Hub + # Logging into Docker Hub helps avoid rate limiting issues when pulling images. + # This requires DOCKERHUB_PULL_USERNAME and DOCKERHUB_PULL_TOKEN secrets to be set. + # If not set, it will attempt to pull images anonymously. + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_PULL_USERNAME }} + password: ${{ secrets.DOCKERHUB_PULL_TOKEN }} + continue-on-error: true + + - name: Free up disk space + # Deletes unused Docker images and build caches to ensure enough space for the emulator. + run: | + docker system prune -af --volumes + docker builder prune -af + + - name: Install dependencies + # Installs the required CLI tools and libraries. + run: | + pip install localstack azlocal funclocal + sudo apt-get install -y jq zip + + - name: Install Azure Functions Core Tools + # Specifically installs 'func' version 4, which is required for publishing Function Apps to the emulator. + run: | + curl https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor -o /usr/share/keyrings/microsoft-archive-keyring.gpg + echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-ubuntu-$(lsb_release -rs)-prod $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/dotnetdev.list + sudo apt-get update + sudo apt-get install azure-functions-core-tools-4 + + - name: Install MSSQL ODBC dependencies + # One of the samples uses Azure SQL Database. These dependencies provide 'sqlcmd', + # which is used to initialize the database schema and seed data. + run: | + curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc + curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list + sudo apt-get update + sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 mssql-tools18 + echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc + # Make tools available for the current shell session. + echo "/opt/mssql-tools18/bin" >> $GITHUB_PATH + + - name: Start LocalStack + # Launches the LocalStack Azure emulator in detached mode. + run: | + IMAGE_NAME=${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }} localstack start -d + localstack wait -t 60 + + - name: Run Test Scripts + # Iterates through the sample projects and executes their deployment and test scripts. + run: | + # Define the list of samples to test. Format: path | deploy_command | test_command + SAMPLES=( + "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" + "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/test.sh" + "samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" + "samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" + "samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" + "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" + ) + + TOTAL=${#SAMPLES[@]} + SHARD=${{ matrix.shard }} + SPLITS=${{ matrix.splits }} + + # Calculate the range of samples for this specific shard. + COUNT=$(( TOTAL / SPLITS )) + START=$(( (SHARD - 1) * COUNT )) + + if [ "$SHARD" -eq "$SPLITS" ]; then + COUNT=$(( TOTAL - START )) + fi + + echo "Running samples from index $START, count $COUNT" + + for (( i=START; i + +# Or create a .env file: +# echo "LOCALSTACK_AUTH_TOKEN=" > .env + +./run-samples.sh +``` + +## Cleanup + +To stop LocalStack and all associated containers, and revert your Azure CLI configuration, run: +```bash +./cleanup.sh +``` + +### Troubleshooting: Line Endings +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: +```bash +find . -name "*.sh" -exec sed -i 's/\r$//' {} + +``` +Or by installing and using `dos2unix`. + ## Configuration Follow the comprehensive setup guide in [LocalStack for Azure Quick Start](./docs/LOCALSTACK.md) to configure your LocalStack for Azure development environment. diff --git a/cleanup.sh b/cleanup.sh new file mode 100644 index 0000000..c8bc12b --- /dev/null +++ b/cleanup.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +set -uo pipefail + +# Cleanup script to stop and remove LocalStack containers and revert CLI configurations. + +echo "Stopping LocalStack..." +localstack stop || true + +echo "Killing any lingering LocalStack-related containers..." +# Kill the main container if it didn't stop +docker stop localstack-main >/dev/null 2>&1 || true +docker rm localstack-main >/dev/null 2>&1 || true + +# Kill any containers started by LocalStack (e.g., function app sidecars) +# These usually have labels or specific naming conventions, but a safe bet is to look for those with localstack in the name or created by the localstack network +CONTAINERS=$(docker ps -a --filter "name=localstack" --filter "name=ls-" -q) +if [ -n "$CONTAINERS" ]; then + echo "Stopping sidecar containers..." + docker stop $CONTAINERS >/dev/null 2>&1 || true + docker rm $CONTAINERS >/dev/null 2>&1 || true +fi + +echo "Cleaning up Docker networks..." +docker network prune -f >/dev/null 2>&1 || true + +echo "Reverting Azure CLI configuration..." +# Switch back to AzureCloud if LocalStack was the current cloud +CURRENT_CLOUD=$(az cloud show --query name -o tsv 2>/dev/null || echo "") +if [ "$CURRENT_CLOUD" == "LocalStack" ]; then + az cloud set -n AzureCloud --only-show-errors || true +fi + +# Optionally unregister the LocalStack cloud +# az cloud unregister -n LocalStack --only-show-errors || true + +echo "Cleanup complete!" +echo "Note: LocalStack persistent data in ~/.localstack/volume was NOT removed." +echo "To remove it, run: rm -rf ~/.localstack/volume" diff --git a/run-samples.sh b/run-samples.sh new file mode 100644 index 0000000..58ef717 --- /dev/null +++ b/run-samples.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Helper script to run all sample tests locally, replicating the CI environment. +# Requirements: +# - Docker +# - Python 3.12+ +# - .NET 9.0+ +# - Azure CLI +# - azlocal (pip install azlocal) +# - funclocal (pip install funclocal) +# - Azure Functions Core Tools (func) +# - LOCALSTACK_AUTH_TOKEN environment variable + +# 0. Load environment variables from .env file if it exists +if [ -f .env ]; then + echo "Loading environment variables from .env file..." + # Use a subshell to avoid exporting everything if not needed, + # but here we actually want them in the environment. + set -a + source .env + set +a +fi + +# 1. 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 funclocal >/dev/null 2>&1 || { echo >&2 "funclocal is required but not installed. Run 'pip install funclocal'. 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." + exit 1 +fi + +# 1. Start LocalStack +echo "Starting LocalStack Azure emulator..." +IMAGE_NAME=localstack/localstack-azure-alpha localstack start -d +localstack wait -t 60 + +# 2. Register LocalStack Cloud in az CLI +#echo "Registering LocalStack cloud profile..." +#az cloud register -n LocalStack \ +# --endpoint-resource-manager "http://localhost:4566" \ +# --suffix-storage-endpoint "localhost.localstack.cloud" \ +# --suffix-keyvault-dns ".localhost.localstack.cloud" \ +# --endpoint-active-directory "http://localhost:4566" \ +# --endpoint-gallery "http://localhost:4566" \ +# --endpoint-management "http://localhost:4566" || true + +#az cloud set -n LocalStack +#az login --service-principal -u "ignored" -p "ignored" --tenant "ignored" --allow-no-subscriptions || true + +# 3. Define Samples +SAMPLES=( + "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" + "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/test.sh" + "samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" + "samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" + "samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" + "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" +) + +# 4. Run Samples +for item in "${SAMPLES[@]}"; do + IFS='|' read -r path deploy test <<< "$item" + echo "============================================================" + echo "Testing Sample: $path" + echo "============================================================" + + pushd "$path" > /dev/null + + echo "Deploying..." + eval "$deploy" + + if [ -n "$test" ]; then + echo "Testing..." + eval "$test" + fi + + popd > /dev/null + echo "Completed: $path" + echo "" +done + +echo "All samples completed successfully!" diff --git a/samples/function-app-front-door/python/scripts/.last_deploy_all.env b/samples/function-app-front-door/python/scripts/.last_deploy_all.env new file mode 100644 index 0000000..30b0f6d --- /dev/null +++ b/samples/function-app-front-door/python/scripts/.last_deploy_all.env @@ -0,0 +1,10 @@ +RESOURCE_GROUP="rg-mydemo-01950" +PROFILE_NAME="afd-mydemo-01950" +EP_BASIC="ep-mydemo-basic-01950" +EP_MULTI="ep-mydemo-multi-01950" +EP_SPEC="ep-mydemo-spec-01950" +EP_RULES="ep-mydemo-rules-01950" +EP_STATE="ep-mydemo-state-01950" +FUNC_MAIN="fa-mydemo-01950" +FUNC_A="fa-mydemoa-01950" +FUNC_B="fa-mydemob-01950" diff --git a/samples/function-app-managed-identity/python/images/azure-storage-explorer.png:Zone.Identifier b/samples/function-app-managed-identity/python/images/azure-storage-explorer.png:Zone.Identifier deleted file mode 100644 index d6c1ec682968c796b9f5e9e080cc6f674b57c766..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2x Date: Tue, 6 Jan 2026 14:08:28 +0000 Subject: [PATCH 02/42] added correct environment --- .github/workflows/run-samples.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 0b859ab..9e1304a 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -27,6 +27,7 @@ jobs: # This divides the total number of samples into multiple parallel jobs, # significantly reducing the total time taken for the CI to complete. name: "Run Test Scripts (amd64) — Part ${{ matrix.shard }} of ${{ matrix.splits }}" + environment: AZURE strategy: fail-fast: false matrix: @@ -66,12 +67,10 @@ jobs: - name: Login to Docker Hub # Logging into Docker Hub helps avoid rate limiting issues when pulling images. # This requires DOCKERHUB_PULL_USERNAME and DOCKERHUB_PULL_TOKEN secrets to be set. - # If not set, it will attempt to pull images anonymously. uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_PULL_USERNAME }} password: ${{ secrets.DOCKERHUB_PULL_TOKEN }} - continue-on-error: true - name: Free up disk space # Deletes unused Docker images and build caches to ensure enough space for the emulator. From 2da99640a4e91aa30375b10fb4414b2328891e9d Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 6 Jan 2026 14:29:36 +0000 Subject: [PATCH 03/42] added dependencies 1 --- .github/workflows/run-samples.yml | 153 ++++++++++++++++++++---------- run-samples.sh | 8 +- 2 files changed, 110 insertions(+), 51 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 9e1304a..ae12a90 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -1,32 +1,30 @@ name: Samples CI -# Control how many workflows can run at the same time. -# This ensures that only one pull request triggered run is executed at a time, -# saving resources and avoiding potential race conditions in the CI environment. +# Theory of Operation: +# This workflow automates the testing of Azure sample applications against the LocalStack Azure emulator. +# It replicates a production-grade CI environment by: +# 1. Setting up multiple runtimes (Python, .NET) required by different samples. +# 2. Installing the full Azure toolchain (Azure CLI, Functions Core Tools, MSSQL tools). +# 3. Configuring the Azure CLI to redirect all traffic to LocalStack (Cloud Registration). +# 4. Bypassing SSL restrictions to allow seamless communication with self-signed certificates. +# 5. Using a matrix strategy (sharding) to run tests in parallel, saving time. + concurrency: + # Prevents multiple runs of the same workflow on the same branch from overlapping. group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true on: push: - branches: [ '**' ] + branches: [ '**' ] # Trigger on all branches for testing pull_request: branches: [ main ] workflow_dispatch: -# Centralized environment variables for consistency across the workflow. -env: - IMAGE_NAME: "localstack/localstack-azure-alpha" - DEFAULT_TAG: "latest" - # Check whether the current job was kicked off by a pull request. - IS_PR: ${{ github.event_name == 'pull_request' }} - jobs: scripts: - # Use sharding to parallelize the test execution. - # This divides the total number of samples into multiple parallel jobs, - # significantly reducing the total time taken for the CI to complete. name: "Run Test Scripts (amd64) — Part ${{ matrix.shard }} of ${{ matrix.splits }}" + # Use the AZURE environment to access secrets like TEST_LOCALSTACK_AUTH_TOKEN environment: AZURE strategy: fail-fast: false @@ -35,85 +33,142 @@ jobs: splits: [2] runs-on: ubuntu-latest - # Environment variables specific to the LocalStack emulator and Azure CLI. env: + # Secrets and core configuration LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} - # Required for Microsoft SQL Server emulator to accept the license agreement. DOCKER_FLAGS: "-e MSSQL_ACCEPT_EULA=Y" - # Bypassing strict SSL verification for LocalStack's self-signed certificates. - # This is critical for .NET tools like the Azure Functions Core Tools. + + # SSL and Networking Robustness + # Tell .NET and Azure CLI to trust LocalStack's self-signed certificates. PERMIT_ALL_CERTIFICATES: "true" AZURE_CLI_DISABLE_CONNECTION_VERIFICATION: "1" - # Use DNS_ADDRESS=0 to avoid DNS resolution issues in the detached container. + # Prevent LocalStack from trying to hijack host DNS, which can be unstable in CI. DNS_ADDRESS: "0" + + # Emulation endpoints + LOCALSTACK_HOSTNAME: "127.0.0.1" + EDGE_PORT: "4566" steps: - name: Checkout repo - # clones the repository into the runner's workspace. uses: actions/checkout@v4 - name: Set up Python - # Installs the Python runtime. Version 3.12 is chosen for compatibility with the samples. uses: actions/setup-python@v5 with: python-version: '3.12' - name: Set up .NET - # Installs the .NET SDK. Version 9.0 is required for the C# based samples. uses: actions/setup-dotnet@v4 with: dotnet-version: '9.0' - name: Login to Docker Hub - # Logging into Docker Hub helps avoid rate limiting issues when pulling images. - # This requires DOCKERHUB_PULL_USERNAME and DOCKERHUB_PULL_TOKEN secrets to be set. + # High-volume CI environments can be throttled by Docker Hub. + # Providing credentials ensures reliable image pulls. uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_PULL_USERNAME }} password: ${{ secrets.DOCKERHUB_PULL_TOKEN }} - name: Free up disk space - # Deletes unused Docker images and build caches to ensure enough space for the emulator. + # The LocalStack Azure image and its sidecars (SQL, etc.) are large. + # Pruning ensure we don't run out of disk space on the runner. run: | docker system prune -af --volumes docker builder prune -af - - name: Install dependencies - # Installs the required CLI tools and libraries. + - name: Install Base Dependencies + # jq for JSON parsing, zip for packaging Web/Function apps. + # azlocal is the core wrapper for the Azure CLI. + # unixodbc-dev is required for pyodbc used in SQL samples. + # libsnappy-dev is a dependency for some Python libraries (e.g., pymongo). + # tflocal is the wrapper for Terraform. + run: | + pip install localstack azlocal tflocal + sudo apt-get update + sudo apt-get install -y jq zip unixodbc-dev libsnappy-dev + + - name: Install Python Requirements + # Install all dependencies found in the sample apps to the host environment. + # This ensures that 'funclocal publish --build local' works correctly. run: | - pip install localstack azlocal funclocal - sudo apt-get install -y jq zip + find samples -name "requirements.txt" -exec pip install -r {} + + + - name: Install Bicep + # Required if any deployment script uses Bicep templates. + run: | + az bicep install - name: Install Azure Functions Core Tools - # Specifically installs 'func' version 4, which is required for publishing Function Apps to the emulator. + # Using npm is the method used in the localstack-pro repo. + # It provides the 'func' command used to publish apps. run: | - curl https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor -o /usr/share/keyrings/microsoft-archive-keyring.gpg - echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-ubuntu-$(lsb_release -rs)-prod $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/dotnetdev.list - sudo apt-get update - sudo apt-get install azure-functions-core-tools-4 + npm install -g azure-functions-core-tools@4 --unsafe-perm true - - name: Install MSSQL ODBC dependencies - # One of the samples uses Azure SQL Database. These dependencies provide 'sqlcmd', - # which is used to initialize the database schema and seed data. + - name: Setup funclocal shim + # The sample scripts specifically call 'funclocal'. + # Since it is an entry point in azlocal, it should be present, + # but we create a shim to 'func' as a robust fallback. + run: | + if ! command -v funclocal >/dev/null 2>&1; then + echo "Creating funclocal shim..." + echo -e '#!/bin/bash\nfunc "$@"' | sudo tee /usr/local/bin/funclocal + sudo chmod +x /usr/local/bin/funclocal + fi + + - name: Install MSSQL ODBC and Tools + # Required for the 'web-app-sql-database' sample which uses 'sqlcmd'. run: | curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list sudo apt-get update sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 mssql-tools18 - echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc - # Make tools available for the current shell session. echo "/opt/mssql-tools18/bin" >> $GITHUB_PATH + - name: Print Tool Versions + # For debugging: print versions of all installed tools. + run: | + echo "Python: $(python --version)" + echo "Pip: $(pip --version)" + echo "Azure CLI: $(az --version | head -n 1)" + echo "Bicep: $(az bicep version)" + echo "Terraform: $(terraform version | head -n 1)" + echo "LocalStack: $(localstack --version)" + echo "azlocal: $(azlocal --version || echo 'N/A')" + echo "tflocal: $(tflocal --version || echo 'N/A')" + echo "Functions CLI: $(func --version)" + echo "Node: $(node --version)" + echo "npm: $(npm --version)" + echo "Dotnet: $(dotnet --version)" + echo "sqlcmd: $(sqlcmd -? | head -n 1)" + - name: Start LocalStack - # Launches the LocalStack Azure emulator in detached mode. + # Starts the emulator in detached mode and waits for the edge port to be ready. run: | - IMAGE_NAME=${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }} localstack start -d + IMAGE_NAME=localstack/localstack-azure-alpha localstack start -d localstack wait -t 60 + - name: Register LocalStack Cloud + # This is the "Magic" that redirects standard Azure CLI commands to LocalStack. + # We use http://127.0.0.1:4566 to avoid SSL handshaking entirely where possible. + run: | + az cloud register -n LocalStack \ + --endpoint-resource-manager "http://127.0.0.1:4566" \ + --suffix-storage-endpoint "localhost.localstack.cloud" \ + --suffix-keyvault-dns ".localhost.localstack.cloud" \ + --endpoint-active-directory "http://127.0.0.1:4566" \ + --endpoint-gallery "http://127.0.0.1:4566" \ + --endpoint-management "http://127.0.0.1:4566" || true + + az cloud set -n LocalStack + + # Perform a dummy login to satisfy the CLI's internal state. + az login --service-principal -u "ignored" -p "ignored" --tenant "ignored" --allow-no-subscriptions || true + - name: Run Test Scripts - # Iterates through the sample projects and executes their deployment and test scripts. run: | - # Define the list of samples to test. Format: path | deploy_command | test_command + # Define all samples and their scripts. Format: path | deploy_command | test_command SAMPLES=( "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/test.sh" @@ -127,7 +182,7 @@ jobs: SHARD=${{ matrix.shard }} SPLITS=${{ matrix.splits }} - # Calculate the range of samples for this specific shard. + # Calculate start and end index for this shard to parallelize execution. COUNT=$(( TOTAL / SPLITS )) START=$(( (SHARD - 1) * COUNT )) @@ -139,19 +194,19 @@ jobs: for (( i=START; i Date: Tue, 6 Jan 2026 15:15:08 +0000 Subject: [PATCH 04/42] added dependecy files --- .github/workflows/run-samples.yml | 135 ++++-------------------------- Makefile | 50 +++++++++++ pyproject.toml | 31 +++++++ requirements-dev.txt | 5 ++ requirements-runtime.txt | 12 +++ run-samples.sh | 24 +++++- setup.py | 3 + 7 files changed, 135 insertions(+), 125 deletions(-) create mode 100644 Makefile create mode 100644 pyproject.toml create mode 100644 requirements-dev.txt create mode 100644 requirements-runtime.txt create mode 100644 setup.py diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index ae12a90..8ff21a2 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -2,21 +2,18 @@ name: Samples CI # Theory of Operation: # This workflow automates the testing of Azure sample applications against the LocalStack Azure emulator. -# It replicates a production-grade CI environment by: -# 1. Setting up multiple runtimes (Python, .NET) required by different samples. -# 2. Installing the full Azure toolchain (Azure CLI, Functions Core Tools, MSSQL tools). -# 3. Configuring the Azure CLI to redirect all traffic to LocalStack (Cloud Registration). -# 4. Bypassing SSL restrictions to allow seamless communication with self-signed certificates. -# 5. Using a matrix strategy (sharding) to run tests in parallel, saving time. +# It follows the best practices from the localstack-pro repository: +# 1. Parallel Testing: Splits the sample suite into shards to reduce execution time. +# 2. Standardized Tooling: Uses a Makefile for environment setup and test orchestration. +# 3. Cloud Emulation: Configures the Azure CLI to target the LocalStack emulator. concurrency: - # Prevents multiple runs of the same workflow on the same branch from overlapping. group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true on: push: - branches: [ '**' ] # Trigger on all branches for testing + branches: [ '**' ] pull_request: branches: [ main ] workflow_dispatch: @@ -24,7 +21,6 @@ on: jobs: scripts: name: "Run Test Scripts (amd64) — Part ${{ matrix.shard }} of ${{ matrix.splits }}" - # Use the AZURE environment to access secrets like TEST_LOCALSTACK_AUTH_TOKEN environment: AZURE strategy: fail-fast: false @@ -34,18 +30,11 @@ jobs: runs-on: ubuntu-latest env: - # Secrets and core configuration LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} DOCKER_FLAGS: "-e MSSQL_ACCEPT_EULA=Y" - - # SSL and Networking Robustness - # Tell .NET and Azure CLI to trust LocalStack's self-signed certificates. PERMIT_ALL_CERTIFICATES: "true" AZURE_CLI_DISABLE_CONNECTION_VERIFICATION: "1" - # Prevent LocalStack from trying to hijack host DNS, which can be unstable in CI. DNS_ADDRESS: "0" - - # Emulation endpoints LOCALSTACK_HOSTNAME: "127.0.0.1" EDGE_PORT: "4566" @@ -57,6 +46,7 @@ jobs: uses: actions/setup-python@v5 with: python-version: '3.12' + cache: 'pip' - name: Set up .NET uses: actions/setup-dotnet@v4 @@ -64,61 +54,32 @@ jobs: dotnet-version: '9.0' - name: Login to Docker Hub - # High-volume CI environments can be throttled by Docker Hub. - # Providing credentials ensures reliable image pulls. + if: ${{ secrets.DOCKERHUB_PULL_USERNAME != '' }} uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_PULL_USERNAME }} password: ${{ secrets.DOCKERHUB_PULL_TOKEN }} - name: Free up disk space - # The LocalStack Azure image and its sidecars (SQL, etc.) are large. - # Pruning ensure we don't run out of disk space on the runner. run: | docker system prune -af --volumes docker builder prune -af - - name: Install Base Dependencies - # jq for JSON parsing, zip for packaging Web/Function apps. - # azlocal is the core wrapper for the Azure CLI. - # unixodbc-dev is required for pyodbc used in SQL samples. - # libsnappy-dev is a dependency for some Python libraries (e.g., pymongo). - # tflocal is the wrapper for Terraform. + - name: Install System Dependencies run: | - pip install localstack azlocal tflocal sudo apt-get update sudo apt-get install -y jq zip unixodbc-dev libsnappy-dev - - name: Install Python Requirements - # Install all dependencies found in the sample apps to the host environment. - # This ensures that 'funclocal publish --build local' works correctly. - run: | - find samples -name "requirements.txt" -exec pip install -r {} + + - name: Install test dependencies + run: make install - name: Install Bicep - # Required if any deployment script uses Bicep templates. - run: | - az bicep install + run: az bicep install - name: Install Azure Functions Core Tools - # Using npm is the method used in the localstack-pro repo. - # It provides the 'func' command used to publish apps. - run: | - npm install -g azure-functions-core-tools@4 --unsafe-perm true - - - name: Setup funclocal shim - # The sample scripts specifically call 'funclocal'. - # Since it is an entry point in azlocal, it should be present, - # but we create a shim to 'func' as a robust fallback. - run: | - if ! command -v funclocal >/dev/null 2>&1; then - echo "Creating funclocal shim..." - echo -e '#!/bin/bash\nfunc "$@"' | sudo tee /usr/local/bin/funclocal - sudo chmod +x /usr/local/bin/funclocal - fi + run: npm install -g azure-functions-core-tools@4 --unsafe-perm true - name: Install MSSQL ODBC and Tools - # Required for the 'web-app-sql-database' sample which uses 'sqlcmd'. run: | curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list @@ -126,32 +87,12 @@ jobs: sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 mssql-tools18 echo "/opt/mssql-tools18/bin" >> $GITHUB_PATH - - name: Print Tool Versions - # For debugging: print versions of all installed tools. - run: | - echo "Python: $(python --version)" - echo "Pip: $(pip --version)" - echo "Azure CLI: $(az --version | head -n 1)" - echo "Bicep: $(az bicep version)" - echo "Terraform: $(terraform version | head -n 1)" - echo "LocalStack: $(localstack --version)" - echo "azlocal: $(azlocal --version || echo 'N/A')" - echo "tflocal: $(tflocal --version || echo 'N/A')" - echo "Functions CLI: $(func --version)" - echo "Node: $(node --version)" - echo "npm: $(npm --version)" - echo "Dotnet: $(dotnet --version)" - echo "sqlcmd: $(sqlcmd -? | head -n 1)" - - name: Start LocalStack - # Starts the emulator in detached mode and waits for the edge port to be ready. run: | IMAGE_NAME=localstack/localstack-azure-alpha localstack start -d localstack wait -t 60 - name: Register LocalStack Cloud - # This is the "Magic" that redirects standard Azure CLI commands to LocalStack. - # We use http://127.0.0.1:4566 to avoid SSL handshaking entirely where possible. run: | az cloud register -n LocalStack \ --endpoint-resource-manager "http://127.0.0.1:4566" \ @@ -162,59 +103,11 @@ jobs: --endpoint-management "http://127.0.0.1:4566" || true az cloud set -n LocalStack - - # Perform a dummy login to satisfy the CLI's internal state. az login --service-principal -u "ignored" -p "ignored" --tenant "ignored" --allow-no-subscriptions || true - name: Run Test Scripts - run: | - # Define all samples and their scripts. Format: path | deploy_command | test_command - SAMPLES=( - "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" - "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/test.sh" - "samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" - "samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" - "samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" - "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" - ) - - TOTAL=${#SAMPLES[@]} - SHARD=${{ matrix.shard }} - SPLITS=${{ matrix.splits }} - - # Calculate start and end index for this shard to parallelize execution. - COUNT=$(( TOTAL / SPLITS )) - START=$(( (SHARD - 1) * COUNT )) - - if [ "$SHARD" -eq "$SPLITS" ]; then - COUNT=$(( TOTAL - START )) - fi - - echo "Running samples from index $START, count $COUNT" - - for (( i=START; i=64', 'wheel'] +build-backend = "setuptools.build_meta" + +[project] +name = "localstack-azure-samples" +version = "0.1.0" +description = "Samples for LocalStack Azure" +requires-python = ">=3.10" +dependencies = [ + "flask", + "pyodbc", + "pymongo", + "azure-functions", + "azure-identity", + "azure-storage-blob", + "azure-mgmt-cosmosdb", + "azure-core", + "python-dotenv", + "localstack", + "azlocal", + "terraform-local", +] + +[project.optional-dependencies] +dev = [ + "pytest>=7.0", + "pytest-xdist", + "pytest-timeout", + "pytest-rerunfailures", +] diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..b57188b --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,5 @@ +-r requirements-runtime.txt +pytest +pytest-xdist +pytest-timeout +pytest-rerunfailures diff --git a/requirements-runtime.txt b/requirements-runtime.txt new file mode 100644 index 0000000..573e0d0 --- /dev/null +++ b/requirements-runtime.txt @@ -0,0 +1,12 @@ +flask +pyodbc +pymongo +azure-functions +azure-identity +azure-storage-blob +azure-mgmt-cosmosdb +azure-core +python-dotenv +localstack +azlocal +terraform-local diff --git a/run-samples.sh b/run-samples.sh index 7ccca06..3ddeabf 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -9,7 +9,7 @@ set -euo pipefail # - Node.js & npm # - Azure CLI (az) # - LocalStack CLI -# - azlocal & tflocal (pip install azlocal tflocal) +# - azlocal & terraform-local (pip install azlocal terraform-local) # - funclocal (pip install funclocal) # - Azure Functions Core Tools (func) # - jq & zip (sudo apt-get install jq zip) @@ -30,7 +30,8 @@ fi 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 funclocal >/dev/null 2>&1 || { echo >&2 "funclocal is required but not installed. Run 'pip install funclocal'. Aborting."; exit 1; } +command -v funclocal >/dev/null 2>&1 || { echo >&2 "funclocal 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 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 @@ -66,8 +67,23 @@ SAMPLES=( "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" ) -# 4. Run Samples -for item in "${SAMPLES[@]}"; do +# 4. Calculate Shard +TOTAL=${#SAMPLES[@]} +SHARD=${1:-1} +SPLITS=${2:-1} + +COUNT=$(( TOTAL / SPLITS )) +START=$(( (SHARD - 1) * COUNT )) + +if [ "$SHARD" -eq "$SPLITS" ]; then + COUNT=$(( TOTAL - START )) +fi + +echo "Running samples shard $SHARD of $SPLITS (index $START, count $COUNT)" + +# 5. Run Samples +for (( i=START; i Date: Tue, 6 Jan 2026 15:23:56 +0000 Subject: [PATCH 05/42] removed if --- .github/workflows/run-samples.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 8ff21a2..2d97afc 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -54,7 +54,6 @@ jobs: dotnet-version: '9.0' - name: Login to Docker Hub - if: ${{ secrets.DOCKERHUB_PULL_USERNAME != '' }} uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_PULL_USERNAME }} From 4ec1d017e4168461b63cae10f31d3c08a687882d Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 6 Jan 2026 15:37:33 +0000 Subject: [PATCH 06/42] addedd docker build job --- .github/workflows/run-samples.yml | 52 ++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 2d97afc..88237bc 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -30,6 +30,8 @@ jobs: runs-on: ubuntu-latest env: + IMAGE_NAME: localstack/localstack-azure-alpha + DEFAULT_TAG: latest LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} DOCKER_FLAGS: "-e MSSQL_ACCEPT_EULA=Y" PERMIT_ALL_CERTIFICATES: "true" @@ -53,32 +55,61 @@ jobs: with: dotnet-version: '9.0' + - name: Install System Dependencies + # Essential tools for script execution, app packaging, and database connectivity. + # jq: for parsing JSON responses from Azure CLI. + # zip: for packaging function/web apps. + # unixodbc-dev & libsnappy-dev: required for Python database drivers (pyodbc, pymongo). + run: | + sudo apt-get update + sudo apt-get install -y jq zip unixodbc-dev libsnappy-dev + + - name: Install test dependencies + # Mirroring the localstack-pro approach: install all Python dependencies + # (including the localstack CLI) into a virtual environment to avoid system-level conflicts. + run: make install + - name: Login to Docker Hub + # Mandatory login to Docker Hub to benefit from higher rate limits for authenticated pulls. + # This prevents '429 Too Many Requests' errors during the pull of large emulator images. uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_PULL_USERNAME }} password: ${{ secrets.DOCKERHUB_PULL_TOKEN }} - name: Free up disk space + # Azure emulator images are large. Pruning unused Docker objects ensures enough + # disk space is available on the GitHub runner for image pulls and sidecar containers. run: | docker system prune -af --volumes docker builder prune -af - - name: Install System Dependencies - run: | - sudo apt-get update - sudo apt-get install -y jq zip unixodbc-dev libsnappy-dev + - name: Pull LocalStack Azure Image + # Explicitly pull the image before starting. This mirrors the "Build Docker Image" + # step in localstack-pro and ensures the pull logic is separated from the start logic. + run: docker pull ${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }} - - name: Install test dependencies - run: make install + - name: Start LocalStack + # Run the emulator in detached mode using the virtual environment. + # We use 'python -m localstack.cli.main' to ensure the correct CLI version from the venv is used. + run: | + source .venv/bin/activate + python -m localstack.cli.main start -d + python -m localstack.cli.main wait -t 60 + env: + IMAGE_NAME: ${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }} - name: Install Bicep + # Required for samples that use Bicep templates for infrastructure-as-code. run: az bicep install - name: Install Azure Functions Core Tools + # Required for publishing function app samples to the emulator. run: npm install -g azure-functions-core-tools@4 --unsafe-perm true - name: Install MSSQL ODBC and Tools + # Required for the 'web-app-sql-database' sample which uses 'sqlcmd' to + # initialize and verify the database schema in the local emulator. run: | curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list @@ -86,12 +117,9 @@ jobs: sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 mssql-tools18 echo "/opt/mssql-tools18/bin" >> $GITHUB_PATH - - name: Start LocalStack - run: | - IMAGE_NAME=localstack/localstack-azure-alpha localstack start -d - localstack wait -t 60 - - name: Register LocalStack Cloud + # This is the 'magic' step that redirects all standard Azure CLI commands + # to the LocalStack edge proxy running at http://127.0.0.1:4566. run: | az cloud register -n LocalStack \ --endpoint-resource-manager "http://127.0.0.1:4566" \ @@ -105,8 +133,10 @@ jobs: az login --service-principal -u "ignored" -p "ignored" --tenant "ignored" --allow-no-subscriptions || true - name: Run Test Scripts + # Executes the sharded test suite. Each shard runs a subset of samples in parallel. run: make test SHARD=${{ matrix.shard }} SPLITS=${{ matrix.splits }} - name: Get LocalStack Logs + # Captured on failure or success to provide a detailed audit trail of the emulator's activity. if: always() run: make logs From 49d9d33b24db581e2177209014f8fbaf666aa016 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 6 Jan 2026 15:46:20 +0000 Subject: [PATCH 07/42] licence refactor --- .github/workflows/run-samples.yml | 19 ++++++++++++------- run-samples.sh | 10 +++++++--- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 88237bc..b606712 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -32,13 +32,6 @@ jobs: env: IMAGE_NAME: localstack/localstack-azure-alpha DEFAULT_TAG: latest - LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} - DOCKER_FLAGS: "-e MSSQL_ACCEPT_EULA=Y" - PERMIT_ALL_CERTIFICATES: "true" - AZURE_CLI_DISABLE_CONNECTION_VERIFICATION: "1" - DNS_ADDRESS: "0" - LOCALSTACK_HOSTNAME: "127.0.0.1" - EDGE_PORT: "4566" steps: - name: Checkout repo @@ -98,6 +91,12 @@ jobs: python -m localstack.cli.main wait -t 60 env: IMAGE_NAME: ${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }} + LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} + DOCKER_FLAGS: "-e MSSQL_ACCEPT_EULA=Y" + LS_LOG: "DEBUG" + DISABLE_EVENTS: "1" + ACTIVATE_PRO: "1" + DNS_ADDRESS: "0" - name: Install Bicep # Required for samples that use Bicep templates for infrastructure-as-code. @@ -135,6 +134,12 @@ jobs: - name: Run Test Scripts # Executes the sharded test suite. Each shard runs a subset of samples in parallel. run: make test SHARD=${{ matrix.shard }} SPLITS=${{ matrix.splits }} + env: + LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} + PERMIT_ALL_CERTIFICATES: "true" + AZURE_CLI_DISABLE_CONNECTION_VERIFICATION: "1" + LOCALSTACK_HOSTNAME: "127.0.0.1" + EDGE_PORT: "4566" - name: Get LocalStack Logs # Captured on failure or success to provide a detailed audit trail of the emulator's activity. diff --git a/run-samples.sh b/run-samples.sh index 3ddeabf..cffbe99 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -40,9 +40,13 @@ if [ -z "${LOCALSTACK_AUTH_TOKEN:-}" ]; then fi # 1. Start LocalStack -echo "Starting LocalStack Azure emulator..." -IMAGE_NAME=localstack/localstack-azure-alpha localstack start -d -localstack wait -t 60 +if ! localstack status | grep -q "running"; then + echo "Starting LocalStack Azure emulator..." + IMAGE_NAME=localstack/localstack-azure-alpha localstack start -d + localstack wait -t 60 +else + echo "LocalStack is already running." +fi # 2. Register LocalStack Cloud in az CLI #echo "Registering LocalStack cloud profile..." From 24427dbca07d0924ceb632fe8ef4f8490bc0cc1e Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 6 Jan 2026 20:44:27 +0000 Subject: [PATCH 08/42] removed not needed registering cloud part --- .github/workflows/run-samples.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index b606712..a329e42 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -116,21 +116,6 @@ jobs: sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 mssql-tools18 echo "/opt/mssql-tools18/bin" >> $GITHUB_PATH - - name: Register LocalStack Cloud - # This is the 'magic' step that redirects all standard Azure CLI commands - # to the LocalStack edge proxy running at http://127.0.0.1:4566. - run: | - az cloud register -n LocalStack \ - --endpoint-resource-manager "http://127.0.0.1:4566" \ - --suffix-storage-endpoint "localhost.localstack.cloud" \ - --suffix-keyvault-dns ".localhost.localstack.cloud" \ - --endpoint-active-directory "http://127.0.0.1:4566" \ - --endpoint-gallery "http://127.0.0.1:4566" \ - --endpoint-management "http://127.0.0.1:4566" || true - - az cloud set -n LocalStack - az login --service-principal -u "ignored" -p "ignored" --tenant "ignored" --allow-no-subscriptions || true - - name: Run Test Scripts # Executes the sharded test suite. Each shard runs a subset of samples in parallel. run: make test SHARD=${{ matrix.shard }} SPLITS=${{ matrix.splits }} From 18acd1bd862b30eccbfd65a7cd1e94f1d913fc22 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 6 Jan 2026 21:16:12 +0000 Subject: [PATCH 09/42] fixed perm settings --- .github/workflows/run-samples.yml | 1 + Makefile | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index a329e42..150497d 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -56,6 +56,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y jq zip unixodbc-dev libsnappy-dev + find . -name "*.sh" -exec chmod +x {} + - name: Install test dependencies # Mirroring the localstack-pro approach: install all Python dependencies diff --git a/Makefile b/Makefile index a3f6361..76d3c12 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ $(VENV_ACTIVATE): pyproject.toml install: venv ## Install dependencies $(VENV_RUN); pip install -r requirements-dev.txt + chmod +x run-samples.sh cleanup.sh clean: ## Clean the environment rm -rf $(VENV_DIR) @@ -30,7 +31,7 @@ SHARD ?= 1 SPLITS ?= 1 test: venv ## Run all samples - $(VENV_RUN); ./run-samples.sh $(SHARD) $(SPLITS) + $(VENV_RUN); bash ./run-samples.sh $(SHARD) $(SPLITS) start: venv ## Start LocalStack $(VENV_RUN); localstack start -d From 1e6efaa9420af25d94e655a9f7aac5a9d2aae132 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 6 Jan 2026 21:24:35 +0000 Subject: [PATCH 10/42] removed az cli disable conn varification --- .github/workflows/run-samples.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 150497d..825ee06 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -122,8 +122,6 @@ jobs: run: make test SHARD=${{ matrix.shard }} SPLITS=${{ matrix.splits }} env: LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} - PERMIT_ALL_CERTIFICATES: "true" - AZURE_CLI_DISABLE_CONNECTION_VERIFICATION: "1" LOCALSTACK_HOSTNAME: "127.0.0.1" EDGE_PORT: "4566" From 014db26843a0ec9427e5d729fe40313aefe5879c Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Wed, 7 Jan 2026 18:19:24 +0000 Subject: [PATCH 11/42] removed comments --- .github/workflows/run-samples.yml | 2 -- run-samples.sh | 18 +++--------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 825ee06..63da3ab 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -122,8 +122,6 @@ jobs: run: make test SHARD=${{ matrix.shard }} SPLITS=${{ matrix.splits }} env: LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} - LOCALSTACK_HOSTNAME: "127.0.0.1" - EDGE_PORT: "4566" - name: Get LocalStack Logs # Captured on failure or success to provide a detailed audit trail of the emulator's activity. diff --git a/run-samples.sh b/run-samples.sh index cffbe99..55a4cbd 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -48,20 +48,8 @@ else echo "LocalStack is already running." fi -# 2. Register LocalStack Cloud in az CLI -#echo "Registering LocalStack cloud profile..." -#az cloud register -n LocalStack \ -# --endpoint-resource-manager "http://localhost:4566" \ -# --suffix-storage-endpoint "localhost.localstack.cloud" \ -# --suffix-keyvault-dns ".localhost.localstack.cloud" \ -# --endpoint-active-directory "http://localhost:4566" \ -# --endpoint-gallery "http://localhost:4566" \ -# --endpoint-management "http://localhost:4566" || true -#az cloud set -n LocalStack -#az login --service-principal -u "ignored" -p "ignored" --tenant "ignored" --allow-no-subscriptions || true - -# 3. Define Samples +# 2. Define Samples SAMPLES=( "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/test.sh" @@ -71,7 +59,7 @@ SAMPLES=( "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" ) -# 4. Calculate Shard +# 3. Calculate Shard TOTAL=${#SAMPLES[@]} SHARD=${1:-1} SPLITS=${2:-1} @@ -85,7 +73,7 @@ fi echo "Running samples shard $SHARD of $SPLITS (index $START, count $COUNT)" -# 5. Run Samples +# 4. Run Samples for (( i=START; i Date: Wed, 7 Jan 2026 18:41:22 +0000 Subject: [PATCH 12/42] added terraform tests only --- run-samples.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/run-samples.sh b/run-samples.sh index 55a4cbd..d4d0071 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -52,11 +52,11 @@ fi # 2. Define Samples SAMPLES=( "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" - "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/test.sh" - "samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" - "samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" - "samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" - "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" + "samples/function-app-managed-identity/python/terraform|bash deploy.sh|" + "samples/function-app-storage-http/dotnet/terraform|bash deploy.sh|" + "samples/web-app-cosmosdb-mongodb-api/python/terraform|bash deploy.sh|" + "samples/web-app-managed-identity/python/terraform|bash deploy.sh|" + "samples/web-app-sql-database/python/terraform|bash deploy.sh|" ) # 3. Calculate Shard From 6a8d47483baf7a53f0f3ed75e6cd0fcc5073050d Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Wed, 7 Jan 2026 18:54:31 +0000 Subject: [PATCH 13/42] added script tests only --- run-samples.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/run-samples.sh b/run-samples.sh index d4d0071..3372f42 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -52,11 +52,11 @@ fi # 2. Define Samples SAMPLES=( "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" - "samples/function-app-managed-identity/python/terraform|bash deploy.sh|" - "samples/function-app-storage-http/dotnet/terraform|bash deploy.sh|" - "samples/web-app-cosmosdb-mongodb-api/python/terraform|bash deploy.sh|" - "samples/web-app-managed-identity/python/terraform|bash deploy.sh|" - "samples/web-app-sql-database/python/terraform|bash deploy.sh|" + "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/validate.sh && bash scripts/test.sh" + "samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" + "samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" + "samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" + "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" ) # 3. Calculate Shard From 3d84f524dd3bab5c562483118714686c1df82cfa Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Wed, 7 Jan 2026 20:02:41 +0000 Subject: [PATCH 14/42] added start_interception --- .../python/scripts/.last_deploy_all.env | 20 +++++++++---------- .../python/scripts/system-managed-identity.sh | 5 +++-- .../python/scripts/test.sh | 5 +++-- .../python/scripts/user-managed-identity.sh | 5 +++-- .../python/scripts/validate.sh | 5 +++-- .../dotnet/scripts/deploy.sh | 5 +++-- .../dotnet/scripts/validate.sh | 5 +++-- .../python/scripts/deploy.sh | 5 +++-- .../python/scripts/validate.sh | 5 +++-- .../python/scripts/api.sh | 6 ++++-- .../python/scripts/cli.sh | 5 +++-- .../python/scripts/system-assigned.sh | 5 +++-- .../python/scripts/user-assigned.sh | 5 +++-- .../python/scripts/validate.sh | 5 +++-- .../python/scripts/deploy.sh | 5 +++-- .../python/scripts/validate.sh | 5 +++-- 16 files changed, 56 insertions(+), 40 deletions(-) diff --git a/samples/function-app-front-door/python/scripts/.last_deploy_all.env b/samples/function-app-front-door/python/scripts/.last_deploy_all.env index 30b0f6d..68620ef 100644 --- a/samples/function-app-front-door/python/scripts/.last_deploy_all.env +++ b/samples/function-app-front-door/python/scripts/.last_deploy_all.env @@ -1,10 +1,10 @@ -RESOURCE_GROUP="rg-mydemo-01950" -PROFILE_NAME="afd-mydemo-01950" -EP_BASIC="ep-mydemo-basic-01950" -EP_MULTI="ep-mydemo-multi-01950" -EP_SPEC="ep-mydemo-spec-01950" -EP_RULES="ep-mydemo-rules-01950" -EP_STATE="ep-mydemo-state-01950" -FUNC_MAIN="fa-mydemo-01950" -FUNC_A="fa-mydemoa-01950" -FUNC_B="fa-mydemob-01950" +RESOURCE_GROUP="rg-testafd-16405" +PROFILE_NAME="afd-testafd-16405" +EP_BASIC="ep-testafd-basic-16405" +EP_MULTI="ep-testafd-multi-16405" +EP_SPEC="ep-testafd-spec-16405" +EP_RULES="ep-testafd-rules-16405" +EP_STATE="ep-testafd-state-16405" +FUNC_MAIN="fa-testafd-16405" +FUNC_A="fa-testafda-16405" +FUNC_B="fa-testafdb-16405" diff --git a/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh b/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh index c05f7fc..c4415db 100755 --- a/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh +++ b/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh @@ -24,12 +24,13 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null diff --git a/samples/function-app-managed-identity/python/scripts/test.sh b/samples/function-app-managed-identity/python/scripts/test.sh index 4d792a2..46c2139 100755 --- a/samples/function-app-managed-identity/python/scripts/test.sh +++ b/samples/function-app-managed-identity/python/scripts/test.sh @@ -16,12 +16,13 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Generate a timestamp in the format YYYY-MM-DD-HH-MM-SS TIMESTAMP=$(date +"%Y-%m-%d-%H-%M-%S") diff --git a/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh b/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh index 3cb9c6e..fcc7f64 100755 --- a/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh +++ b/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh @@ -26,12 +26,13 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null diff --git a/samples/function-app-managed-identity/python/scripts/validate.sh b/samples/function-app-managed-identity/python/scripts/validate.sh index d79f7a6..2c64bd5 100644 --- a/samples/function-app-managed-identity/python/scripts/validate.sh +++ b/samples/function-app-managed-identity/python/scripts/validate.sh @@ -6,12 +6,13 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Check resource group $AZ group show \ --name local-rg \ diff --git a/samples/function-app-storage-http/dotnet/scripts/deploy.sh b/samples/function-app-storage-http/dotnet/scripts/deploy.sh index bdacc47..dfec495 100644 --- a/samples/function-app-storage-http/dotnet/scripts/deploy.sh +++ b/samples/function-app-storage-http/dotnet/scripts/deploy.sh @@ -27,14 +27,15 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception FUNC="funclocal" else echo "Using standard az for AzureCloud environment." - AZ="az" FUNC="func" fi +AZ="az" + # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null diff --git a/samples/function-app-storage-http/dotnet/scripts/validate.sh b/samples/function-app-storage-http/dotnet/scripts/validate.sh index b39c6c8..46eec0d 100644 --- a/samples/function-app-storage-http/dotnet/scripts/validate.sh +++ b/samples/function-app-storage-http/dotnet/scripts/validate.sh @@ -6,12 +6,13 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Check resource group $AZ group show \ --name local-rg \ diff --git a/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh b/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh index c56b4a0..80e08aa 100755 --- a/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh +++ b/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh @@ -28,12 +28,13 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Create a resource group echo "Creating resource group [$RESOURCE_GROUP_NAME]..." $AZ group create \ diff --git a/samples/web-app-cosmosdb-mongodb-api/python/scripts/validate.sh b/samples/web-app-cosmosdb-mongodb-api/python/scripts/validate.sh index 9d836f3..fe8f7f2 100644 --- a/samples/web-app-cosmosdb-mongodb-api/python/scripts/validate.sh +++ b/samples/web-app-cosmosdb-mongodb-api/python/scripts/validate.sh @@ -6,12 +6,13 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Check resource group $AZ group show \ --name local-rg \ diff --git a/samples/web-app-managed-identity/python/scripts/api.sh b/samples/web-app-managed-identity/python/scripts/api.sh index a3ad8a3..c0d33a6 100755 --- a/samples/web-app-managed-identity/python/scripts/api.sh +++ b/samples/web-app-managed-identity/python/scripts/api.sh @@ -19,14 +19,16 @@ API_VERSION="2024-11-30" # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception CURL="env http_proxy=http://127.0.0.1:$PROXY_PORT https_proxy=http://127.0.0.1:$PROXY_PORT curl -k -s" else echo "Using standard az for AzureCloud environment." - AZ="az" + CURL="curl -s" fi +AZ="az" + # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null diff --git a/samples/web-app-managed-identity/python/scripts/cli.sh b/samples/web-app-managed-identity/python/scripts/cli.sh index 96a5d9e..fd900e3 100755 --- a/samples/web-app-managed-identity/python/scripts/cli.sh +++ b/samples/web-app-managed-identity/python/scripts/cli.sh @@ -13,12 +13,13 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null diff --git a/samples/web-app-managed-identity/python/scripts/system-assigned.sh b/samples/web-app-managed-identity/python/scripts/system-assigned.sh index 7263544..88799a8 100755 --- a/samples/web-app-managed-identity/python/scripts/system-assigned.sh +++ b/samples/web-app-managed-identity/python/scripts/system-assigned.sh @@ -25,12 +25,13 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null diff --git a/samples/web-app-managed-identity/python/scripts/user-assigned.sh b/samples/web-app-managed-identity/python/scripts/user-assigned.sh index a2b8696..828e17a 100755 --- a/samples/web-app-managed-identity/python/scripts/user-assigned.sh +++ b/samples/web-app-managed-identity/python/scripts/user-assigned.sh @@ -27,12 +27,13 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null diff --git a/samples/web-app-managed-identity/python/scripts/validate.sh b/samples/web-app-managed-identity/python/scripts/validate.sh index 279bea6..2efd210 100644 --- a/samples/web-app-managed-identity/python/scripts/validate.sh +++ b/samples/web-app-managed-identity/python/scripts/validate.sh @@ -6,12 +6,13 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Check resource group $AZ group show \ --name local-rg \ diff --git a/samples/web-app-sql-database/python/scripts/deploy.sh b/samples/web-app-sql-database/python/scripts/deploy.sh index fc1c538..8bdc6b8 100755 --- a/samples/web-app-sql-database/python/scripts/deploy.sh +++ b/samples/web-app-sql-database/python/scripts/deploy.sh @@ -29,12 +29,13 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Create a resource group echo "Creating resource group [$RESOURCE_GROUP_NAME]..." $AZ group create \ diff --git a/samples/web-app-sql-database/python/scripts/validate.sh b/samples/web-app-sql-database/python/scripts/validate.sh index 47bf78a..62186e4 100644 --- a/samples/web-app-sql-database/python/scripts/validate.sh +++ b/samples/web-app-sql-database/python/scripts/validate.sh @@ -6,12 +6,13 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - AZ="azlocal" + azlocal start_interception else echo "Using standard az for AzureCloud environment." - AZ="az" fi +AZ="az" + # Check resource group $AZ group show \ --name local-rg \ From 0b7fb16e977c0b38f907fa7a50ea87cec82ebad9 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Wed, 7 Jan 2026 20:46:59 +0000 Subject: [PATCH 15/42] added pre login to azure cli --- .github/workflows/run-samples.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 63da3ab..2dafb49 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -32,6 +32,9 @@ jobs: env: IMAGE_NAME: localstack/localstack-azure-alpha DEFAULT_TAG: latest + # Isolate Azure CLI auth/config per shard to avoid cross-runner contention. + # This follows the best practices from localstack-pro. + AZURE_CONFIG_DIR: ${{ runner.temp }}/azure-cli-${{ matrix.shard }} steps: - name: Checkout repo @@ -99,6 +102,20 @@ jobs: ACTIVATE_PRO: "1" DNS_ADDRESS: "0" + - name: Pre-login Azure CLI + # Ensures the Azure CLI is correctly configured to target the LocalStack emulator. + # Mirroring the approach in localstack-pro. + run: | + mkdir -p "$AZURE_CONFIG_DIR" + source .venv/bin/activate + if command -v azlocal >/dev/null 2>&1; then + azlocal login || true + else + # Fallback for environments where azlocal is not available + az login --service-principal -u any-app -p any-pass --tenant any-tenant || true + fi + az account show --output table || true + - name: Install Bicep # Required for samples that use Bicep templates for infrastructure-as-code. run: az bicep install From 78d8a0db92b2c075f4d6fbb78787af3e84a7f90c Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Wed, 7 Jan 2026 20:54:46 +0000 Subject: [PATCH 16/42] =?UTF-8?q?=C3=82test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/run-samples.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 2dafb49..88fa1d1 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -32,9 +32,6 @@ jobs: env: IMAGE_NAME: localstack/localstack-azure-alpha DEFAULT_TAG: latest - # Isolate Azure CLI auth/config per shard to avoid cross-runner contention. - # This follows the best practices from localstack-pro. - AZURE_CONFIG_DIR: ${{ runner.temp }}/azure-cli-${{ matrix.shard }} steps: - name: Checkout repo @@ -105,6 +102,8 @@ jobs: - name: Pre-login Azure CLI # Ensures the Azure CLI is correctly configured to target the LocalStack emulator. # Mirroring the approach in localstack-pro. + env: + AZURE_CONFIG_DIR: ${{ runner.temp }}/azure-cli-${{ matrix.shard }} run: | mkdir -p "$AZURE_CONFIG_DIR" source .venv/bin/activate @@ -118,6 +117,8 @@ jobs: - name: Install Bicep # Required for samples that use Bicep templates for infrastructure-as-code. + env: + AZURE_CONFIG_DIR: ${{ runner.temp }}/azure-cli-${{ matrix.shard }} run: az bicep install - name: Install Azure Functions Core Tools @@ -136,9 +137,10 @@ jobs: - name: Run Test Scripts # Executes the sharded test suite. Each shard runs a subset of samples in parallel. - run: make test SHARD=${{ matrix.shard }} SPLITS=${{ matrix.splits }} env: + AZURE_CONFIG_DIR: ${{ runner.temp }}/azure-cli-${{ matrix.shard }} LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} + run: make test SHARD=${{ matrix.shard }} SPLITS=${{ matrix.splits }} - name: Get LocalStack Logs # Captured on failure or success to provide a detailed audit trail of the emulator's activity. From fc976fb7d6f63581408269716424fad81f5c8a32 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Wed, 7 Jan 2026 21:22:12 +0000 Subject: [PATCH 17/42] . --- .github/workflows/run-samples.yml | 22 ++-------------------- run-samples.sh | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 88fa1d1..0493e6c 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -32,6 +32,7 @@ jobs: env: IMAGE_NAME: localstack/localstack-azure-alpha DEFAULT_TAG: latest + AZURE_CONFIG_DIR: ${{ runner.temp }}/azure-cli steps: - name: Checkout repo @@ -99,26 +100,8 @@ jobs: ACTIVATE_PRO: "1" DNS_ADDRESS: "0" - - name: Pre-login Azure CLI - # Ensures the Azure CLI is correctly configured to target the LocalStack emulator. - # Mirroring the approach in localstack-pro. - env: - AZURE_CONFIG_DIR: ${{ runner.temp }}/azure-cli-${{ matrix.shard }} - run: | - mkdir -p "$AZURE_CONFIG_DIR" - source .venv/bin/activate - if command -v azlocal >/dev/null 2>&1; then - azlocal login || true - else - # Fallback for environments where azlocal is not available - az login --service-principal -u any-app -p any-pass --tenant any-tenant || true - fi - az account show --output table || true - - name: Install Bicep # Required for samples that use Bicep templates for infrastructure-as-code. - env: - AZURE_CONFIG_DIR: ${{ runner.temp }}/azure-cli-${{ matrix.shard }} run: az bicep install - name: Install Azure Functions Core Tools @@ -137,10 +120,9 @@ jobs: - name: Run Test Scripts # Executes the sharded test suite. Each shard runs a subset of samples in parallel. + run: make test SHARD=${{ matrix.shard }} SPLITS=${{ matrix.splits }} env: - AZURE_CONFIG_DIR: ${{ runner.temp }}/azure-cli-${{ matrix.shard }} LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }} - run: make test SHARD=${{ matrix.shard }} SPLITS=${{ matrix.splits }} - name: Get LocalStack Logs # Captured on failure or success to provide a detailed audit trail of the emulator's activity. diff --git a/run-samples.sh b/run-samples.sh index 3372f42..d9e75a7 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -48,8 +48,21 @@ else echo "LocalStack is already running." fi +# 2. Configure Azure CLI for LocalStack +echo "Configuring Azure CLI for LocalStack..." +if [ -n "${AZURE_CONFIG_DIR:-}" ]; then + mkdir -p "$AZURE_CONFIG_DIR" +fi + +if command -v azlocal >/dev/null 2>&1; then + azlocal login || true + azlocal start_interception +else + az login --service-principal -u any-app -p any-pass --tenant any-tenant || true +fi + -# 2. Define Samples +# 3. Define Samples SAMPLES=( "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/validate.sh && bash scripts/test.sh" @@ -59,7 +72,7 @@ SAMPLES=( "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" ) -# 3. Calculate Shard +# 4. Calculate Shard TOTAL=${#SAMPLES[@]} SHARD=${1:-1} SPLITS=${2:-1} @@ -73,7 +86,7 @@ fi echo "Running samples shard $SHARD of $SPLITS (index $START, count $COUNT)" -# 4. Run Samples +# 5. Run Samples for (( i=START; i Date: Wed, 7 Jan 2026 21:24:33 +0000 Subject: [PATCH 18/42] .. --- .github/workflows/run-samples.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 0493e6c..5302c4a 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -32,12 +32,14 @@ jobs: env: IMAGE_NAME: localstack/localstack-azure-alpha DEFAULT_TAG: latest - AZURE_CONFIG_DIR: ${{ runner.temp }}/azure-cli steps: - name: Checkout repo uses: actions/checkout@v4 + - name: Set up environment + run: echo "AZURE_CONFIG_DIR=${{ runner.temp }}/azure-cli" >> $GITHUB_ENV + - name: Set up Python uses: actions/setup-python@v5 with: From 807fb2eadfee4caecc387998a58823109baf78f5 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Thu, 8 Jan 2026 16:13:39 +0000 Subject: [PATCH 19/42] testing disabling az cli auth --- .../python/scripts/system-managed-identity.sh | 1 + samples/function-app-managed-identity/python/scripts/test.sh | 1 + .../python/scripts/user-managed-identity.sh | 1 + samples/function-app-managed-identity/python/scripts/validate.sh | 1 + 4 files changed, 4 insertions(+) diff --git a/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh b/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh index c4415db..cb97717 100755 --- a/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh +++ b/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh @@ -25,6 +25,7 @@ cd "$CURRENT_DIR" || exit if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." azlocal start_interception + export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 else echo "Using standard az for AzureCloud environment." fi diff --git a/samples/function-app-managed-identity/python/scripts/test.sh b/samples/function-app-managed-identity/python/scripts/test.sh index 46c2139..7c6660b 100755 --- a/samples/function-app-managed-identity/python/scripts/test.sh +++ b/samples/function-app-managed-identity/python/scripts/test.sh @@ -17,6 +17,7 @@ cd "$CURRENT_DIR" || exit if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." azlocal start_interception + export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 else echo "Using standard az for AzureCloud environment." fi diff --git a/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh b/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh index fcc7f64..ca6ecca 100755 --- a/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh +++ b/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh @@ -27,6 +27,7 @@ cd "$CURRENT_DIR" || exit if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." azlocal start_interception + export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 else echo "Using standard az for AzureCloud environment." fi diff --git a/samples/function-app-managed-identity/python/scripts/validate.sh b/samples/function-app-managed-identity/python/scripts/validate.sh index 2c64bd5..2a745c1 100644 --- a/samples/function-app-managed-identity/python/scripts/validate.sh +++ b/samples/function-app-managed-identity/python/scripts/validate.sh @@ -7,6 +7,7 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." azlocal start_interception + export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 else echo "Using standard az for AzureCloud environment." fi From a5058d61dfce3becb7705e2f55e571fd77bb6147 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Thu, 8 Jan 2026 19:57:35 +0000 Subject: [PATCH 20/42] reverts --- run-samples.sh | 2 ++ .../python/scripts/cleanup_all.sh | 2 ++ .../python/scripts/deploy_all.sh | 4 +++- .../python/scripts/system-managed-identity.sh | 24 ++++++++++++------- .../python/scripts/test.sh | 6 ++--- .../python/scripts/user-managed-identity.sh | 24 ++++++++++++------- .../python/scripts/validate.sh | 6 ++--- .../dotnet/scripts/deploy.sh | 11 +++++---- .../dotnet/scripts/validate.sh | 5 ++-- .../python/scripts/deploy.sh | 9 ++++--- .../python/scripts/validate.sh | 5 ++-- .../python/scripts/api.sh | 6 +++-- .../python/scripts/cli.sh | 5 ++-- .../python/scripts/system-assigned.sh | 9 ++++--- .../python/scripts/user-assigned.sh | 9 ++++--- .../python/scripts/validate.sh | 5 ++-- .../python/scripts/deploy.sh | 5 ++-- .../python/scripts/validate.sh | 5 ++-- 18 files changed, 84 insertions(+), 58 deletions(-) diff --git a/run-samples.sh b/run-samples.sh index d9e75a7..15cb2e5 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -57,6 +57,8 @@ fi if command -v azlocal >/dev/null 2>&1; then azlocal login || true azlocal start_interception + export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 + export AZURE_SDK_DISABLE_CONNECTION_VERIFICATION=1 else az login --service-principal -u any-app -p any-pass --tenant any-tenant || true fi diff --git a/samples/function-app-front-door/python/scripts/cleanup_all.sh b/samples/function-app-front-door/python/scripts/cleanup_all.sh index 7d5acf4..bfd5a59 100644 --- a/samples/function-app-front-door/python/scripts/cleanup_all.sh +++ b/samples/function-app-front-door/python/scripts/cleanup_all.sh @@ -78,6 +78,8 @@ if [[ "$USE_LOCALSTACK" == "true" ]]; then fi if azlocal start_interception; then INTERCEPTION_STARTED="true"; echo "LocalStack interception started." + export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 + export AZURE_SDK_DISABLE_CONNECTION_VERIFICATION=1 else echo "Error: azlocal failed to start interception. Ensure LocalStack is running and azlocal is configured correctly." >&2 exit 1 diff --git a/samples/function-app-front-door/python/scripts/deploy_all.sh b/samples/function-app-front-door/python/scripts/deploy_all.sh index 96b4799..06e9635 100644 --- a/samples/function-app-front-door/python/scripts/deploy_all.sh +++ b/samples/function-app-front-door/python/scripts/deploy_all.sh @@ -178,6 +178,8 @@ if [[ "$USE_LOCALSTACK" == "true" ]]; then fi if azlocal start_interception; then INTERCEPTION_STARTED="true"; echo "LocalStack interception started." + export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 + export AZURE_SDK_DISABLE_CONNECTION_VERIFICATION=1 else echo "Error: azlocal failed to start interception. Ensure LocalStack is running." >&2 exit 1 @@ -212,7 +214,7 @@ create_function_app() { STORAGE_KEY=$(az storage account keys list -g "$RESOURCE_GROUP" -n "$storageName" --query "[0].value" -o tsv) if [[ -z "$STORAGE_KEY" ]]; then echo "Failed to get storage key for $storageName" >&2; exit 1; fi local STORAGE_CONNECTION_STRING - STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$storageName;AccountKey=$STORAGE_KEY;BlobEndpoint=https://$storageName.blob.localhost.localstack.cloud:4566;QueueEndpoint=https://$storageName.queue.localhost.localstack.cloud:4566;TableEndpoint=https://$storageName.table.localhost.localstack.cloud:4566;FileEndpoint=https://$storageName.file.localhost.localstack.cloud:4566" + STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=http;AccountName=$storageName;AccountKey=$STORAGE_KEY;BlobEndpoint=http://$storageName.blob.localhost.localstack.cloud:4566;QueueEndpoint=http://$storageName.queue.localhost.localstack.cloud:4566;TableEndpoint=http://$storageName.table.localhost.localstack.cloud:4566;FileEndpoint=http://$storageName.file.localhost.localstack.cloud:4566" az functionapp config appsettings set -g "$RESOURCE_GROUP" -n "$funcName" \ --settings AzureWebJobsStorage="$STORAGE_CONNECTION_STRING" WEBSITE_CONTENTAZUREFILECONNECTIONSTRING="$STORAGE_CONNECTION_STRING" SCM_RUN_FROM_PACKAGE= -o none fi diff --git a/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh b/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh index cb97717..3b447be 100755 --- a/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh +++ b/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh @@ -24,14 +24,12 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception - export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null @@ -96,7 +94,11 @@ else fi # Construct the storage connection string for LocalStack -STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" +if [[ $ENVIRONMENT == "LocalStack" ]]; then + STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=http;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" +else + STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" +fi echo "Storage connection string constructed: [$STORAGE_CONNECTION_STRING]" # Get the storage account resource ID @@ -297,9 +299,15 @@ fi echo "Setting function app settings for [$FUNCTION_APP_NAME]..." # Set storage URIs based on environment -BLOB_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" -QUEUE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" -TABLE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" +if [[ $ENVIRONMENT == "LocalStack" ]]; then + BLOB_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" + QUEUE_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" + TABLE_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" +else + BLOB_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" + QUEUE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" + TABLE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" +fi $AZ functionapp config appsettings set \ diff --git a/samples/function-app-managed-identity/python/scripts/test.sh b/samples/function-app-managed-identity/python/scripts/test.sh index 7c6660b..4d792a2 100755 --- a/samples/function-app-managed-identity/python/scripts/test.sh +++ b/samples/function-app-managed-identity/python/scripts/test.sh @@ -16,14 +16,12 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception - export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Generate a timestamp in the format YYYY-MM-DD-HH-MM-SS TIMESTAMP=$(date +"%Y-%m-%d-%H-%M-%S") diff --git a/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh b/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh index ca6ecca..9660e6a 100755 --- a/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh +++ b/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh @@ -26,14 +26,12 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception - export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null @@ -98,7 +96,11 @@ else fi # Construct the storage connection string for LocalStack -STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" +if [[ $ENVIRONMENT == "LocalStack" ]]; then + STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=http;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" +else + STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" +fi echo "Storage connection string constructed: [$STORAGE_CONNECTION_STRING]" # Get the storage account resource ID @@ -358,9 +360,15 @@ fi echo "Setting function app settings for [$FUNCTION_APP_NAME]..." # Set storage URIs based on environment -BLOB_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" -QUEUE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" -TABLE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" +if [[ $ENVIRONMENT == "LocalStack" ]]; then + BLOB_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" + QUEUE_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" + TABLE_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" +else + BLOB_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" + QUEUE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" + TABLE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" +fi $AZ functionapp config appsettings set \ diff --git a/samples/function-app-managed-identity/python/scripts/validate.sh b/samples/function-app-managed-identity/python/scripts/validate.sh index 2a745c1..d79f7a6 100644 --- a/samples/function-app-managed-identity/python/scripts/validate.sh +++ b/samples/function-app-managed-identity/python/scripts/validate.sh @@ -6,14 +6,12 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception - export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Check resource group $AZ group show \ --name local-rg \ diff --git a/samples/function-app-storage-http/dotnet/scripts/deploy.sh b/samples/function-app-storage-http/dotnet/scripts/deploy.sh index dfec495..42a572c 100644 --- a/samples/function-app-storage-http/dotnet/scripts/deploy.sh +++ b/samples/function-app-storage-http/dotnet/scripts/deploy.sh @@ -27,15 +27,14 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" FUNC="funclocal" else echo "Using standard az for AzureCloud environment." + AZ="az" FUNC="func" fi -AZ="az" - # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null @@ -119,7 +118,11 @@ else fi # Construct the storage connection string for LocalStack -STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" +if [[ $ENVIRONMENT == "LocalStack" ]]; then + STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=http;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" +else + STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" +fi # Set function app settings echo "Setting function app settings for [$FUNCTION_APP_NAME]..." diff --git a/samples/function-app-storage-http/dotnet/scripts/validate.sh b/samples/function-app-storage-http/dotnet/scripts/validate.sh index 46eec0d..b39c6c8 100644 --- a/samples/function-app-storage-http/dotnet/scripts/validate.sh +++ b/samples/function-app-storage-http/dotnet/scripts/validate.sh @@ -6,13 +6,12 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Check resource group $AZ group show \ --name local-rg \ diff --git a/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh b/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh index 80e08aa..cb3e0b5 100755 --- a/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh +++ b/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh @@ -28,13 +28,12 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Create a resource group echo "Creating resource group [$RESOURCE_GROUP_NAME]..." $AZ group create \ @@ -75,6 +74,10 @@ DOCUMENT_ENDPOINT=$($AZ cosmosdb show \ --output tsv \ --only-show-errors) +if [[ $ENVIRONMENT == "LocalStack" ]]; then + DOCUMENT_ENDPOINT=$(echo $DOCUMENT_ENDPOINT | sed 's/https/http/') +fi + if [ -n "$DOCUMENT_ENDPOINT" ]; then echo "Document endpoint retrieved successfully: $DOCUMENT_ENDPOINT" else diff --git a/samples/web-app-cosmosdb-mongodb-api/python/scripts/validate.sh b/samples/web-app-cosmosdb-mongodb-api/python/scripts/validate.sh index fe8f7f2..9d836f3 100644 --- a/samples/web-app-cosmosdb-mongodb-api/python/scripts/validate.sh +++ b/samples/web-app-cosmosdb-mongodb-api/python/scripts/validate.sh @@ -6,13 +6,12 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Check resource group $AZ group show \ --name local-rg \ diff --git a/samples/web-app-managed-identity/python/scripts/api.sh b/samples/web-app-managed-identity/python/scripts/api.sh index c0d33a6..3a20257 100755 --- a/samples/web-app-managed-identity/python/scripts/api.sh +++ b/samples/web-app-managed-identity/python/scripts/api.sh @@ -20,15 +20,17 @@ API_VERSION="2024-11-30" if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." azlocal start_interception + export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 + export AZURE_SDK_DISABLE_CONNECTION_VERIFICATION=1 CURL="env http_proxy=http://127.0.0.1:$PROXY_PORT https_proxy=http://127.0.0.1:$PROXY_PORT curl -k -s" + AZ="azlocal" else echo "Using standard az for AzureCloud environment." CURL="curl -s" + AZ="az" fi -AZ="az" - # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null diff --git a/samples/web-app-managed-identity/python/scripts/cli.sh b/samples/web-app-managed-identity/python/scripts/cli.sh index fd900e3..96a5d9e 100755 --- a/samples/web-app-managed-identity/python/scripts/cli.sh +++ b/samples/web-app-managed-identity/python/scripts/cli.sh @@ -13,13 +13,12 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null diff --git a/samples/web-app-managed-identity/python/scripts/system-assigned.sh b/samples/web-app-managed-identity/python/scripts/system-assigned.sh index 88799a8..551c3f7 100755 --- a/samples/web-app-managed-identity/python/scripts/system-assigned.sh +++ b/samples/web-app-managed-identity/python/scripts/system-assigned.sh @@ -25,13 +25,12 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null @@ -119,6 +118,10 @@ AZURE_STORAGE_ACCOUNT_URL=$($AZ storage account show \ --output tsv \ --only-show-errors) +if [[ $ENVIRONMENT == "LocalStack" ]]; then + AZURE_STORAGE_ACCOUNT_URL=$(echo $AZURE_STORAGE_ACCOUNT_URL | sed 's/https/http/') +fi + if [ -n "$AZURE_STORAGE_ACCOUNT_URL" ]; then echo "Storage account blob primary endpoint retrieved successfully: $AZURE_STORAGE_ACCOUNT_URL" else diff --git a/samples/web-app-managed-identity/python/scripts/user-assigned.sh b/samples/web-app-managed-identity/python/scripts/user-assigned.sh index 828e17a..4c0510f 100755 --- a/samples/web-app-managed-identity/python/scripts/user-assigned.sh +++ b/samples/web-app-managed-identity/python/scripts/user-assigned.sh @@ -27,13 +27,12 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Create a resource group echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..." $AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null @@ -121,6 +120,10 @@ AZURE_STORAGE_ACCOUNT_URL=$($AZ storage account show \ --output tsv \ --only-show-errors) +if [[ $ENVIRONMENT == "LocalStack" ]]; then + AZURE_STORAGE_ACCOUNT_URL=$(echo $AZURE_STORAGE_ACCOUNT_URL | sed 's/https/http/') +fi + if [ -n "$AZURE_STORAGE_ACCOUNT_URL" ]; then echo "Storage account blob primary endpoint retrieved successfully: $AZURE_STORAGE_ACCOUNT_URL" else diff --git a/samples/web-app-managed-identity/python/scripts/validate.sh b/samples/web-app-managed-identity/python/scripts/validate.sh index 2efd210..279bea6 100644 --- a/samples/web-app-managed-identity/python/scripts/validate.sh +++ b/samples/web-app-managed-identity/python/scripts/validate.sh @@ -6,13 +6,12 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Check resource group $AZ group show \ --name local-rg \ diff --git a/samples/web-app-sql-database/python/scripts/deploy.sh b/samples/web-app-sql-database/python/scripts/deploy.sh index 8bdc6b8..fc1c538 100755 --- a/samples/web-app-sql-database/python/scripts/deploy.sh +++ b/samples/web-app-sql-database/python/scripts/deploy.sh @@ -29,13 +29,12 @@ cd "$CURRENT_DIR" || exit # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Create a resource group echo "Creating resource group [$RESOURCE_GROUP_NAME]..." $AZ group create \ diff --git a/samples/web-app-sql-database/python/scripts/validate.sh b/samples/web-app-sql-database/python/scripts/validate.sh index 62186e4..47bf78a 100644 --- a/samples/web-app-sql-database/python/scripts/validate.sh +++ b/samples/web-app-sql-database/python/scripts/validate.sh @@ -6,13 +6,12 @@ ENVIRONMENT=$(az account show --query environmentName --output tsv) # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" fi -AZ="az" - # Check resource group $AZ group show \ --name local-rg \ From f4df888cd07e17886c596a886c8ef8ce4a48cb84 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Thu, 8 Jan 2026 20:06:17 +0000 Subject: [PATCH 21/42] reverts 2 --- samples/function-app-front-door/python/scripts/deploy_all.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/samples/function-app-front-door/python/scripts/deploy_all.sh b/samples/function-app-front-door/python/scripts/deploy_all.sh index 06e9635..51a5051 100644 --- a/samples/function-app-front-door/python/scripts/deploy_all.sh +++ b/samples/function-app-front-door/python/scripts/deploy_all.sh @@ -178,8 +178,6 @@ if [[ "$USE_LOCALSTACK" == "true" ]]; then fi if azlocal start_interception; then INTERCEPTION_STARTED="true"; echo "LocalStack interception started." - export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 - export AZURE_SDK_DISABLE_CONNECTION_VERIFICATION=1 else echo "Error: azlocal failed to start interception. Ensure LocalStack is running." >&2 exit 1 From c618315fcd145d5bcaf286099372f31ef7af1f61 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Thu, 8 Jan 2026 20:15:26 +0000 Subject: [PATCH 22/42] reverts 3 --- run-samples.sh | 2 -- samples/function-app-front-door/python/scripts/cleanup_all.sh | 2 -- samples/web-app-managed-identity/python/scripts/api.sh | 3 --- 3 files changed, 7 deletions(-) diff --git a/run-samples.sh b/run-samples.sh index 15cb2e5..d9e75a7 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -57,8 +57,6 @@ fi if command -v azlocal >/dev/null 2>&1; then azlocal login || true azlocal start_interception - export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 - export AZURE_SDK_DISABLE_CONNECTION_VERIFICATION=1 else az login --service-principal -u any-app -p any-pass --tenant any-tenant || true fi diff --git a/samples/function-app-front-door/python/scripts/cleanup_all.sh b/samples/function-app-front-door/python/scripts/cleanup_all.sh index bfd5a59..7d5acf4 100644 --- a/samples/function-app-front-door/python/scripts/cleanup_all.sh +++ b/samples/function-app-front-door/python/scripts/cleanup_all.sh @@ -78,8 +78,6 @@ if [[ "$USE_LOCALSTACK" == "true" ]]; then fi if azlocal start_interception; then INTERCEPTION_STARTED="true"; echo "LocalStack interception started." - export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 - export AZURE_SDK_DISABLE_CONNECTION_VERIFICATION=1 else echo "Error: azlocal failed to start interception. Ensure LocalStack is running and azlocal is configured correctly." >&2 exit 1 diff --git a/samples/web-app-managed-identity/python/scripts/api.sh b/samples/web-app-managed-identity/python/scripts/api.sh index 3a20257..d0782c3 100755 --- a/samples/web-app-managed-identity/python/scripts/api.sh +++ b/samples/web-app-managed-identity/python/scripts/api.sh @@ -20,13 +20,10 @@ API_VERSION="2024-11-30" if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." azlocal start_interception - export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 - export AZURE_SDK_DISABLE_CONNECTION_VERIFICATION=1 CURL="env http_proxy=http://127.0.0.1:$PROXY_PORT https_proxy=http://127.0.0.1:$PROXY_PORT curl -k -s" AZ="azlocal" else echo "Using standard az for AzureCloud environment." - CURL="curl -s" AZ="az" fi From 01d2dd8624c0fa55def7ce422ead2fe9a032e90c Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Thu, 8 Jan 2026 20:22:28 +0000 Subject: [PATCH 23/42] reverts 4 --- .../python/scripts/system-managed-identity.sh | 18 ++++-------------- .../python/scripts/user-managed-identity.sh | 18 ++++-------------- .../dotnet/scripts/deploy.sh | 6 +----- .../python/scripts/deploy.sh | 4 ---- .../python/scripts/api.sh | 5 ++--- .../python/scripts/system-assigned.sh | 4 ---- .../python/scripts/user-assigned.sh | 4 ---- 7 files changed, 11 insertions(+), 48 deletions(-) diff --git a/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh b/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh index 3b447be..c05f7fc 100755 --- a/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh +++ b/samples/function-app-managed-identity/python/scripts/system-managed-identity.sh @@ -94,11 +94,7 @@ else fi # Construct the storage connection string for LocalStack -if [[ $ENVIRONMENT == "LocalStack" ]]; then - STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=http;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" -else - STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" -fi +STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" echo "Storage connection string constructed: [$STORAGE_CONNECTION_STRING]" # Get the storage account resource ID @@ -299,15 +295,9 @@ fi echo "Setting function app settings for [$FUNCTION_APP_NAME]..." # Set storage URIs based on environment -if [[ $ENVIRONMENT == "LocalStack" ]]; then - BLOB_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" - QUEUE_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" - TABLE_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" -else - BLOB_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" - QUEUE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" - TABLE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" -fi +BLOB_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" +QUEUE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" +TABLE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" $AZ functionapp config appsettings set \ diff --git a/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh b/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh index 9660e6a..3cb9c6e 100755 --- a/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh +++ b/samples/function-app-managed-identity/python/scripts/user-managed-identity.sh @@ -96,11 +96,7 @@ else fi # Construct the storage connection string for LocalStack -if [[ $ENVIRONMENT == "LocalStack" ]]; then - STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=http;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" -else - STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" -fi +STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" echo "Storage connection string constructed: [$STORAGE_CONNECTION_STRING]" # Get the storage account resource ID @@ -360,15 +356,9 @@ fi echo "Setting function app settings for [$FUNCTION_APP_NAME]..." # Set storage URIs based on environment -if [[ $ENVIRONMENT == "LocalStack" ]]; then - BLOB_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" - QUEUE_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" - TABLE_SERVICE_URI="http://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" -else - BLOB_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" - QUEUE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" - TABLE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" -fi +BLOB_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net" +QUEUE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.queue.core.windows.net" +TABLE_SERVICE_URI="https://${STORAGE_ACCOUNT_NAME}.table.core.windows.net" $AZ functionapp config appsettings set \ diff --git a/samples/function-app-storage-http/dotnet/scripts/deploy.sh b/samples/function-app-storage-http/dotnet/scripts/deploy.sh index 42a572c..bdacc47 100644 --- a/samples/function-app-storage-http/dotnet/scripts/deploy.sh +++ b/samples/function-app-storage-http/dotnet/scripts/deploy.sh @@ -118,11 +118,7 @@ else fi # Construct the storage connection string for LocalStack -if [[ $ENVIRONMENT == "LocalStack" ]]; then - STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=http;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" -else - STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" -fi +STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net" # Set function app settings echo "Setting function app settings for [$FUNCTION_APP_NAME]..." diff --git a/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh b/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh index cb3e0b5..c56b4a0 100755 --- a/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh +++ b/samples/web-app-cosmosdb-mongodb-api/python/scripts/deploy.sh @@ -74,10 +74,6 @@ DOCUMENT_ENDPOINT=$($AZ cosmosdb show \ --output tsv \ --only-show-errors) -if [[ $ENVIRONMENT == "LocalStack" ]]; then - DOCUMENT_ENDPOINT=$(echo $DOCUMENT_ENDPOINT | sed 's/https/http/') -fi - if [ -n "$DOCUMENT_ENDPOINT" ]; then echo "Document endpoint retrieved successfully: $DOCUMENT_ENDPOINT" else diff --git a/samples/web-app-managed-identity/python/scripts/api.sh b/samples/web-app-managed-identity/python/scripts/api.sh index d0782c3..a3ad8a3 100755 --- a/samples/web-app-managed-identity/python/scripts/api.sh +++ b/samples/web-app-managed-identity/python/scripts/api.sh @@ -19,13 +19,12 @@ API_VERSION="2024-11-30" # Choose the appropriate CLI based on the environment if [[ $ENVIRONMENT == "LocalStack" ]]; then echo "Using azlocal for LocalStack emulator environment." - azlocal start_interception + AZ="azlocal" CURL="env http_proxy=http://127.0.0.1:$PROXY_PORT https_proxy=http://127.0.0.1:$PROXY_PORT curl -k -s" - AZ="azlocal" else echo "Using standard az for AzureCloud environment." + AZ="az" CURL="curl -s" - AZ="az" fi # Create a resource group diff --git a/samples/web-app-managed-identity/python/scripts/system-assigned.sh b/samples/web-app-managed-identity/python/scripts/system-assigned.sh index 551c3f7..7263544 100755 --- a/samples/web-app-managed-identity/python/scripts/system-assigned.sh +++ b/samples/web-app-managed-identity/python/scripts/system-assigned.sh @@ -118,10 +118,6 @@ AZURE_STORAGE_ACCOUNT_URL=$($AZ storage account show \ --output tsv \ --only-show-errors) -if [[ $ENVIRONMENT == "LocalStack" ]]; then - AZURE_STORAGE_ACCOUNT_URL=$(echo $AZURE_STORAGE_ACCOUNT_URL | sed 's/https/http/') -fi - if [ -n "$AZURE_STORAGE_ACCOUNT_URL" ]; then echo "Storage account blob primary endpoint retrieved successfully: $AZURE_STORAGE_ACCOUNT_URL" else diff --git a/samples/web-app-managed-identity/python/scripts/user-assigned.sh b/samples/web-app-managed-identity/python/scripts/user-assigned.sh index 4c0510f..a2b8696 100755 --- a/samples/web-app-managed-identity/python/scripts/user-assigned.sh +++ b/samples/web-app-managed-identity/python/scripts/user-assigned.sh @@ -120,10 +120,6 @@ AZURE_STORAGE_ACCOUNT_URL=$($AZ storage account show \ --output tsv \ --only-show-errors) -if [[ $ENVIRONMENT == "LocalStack" ]]; then - AZURE_STORAGE_ACCOUNT_URL=$(echo $AZURE_STORAGE_ACCOUNT_URL | sed 's/https/http/') -fi - if [ -n "$AZURE_STORAGE_ACCOUNT_URL" ]; then echo "Storage account blob primary endpoint retrieved successfully: $AZURE_STORAGE_ACCOUNT_URL" else From 7484a105d6d1f9387c0c4d685462812591436415 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Thu, 8 Jan 2026 22:13:23 +0000 Subject: [PATCH 24/42] added .net no proxy --- .../function-app-storage-http/dotnet/scripts/deploy.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/samples/function-app-storage-http/dotnet/scripts/deploy.sh b/samples/function-app-storage-http/dotnet/scripts/deploy.sh index bdacc47..be383b0 100644 --- a/samples/function-app-storage-http/dotnet/scripts/deploy.sh +++ b/samples/function-app-storage-http/dotnet/scripts/deploy.sh @@ -150,6 +150,10 @@ fi # CD into the function app directory cd ../src/sample || exit -# Publish the function app echo "Publishing function app [$FUNCTION_APP_NAME]..." -$FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --verbose --debug \ No newline at end of file +if [[ $ENVIRONMENT == "LocalStack" ]]; then + # Disable proxy for NuGet during build to avoid proxy interference + NO_PROXY="api.nuget.org,*.nuget.org" no_proxy="api.nuget.org,*.nuget.org" $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --verbose --debug +else + $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --verbose --debug +fi \ No newline at end of file From c95af167153d8e870c0d2303c13693d7ba11be6b Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Thu, 8 Jan 2026 22:33:40 +0000 Subject: [PATCH 25/42] --no-build --- samples/function-app-storage-http/dotnet/scripts/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/function-app-storage-http/dotnet/scripts/deploy.sh b/samples/function-app-storage-http/dotnet/scripts/deploy.sh index be383b0..3d5e0fe 100644 --- a/samples/function-app-storage-http/dotnet/scripts/deploy.sh +++ b/samples/function-app-storage-http/dotnet/scripts/deploy.sh @@ -153,7 +153,7 @@ cd ../src/sample || exit echo "Publishing function app [$FUNCTION_APP_NAME]..." if [[ $ENVIRONMENT == "LocalStack" ]]; then # Disable proxy for NuGet during build to avoid proxy interference - NO_PROXY="api.nuget.org,*.nuget.org" no_proxy="api.nuget.org,*.nuget.org" $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --verbose --debug + NO_PROXY="api.nuget.org,*.nuget.org" no_proxy="api.nuget.org,*.nuget.org" $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --no-build --verbose --debug else $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --verbose --debug fi \ No newline at end of file From 380562badb1cefa71e5901f2c7699de83427b136 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Thu, 8 Jan 2026 23:51:03 +0000 Subject: [PATCH 26/42] skip .net test --- run-samples.sh | 2 +- samples/function-app-storage-http/dotnet/scripts/deploy.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/run-samples.sh b/run-samples.sh index d9e75a7..ced7162 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -66,7 +66,7 @@ fi SAMPLES=( "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/validate.sh && bash scripts/test.sh" - "samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" + #"samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" "samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" "samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" diff --git a/samples/function-app-storage-http/dotnet/scripts/deploy.sh b/samples/function-app-storage-http/dotnet/scripts/deploy.sh index 3d5e0fe..be383b0 100644 --- a/samples/function-app-storage-http/dotnet/scripts/deploy.sh +++ b/samples/function-app-storage-http/dotnet/scripts/deploy.sh @@ -153,7 +153,7 @@ cd ../src/sample || exit echo "Publishing function app [$FUNCTION_APP_NAME]..." if [[ $ENVIRONMENT == "LocalStack" ]]; then # Disable proxy for NuGet during build to avoid proxy interference - NO_PROXY="api.nuget.org,*.nuget.org" no_proxy="api.nuget.org,*.nuget.org" $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --no-build --verbose --debug + NO_PROXY="api.nuget.org,*.nuget.org" no_proxy="api.nuget.org,*.nuget.org" $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --verbose --debug else $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --verbose --debug fi \ No newline at end of file From 3e91113dc76fd5362fc93de4e4c2f1819f204cb1 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Fri, 9 Jan 2026 00:16:10 +0000 Subject: [PATCH 27/42] skip sql test --- run-samples.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-samples.sh b/run-samples.sh index ced7162..75dd79d 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -69,7 +69,7 @@ SAMPLES=( #"samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" "samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" "samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" - "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" + #"samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" ) # 4. Calculate Shard From 48b46379b5c139aff02a9634991fee6ac06c9b33 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Mon, 12 Jan 2026 19:32:49 +0000 Subject: [PATCH 28/42] testing dotnet test --- run-samples.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-samples.sh b/run-samples.sh index 75dd79d..e462903 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -66,7 +66,7 @@ fi SAMPLES=( "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/validate.sh && bash scripts/test.sh" - #"samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" + "samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" "samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" "samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" #"samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" From 23d3e1362ac2c316fe1e43a81a5f38873dcb9cbb Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Mon, 12 Jan 2026 19:50:24 +0000 Subject: [PATCH 29/42] only run failing tests --- run-samples.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/run-samples.sh b/run-samples.sh index e462903..95b52e2 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -64,12 +64,12 @@ fi # 3. Define Samples SAMPLES=( - "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" - "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/validate.sh && bash scripts/test.sh" + #"samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" + #"samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/validate.sh && bash scripts/test.sh" "samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" - "samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" - "samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" - #"samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" + #"samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" + #"samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" + "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" ) # 4. Calculate Shard From 2d3d152b13c568e73a542c3646f565f369610faf Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Mon, 12 Jan 2026 20:14:52 +0000 Subject: [PATCH 30/42] web app sql certificate set as trusted --- run-samples.sh | 2 +- .../web-app-sql-database/python/scripts/deploy.sh | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/run-samples.sh b/run-samples.sh index 95b52e2..a7bc4a8 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -66,7 +66,7 @@ fi SAMPLES=( #"samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" #"samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/validate.sh && bash scripts/test.sh" - "samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" + #"samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" #"samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" #"samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" diff --git a/samples/web-app-sql-database/python/scripts/deploy.sh b/samples/web-app-sql-database/python/scripts/deploy.sh index fc1c538..e6955a0 100755 --- a/samples/web-app-sql-database/python/scripts/deploy.sh +++ b/samples/web-app-sql-database/python/scripts/deploy.sh @@ -144,12 +144,13 @@ fi # Create server-level login echo "Creating login [$DATABASE_USER_NAME] at server level..." sqlcmd -S "$SQL_SERVER_FQDN" \ - -d master \ - -U "$ADMIN_USER" \ - -P "$ADMIN_PASSWORD" \ - -Q "IF NOT EXISTS (SELECT * FROM sys.sql_logins WHERE name = '$DATABASE_USER_NAME') - CREATE LOGIN [$DATABASE_USER_NAME] WITH PASSWORD = '$DATABASE_USER_PASSWORD';" \ - -V 1 + -d master \ + -U "$ADMIN_USER" \ + -P "$ADMIN_PASSWORD" \ + -N -C \ + -Q "IF NOT EXISTS (SELECT * FROM sys.sql_logins WHERE name = '$DATABASE_USER_NAME') + CREATE LOGIN [$DATABASE_USER_NAME] WITH PASSWORD = '$DATABASE_USER_PASSWORD';" \ + -V 1 if [ $? -eq 0 ]; then echo "Login [$DATABASE_USER_NAME] created successfully" From cb71e784ffac42602af9e7e04f251ec330d9453f Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Mon, 12 Jan 2026 20:20:13 +0000 Subject: [PATCH 31/42] trusted cert --- .../web-app-sql-database/python/scripts/deploy.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/samples/web-app-sql-database/python/scripts/deploy.sh b/samples/web-app-sql-database/python/scripts/deploy.sh index e6955a0..08e01ea 100755 --- a/samples/web-app-sql-database/python/scripts/deploy.sh +++ b/samples/web-app-sql-database/python/scripts/deploy.sh @@ -162,12 +162,13 @@ fi # Create database user echo "Creating user [$DATABASE_USER_NAME] in database [$SQL_DATABASE_NAME]..." sqlcmd -S "$SQL_SERVER_FQDN" \ - -d "$SQL_DATABASE_NAME" \ - -U "$ADMIN_USER" \ - -P "$ADMIN_PASSWORD" \ - -Q "IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = '$DATABASE_USER_NAME') - CREATE USER [$DATABASE_USER_NAME] FOR LOGIN [$DATABASE_USER_NAME];" \ - -V 1 + -d "$SQL_DATABASE_NAME" \ + -U "$ADMIN_USER" \ + -P "$ADMIN_PASSWORD" \ + -N -C \ + -Q "IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = '$DATABASE_USER_NAME') + CREATE USER [$DATABASE_USER_NAME] FOR LOGIN [$DATABASE_USER_NAME];" \ + -V 1 if [ $? -eq 0 ]; then echo "User [$DATABASE_USER_NAME] created successfully in database [$SQL_DATABASE_NAME]" From 70f71c148610ccd6bbedf8b73f23f33dfccd42bc Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Mon, 12 Jan 2026 20:26:55 +0000 Subject: [PATCH 32/42] added -N -C to all sql cmds --- samples/web-app-sql-database/python/scripts/deploy.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/samples/web-app-sql-database/python/scripts/deploy.sh b/samples/web-app-sql-database/python/scripts/deploy.sh index 08e01ea..d38d0ae 100755 --- a/samples/web-app-sql-database/python/scripts/deploy.sh +++ b/samples/web-app-sql-database/python/scripts/deploy.sh @@ -183,6 +183,7 @@ sqlcmd -S "$SQL_SERVER_FQDN" \ -d "$SQL_DATABASE_NAME" \ -U "$ADMIN_USER" \ -P "$ADMIN_PASSWORD" \ + -N -C \ -Q "ALTER ROLE db_datareader ADD MEMBER [$DATABASE_USER_NAME]; ALTER ROLE db_datawriter ADD MEMBER [$DATABASE_USER_NAME]; ALTER ROLE db_ddladmin ADD MEMBER [$DATABASE_USER_NAME];" \ @@ -201,6 +202,7 @@ sqlcmd -S "$SQL_SERVER_FQDN" \ -d "$SQL_DATABASE_NAME" \ -U "$DATABASE_USER_NAME" \ -P "$DATABASE_USER_PASSWORD" \ + -N -C \ -Q "SELECT SYSTEM_USER AS CurrentUser, DB_NAME() AS CurrentDatabase, GETDATE() AS CurrentTime;" \ -V 1 @@ -217,6 +219,7 @@ sqlcmd -S "$SQL_SERVER_FQDN" \ -d "$SQL_DATABASE_NAME" \ -U "$DATABASE_USER_NAME" \ -P "$DATABASE_USER_PASSWORD" \ + -N -C \ -Q "IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Activities' AND schema_id = SCHEMA_ID('dbo')) CREATE TABLE dbo.Activities ( -- Primary Key: UNIQUEIDENTIFIER with a default of a new sequential GUID (best for indexing) @@ -246,6 +249,7 @@ sqlcmd -S "$SQL_SERVER_FQDN" \ -d "$SQL_DATABASE_NAME" \ -U "$DATABASE_USER_NAME" \ -P "$DATABASE_USER_PASSWORD" \ + -N -C \ -Q "INSERT INTO Activities (username, activity, timestamp) VALUES ('paolo', 'Go to Paris', GETDATE()), @@ -266,6 +270,7 @@ sqlcmd -S "$SQL_SERVER_FQDN" \ -d "$SQL_DATABASE_NAME" \ -U "$DATABASE_USER_NAME" \ -P "$DATABASE_USER_PASSWORD" \ + -N -C \ -Q "SELECT * FROM Activities;" \ -V 1 From d39412753ef9b28246293e58ff2155f052d5e11e Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Mon, 12 Jan 2026 20:35:10 +0000 Subject: [PATCH 33/42] removed install bicep --- .github/workflows/run-samples.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 5302c4a..67a42e8 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -102,10 +102,6 @@ jobs: ACTIVATE_PRO: "1" DNS_ADDRESS: "0" - - name: Install Bicep - # Required for samples that use Bicep templates for infrastructure-as-code. - run: az bicep install - - name: Install Azure Functions Core Tools # Required for publishing function app samples to the emulator. run: npm install -g azure-functions-core-tools@4 --unsafe-perm true From f996c154fea88f98c7af242320db3e291336977b Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 13 Jan 2026 13:58:14 +0000 Subject: [PATCH 34/42] run all test --- .github/workflows/run-samples.yml | 2 +- run-samples.sh | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 67a42e8..732f011 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -27,7 +27,7 @@ jobs: matrix: shard: [1, 2] splits: [2] - runs-on: ubuntu-latest + runs-on: buildjet-8vcpu-ubuntu-2204 env: IMAGE_NAME: localstack/localstack-azure-alpha diff --git a/run-samples.sh b/run-samples.sh index a7bc4a8..d9e75a7 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -64,11 +64,11 @@ fi # 3. Define Samples SAMPLES=( - #"samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" - #"samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/validate.sh && bash scripts/test.sh" - #"samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" - #"samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" - #"samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" + "samples/function-app-front-door/python|bash scripts/deploy_all.sh --name-prefix testafd --use-localstack|" + "samples/function-app-managed-identity/python|bash scripts/user-managed-identity.sh|bash scripts/validate.sh && bash scripts/test.sh" + "samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh" + "samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" + "samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh" "samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh" ) From 16a39926407c463b7137ccfdbc136934cfe99db9 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 13 Jan 2026 14:05:51 +0000 Subject: [PATCH 35/42] run all test --- .github/workflows/run-samples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 732f011..67a42e8 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -27,7 +27,7 @@ jobs: matrix: shard: [1, 2] splits: [2] - runs-on: buildjet-8vcpu-ubuntu-2204 + runs-on: ubuntu-latest env: IMAGE_NAME: localstack/localstack-azure-alpha From cc73d9439894baa3f78d2361ba523b76fc3f4466 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 13 Jan 2026 15:01:55 +0000 Subject: [PATCH 36/42] increase runner --- .github/workflows/run-samples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 67a42e8..6ef7357 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -27,7 +27,7 @@ jobs: matrix: shard: [1, 2] splits: [2] - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8-cores env: IMAGE_NAME: localstack/localstack-azure-alpha From e6d0cd347da40285e98e8cabe17443af049a0fad Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 13 Jan 2026 18:40:03 +0000 Subject: [PATCH 37/42] clean disk after each test --- .github/workflows/run-samples.yml | 2 +- run-samples.sh | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 6ef7357..67a42e8 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -27,7 +27,7 @@ jobs: matrix: shard: [1, 2] splits: [2] - runs-on: ubuntu-latest-8-cores + runs-on: ubuntu-latest env: IMAGE_NAME: localstack/localstack-azure-alpha diff --git a/run-samples.sh b/run-samples.sh index d9e75a7..d38150e 100644 --- a/run-samples.sh +++ b/run-samples.sh @@ -106,6 +106,10 @@ for (( i=START; i /dev/null echo "Completed: $path" + + # Cleanup Docker resources after each test to free up disk space + echo "Cleaning up Docker resources..." + docker system prune -af --volumes || true echo "" done From 60e3a8644a18b977a68c5f40ea4d5d6d2f3209a9 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 13 Jan 2026 18:58:39 +0000 Subject: [PATCH 38/42] removed verbose debu --- samples/function-app-front-door/python/scripts/deploy_all.sh | 2 +- samples/function-app-storage-http/dotnet/scripts/deploy.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/function-app-front-door/python/scripts/deploy_all.sh b/samples/function-app-front-door/python/scripts/deploy_all.sh index 51a5051..27fa508 100644 --- a/samples/function-app-front-door/python/scripts/deploy_all.sh +++ b/samples/function-app-front-door/python/scripts/deploy_all.sh @@ -228,7 +228,7 @@ publish_function_code() { echo "Error: Azure Functions Core Tools ('func') not found in PATH." >&2; exit 1 fi pushd "$FUNCTION_SRC" >/dev/null - funclocal azure functionapp publish "$funcName" --python --build local --verbose --debug + funclocal azure functionapp publish "$funcName" --python --build local #--verbose --debug popd >/dev/null else rm -f "$zipPath"; ( cd "$FUNCTION_SRC" && zip -rq "$zipPath" . ) diff --git a/samples/function-app-storage-http/dotnet/scripts/deploy.sh b/samples/function-app-storage-http/dotnet/scripts/deploy.sh index be383b0..49e5b0c 100644 --- a/samples/function-app-storage-http/dotnet/scripts/deploy.sh +++ b/samples/function-app-storage-http/dotnet/scripts/deploy.sh @@ -153,7 +153,7 @@ cd ../src/sample || exit echo "Publishing function app [$FUNCTION_APP_NAME]..." if [[ $ENVIRONMENT == "LocalStack" ]]; then # Disable proxy for NuGet during build to avoid proxy interference - NO_PROXY="api.nuget.org,*.nuget.org" no_proxy="api.nuget.org,*.nuget.org" $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --verbose --debug + NO_PROXY="api.nuget.org,*.nuget.org" no_proxy="api.nuget.org,*.nuget.org" $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated #--verbose --debug else - $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated --verbose --debug + $FUNC azure functionapp publish $FUNCTION_APP_NAME --dotnet-isolated #--verbose --debug fi \ No newline at end of file From fc6f8b073605e421e9d759282dd0d3b802a12742 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 13 Jan 2026 19:32:17 +0000 Subject: [PATCH 39/42] removed unnecessary files --- Makefile | 24 ++---------------------- cleanup.sh | 38 -------------------------------------- setup.py | 3 --- 3 files changed, 2 insertions(+), 63 deletions(-) delete mode 100644 cleanup.sh delete mode 100644 setup.py diff --git a/Makefile b/Makefile index 76d3c12..fac6445 100644 --- a/Makefile +++ b/Makefile @@ -17,15 +17,7 @@ $(VENV_ACTIVATE): pyproject.toml install: venv ## Install dependencies $(VENV_RUN); pip install -r requirements-dev.txt - chmod +x run-samples.sh cleanup.sh - -clean: ## Clean the environment - rm -rf $(VENV_DIR) - rm -rf build/ - rm -rf dist/ - rm -rf *.egg-info/ - find . -name "*.pyc" -delete - find . -name "__pycache__" -delete + chmod +x run-samples.sh SHARD ?= 1 SPLITS ?= 1 @@ -33,19 +25,7 @@ SPLITS ?= 1 test: venv ## Run all samples $(VENV_RUN); bash ./run-samples.sh $(SHARD) $(SPLITS) -start: venv ## Start LocalStack - $(VENV_RUN); localstack start -d - -stop: venv ## Stop LocalStack - $(VENV_RUN); localstack stop - -status: venv ## Check LocalStack status - $(VENV_RUN); localstack status - logs: venv ## Get LocalStack logs $(VENV_RUN); localstack logs -.PHONY: venv install clean test start stop status logs help - -help: ## Display this help message - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' +.PHONY: venv install test logs diff --git a/cleanup.sh b/cleanup.sh deleted file mode 100644 index c8bc12b..0000000 --- a/cleanup.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash -set -uo pipefail - -# Cleanup script to stop and remove LocalStack containers and revert CLI configurations. - -echo "Stopping LocalStack..." -localstack stop || true - -echo "Killing any lingering LocalStack-related containers..." -# Kill the main container if it didn't stop -docker stop localstack-main >/dev/null 2>&1 || true -docker rm localstack-main >/dev/null 2>&1 || true - -# Kill any containers started by LocalStack (e.g., function app sidecars) -# These usually have labels or specific naming conventions, but a safe bet is to look for those with localstack in the name or created by the localstack network -CONTAINERS=$(docker ps -a --filter "name=localstack" --filter "name=ls-" -q) -if [ -n "$CONTAINERS" ]; then - echo "Stopping sidecar containers..." - docker stop $CONTAINERS >/dev/null 2>&1 || true - docker rm $CONTAINERS >/dev/null 2>&1 || true -fi - -echo "Cleaning up Docker networks..." -docker network prune -f >/dev/null 2>&1 || true - -echo "Reverting Azure CLI configuration..." -# Switch back to AzureCloud if LocalStack was the current cloud -CURRENT_CLOUD=$(az cloud show --query name -o tsv 2>/dev/null || echo "") -if [ "$CURRENT_CLOUD" == "LocalStack" ]; then - az cloud set -n AzureCloud --only-show-errors || true -fi - -# Optionally unregister the LocalStack cloud -# az cloud unregister -n LocalStack --only-show-errors || true - -echo "Cleanup complete!" -echo "Note: LocalStack persistent data in ~/.localstack/volume was NOT removed." -echo "To remove it, run: rm -rf ~/.localstack/volume" diff --git a/setup.py b/setup.py deleted file mode 100644 index 6068493..0000000 --- a/setup.py +++ /dev/null @@ -1,3 +0,0 @@ -from setuptools import setup - -setup() From 695c2b7038f7cf8f8693c215a882ec4f1719ae23 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 13 Jan 2026 19:59:26 +0000 Subject: [PATCH 40/42] updated readme --- README.md | 9 ++------- .../python/scripts/.last_deploy_all.env | 20 +++++++++---------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a1c50eb..edaf852 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,8 @@ Each sample project is organized by Azure service and includes: 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. ```bash +cd localstack-azure-samples + # Set your LOCALSTACK_AUTH_TOKEN export LOCALSTACK_AUTH_TOKEN= @@ -56,13 +58,6 @@ export LOCALSTACK_AUTH_TOKEN= ./run-samples.sh ``` -## Cleanup - -To stop LocalStack and all associated containers, and revert your Azure CLI configuration, run: -```bash -./cleanup.sh -``` - ### Troubleshooting: Line Endings 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: ```bash diff --git a/samples/function-app-front-door/python/scripts/.last_deploy_all.env b/samples/function-app-front-door/python/scripts/.last_deploy_all.env index 68620ef..69f3cff 100644 --- a/samples/function-app-front-door/python/scripts/.last_deploy_all.env +++ b/samples/function-app-front-door/python/scripts/.last_deploy_all.env @@ -1,10 +1,10 @@ -RESOURCE_GROUP="rg-testafd-16405" -PROFILE_NAME="afd-testafd-16405" -EP_BASIC="ep-testafd-basic-16405" -EP_MULTI="ep-testafd-multi-16405" -EP_SPEC="ep-testafd-spec-16405" -EP_RULES="ep-testafd-rules-16405" -EP_STATE="ep-testafd-state-16405" -FUNC_MAIN="fa-testafd-16405" -FUNC_A="fa-testafda-16405" -FUNC_B="fa-testafdb-16405" +RESOURCE_GROUP="rg-testafd-30236" +PROFILE_NAME="afd-testafd-30236" +EP_BASIC="ep-testafd-basic-30236" +EP_MULTI="ep-testafd-multi-30236" +EP_SPEC="ep-testafd-spec-30236" +EP_RULES="ep-testafd-rules-30236" +EP_STATE="ep-testafd-state-30236" +FUNC_MAIN="fa-testafd-30236" +FUNC_A="fa-testafda-30236" +FUNC_B="fa-testafdb-30236" From a999e84fd72bca147670ecbe63ea8aa7bd31ee93 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 13 Jan 2026 20:18:11 +0000 Subject: [PATCH 41/42] only run on merge to main --- .github/workflows/run-samples.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 67a42e8..5ce86f4 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -12,8 +12,6 @@ concurrency: cancel-in-progress: true on: - push: - branches: [ '**' ] pull_request: branches: [ main ] workflow_dispatch: From 2d81738896fc998baf5491e2d9141b5e9b2e5c62 Mon Sep 17 00:00:00 2001 From: "Dris.S" Date: Tue, 13 Jan 2026 20:24:26 +0000 Subject: [PATCH 42/42] increase localstack start time to 120 s --- .github/workflows/run-samples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-samples.yml b/.github/workflows/run-samples.yml index 5ce86f4..31f37bb 100644 --- a/.github/workflows/run-samples.yml +++ b/.github/workflows/run-samples.yml @@ -90,7 +90,7 @@ jobs: run: | source .venv/bin/activate python -m localstack.cli.main start -d - python -m localstack.cli.main wait -t 60 + python -m localstack.cli.main wait -t 120 env: IMAGE_NAME: ${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }} LOCALSTACK_AUTH_TOKEN: ${{ secrets.TEST_LOCALSTACK_AUTH_TOKEN }}