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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 42 additions & 14 deletions .github/workflows/run-samples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ name: Test samples on LocalStack for Azure
# app with its numbered scripts, one job per app and platform, and checks the app end to end with
# tests/test-vacation-planner.sh. As in the Samples CI of localstack-azure-samples, a pull request or a
# push runs the apps it changes (every app when a file all of them use changes), and a manual run can
# choose to run every app, on Linux, on Windows or on both.
# choose to run every app, on Linux, on Windows or on both. Two more jobs create the cluster with bicep/
# and with terraform/ instead of the script, and deploy and check one app on each. Every job checks the
# diagnostic settings of the cluster's resources with tests/test-diagnostic-settings.sh.

on:
push:
Expand Down Expand Up @@ -76,6 +78,8 @@ jobs:
# Every app a job can deploy, as samples/<sample>/<language>, so a new sample needs no change here
apps=$(printf '%s\n' samples/*/*/scripts/05-deploy-app.sh | sed 's|/scripts/05-deploy-app\.sh$||')
selected=$apps
# The Bicep and Terraform deployments of the cluster, each checked with one app
deployments="bicep terraform"

if [ "$RUN_MODE" = changed ]; then
case $EVENT_NAME in
Expand All @@ -87,14 +91,18 @@ jobs:
changed=$(git diff --name-only "$base...HEAD")
echo "Files changed since $base:"
echo "$changed"
# Every job creates the cluster with the same script and checks the app with the same test, so a
# change to either, or to this workflow, runs every app; otherwise an app runs when its folder changes
shared='^(scripts/01-system-assigned-managed-identity\.sh|tests/test-vacation-planner\.sh|\.github/workflows/run-samples\.yml)$'
# Every job creates the cluster with the same script and checks it and the app with the same tests, so
# a change to any of them, or to this workflow, runs every app; otherwise an app runs when its folder changes
shared='^(scripts/01-system-assigned-managed-identity\.sh|tests/test-vacation-planner\.sh|tests/test-diagnostic-settings\.sh|\.github/workflows/run-samples\.yml)$'
if ! grep -q -E "$shared" <<< "$changed"; then
selected=$(while read -r app; do
if grep -q "^$app/" <<< "$changed"; then echo "$app"; fi
done <<< "$apps")
fi
# A deployment runs when its folder, one of the tests or this workflow changes
deployments=$(for deployment in bicep terraform; do
if grep -q -E "^($deployment/|tests/|\.github/workflows/run-samples\.yml$)" <<< "$changed"; then echo "$deployment"; fi
done)
else
# A push that creates the branch or rewrites its history leaves no base commit to compare with
echo "Base commit '$base' not found: running every sample"
Expand All @@ -106,15 +114,19 @@ jobs:
*) echo "::error::Unknown platform '$PLATFORM' (expected Linux, Windows or all)"; exit 1 ;;
esac

# One job per app and platform: the entry names the runner and the job, so a run lists only the jobs
# it runs, under their own names
matrix=$(jq -n -R -c --arg platform "$PLATFORM" '
[inputs | select(length > 0) | split("/") | {sample: .[1], language: .[2]}] as $apps
# One job per app and platform, and one per deployment and platform: the entry names the runner and the
# job, so a run lists only the jobs it runs, under their own names. The script creates the cluster of the
# app jobs; each deployment job creates it with bicep/ or terraform/ and checks web-app-managed-identity
matrix=$(jq -n -R -c --arg platform "$PLATFORM" --arg deployments "$deployments" '
([inputs | select(length > 0) | split("/") | {sample: .[1], language: .[2], provisioning: "script", cluster: ""}]
+ [$deployments | splits("\\s+") | select(length > 0)
| {sample: "web-app-managed-identity", language: "python", provisioning: .,
cluster: (if . == "bicep" then "Bicep cluster: " else "Terraform cluster: " end)}]) as $jobs
| {include: (
(if $platform == "Windows" then [] else
[$apps[] | . + {os: "linux", runner: "ubuntu-latest", name: "\(.sample) (\(.language))"}] end)
[$jobs[] | . + {os: "linux", runner: "ubuntu-latest", name: "\(.cluster)\(.sample) (\(.language))"}] end)
+ (if $platform == "Linux" then [] else
[$apps[] | . + {os: "windows", runner: "windows-latest", name: "Windows (Git Bash) \(.sample) (\(.language))"}] end)
[$jobs[] | . + {os: "windows", runner: "windows-latest", name: "Windows (Git Bash) \(.cluster)\(.sample) (\(.language))"}] end)
)}' <<< "$selected")
echo "Jobs to run: $(jq -r '[.include[].name] | if length > 0 then join(", ") else "none" end' <<< "$matrix")"
{
Expand Down Expand Up @@ -147,6 +159,7 @@ jobs:
env:
SAMPLE: ${{ matrix.sample }}
LANGUAGE: ${{ matrix.language }}
PROVISIONING: ${{ matrix.provisioning }}

steps:
- name: Check out repo
Expand Down Expand Up @@ -347,11 +360,26 @@ jobs:
fi
lstk az start-interception

# The script prompts for the network configuration and both node pool sizes:
# pick option 1 (Azure network plugin and policy) and keep the default sizes
- name: Set up Terraform
if: matrix.provisioning == 'terraform'
uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1
with:
# deploy.sh runs terraform itself: the wrapper only serves steps that read terraform's outputs
terraform_wrapper: false

# The script prompts for the network configuration and both node pool sizes: pick option 1 (Azure network
# plugin and policy) and keep the default sizes. bicep/deploy.sh and terraform/deploy.sh default to the same.
- name: Create the AKS cluster
working-directory: scripts
run: printf '1\n\n\n' | ./01-system-assigned-managed-identity.sh
run: |
case $PROVISIONING in
script) (cd scripts && printf '1\n\n\n' | ./01-system-assigned-managed-identity.sh) ;;
bicep) bicep/deploy.sh ;;
terraform) terraform/deploy.sh ;;
*) echo "::error::Unknown provisioning '$PROVISIONING'"; exit 1 ;;
esac

- name: Check the diagnostic settings of the cluster's resources
run: tests/test-diagnostic-settings.sh

- name: Deploy the sample
working-directory: samples/${{ matrix.sample }}/${{ matrix.language }}/scripts
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,17 @@ Before deploying any sample you must first provision an AKS cluster. Four script

[scripts/README.md](scripts/README.md) details what each script provisions, which samples need which feature, and the variables of the configurable script.

The same full cluster can also be deployed as infrastructure as code. [bicep/](bicep/) and [terraform/](terraform/) create the cluster of `01-system-assigned-managed-identity.sh`, or with a user-assigned identity the one of `01-user-assigned-managed-identity.sh`, with the same names and defaults, so every sample runs on it:

| Deployment | Cluster identity | How to run it |
| ---------- | ---------------- | ------------- |
| [bicep/](bicep/README.md) | System-assigned, or user-assigned with `IDENTITY_TYPE=UserAssigned` | `cd bicep && ./deploy.sh` |
| [terraform/](terraform/README.md) | System-assigned, or user-assigned with `IDENTITY_TYPE=UserAssigned` | `cd terraform && ./deploy.sh` |

All four scripts are idempotent: they check whether each resource already exists before creating it, so they can be safely re-run. The two managed-identity scripts, and the configurable one with every default, provision the following building blocks:

- A resource group and a Log Analytics workspace (wired to the cluster through the monitoring add-on / Azure Monitor for containers).
- A diagnostic setting called `default` on the cluster, the virtual network, the Bastion host and its public IP address, the container registry and the key vault, which sends their logs and metrics to the workspace. See [Monitoring](scripts/README.md#monitoring).
- A dedicated virtual network (`10.0.0.0/8`) with three subnets: `SystemSubnet` (system node pool), `UserSubnet` (user node pool), and `AzureBastionSubnet`.
- An [Azure Bastion](https://learn.microsoft.com/en-us/azure/bastion/bastion-overview) host in `AzureBastionSubnet`, with the Standard SKU static public IP it requires, for reaching the nodes without exposing SSH to the internet. Creating it takes several minutes.
- An [Azure Container Registry (ACR)](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-intro) that is attached to the cluster (via `--attach-acr`) so nodes can pull images without extra credentials.
Expand Down Expand Up @@ -239,10 +247,11 @@ Alternatively, you can use a terminal UI such as [k9s](https://k9scli.io/) to se

The [Test samples on LocalStack for Azure](.github/workflows/run-samples.yml) workflow runs this against the emulator, one job per sample app, in Python and .NET. Each job creates the cluster with `scripts/01-system-assigned-managed-identity.sh`, deploys the app with its numbered scripts, and runs the test. A pull request or a push to `main` runs the apps whose folders it changes, and all 20 when it changes the cluster script, the test or the workflow. A manual run tests the changed apps by default, or all 20 with `run_mode: all`.
It also picks where they run with `platform`: `Linux` (the default), `Windows`, from Git Bash, or `all`, which runs both at once, in parallel jobs of the same run.
Two more jobs create the cluster with [bicep/](bicep/) and with [terraform/](terraform/) and deploy and test one app on each, `web-app-managed-identity` in Python. They run when their folder, the test scripts or the workflow change, and in every manual run with `run_mode: all`. Every job also checks the diagnostic settings of the cluster's resources with [tests/test-diagnostic-settings.sh](tests/test-diagnostic-settings.sh).

## Tutorials

Beyond the Vacation Planner samples, the repository includes standalone tutorials that exercise specific AKS capabilities. Unlike the samples above, they do not deploy the web app.
Beyond the Vacation Planner samples, the repository includes standalone tutorials that exercise specific AKS capabilities. Unlike the samples above, they do not deploy the web app. The Bicep and Terraform tutorials build their own feature-rich cluster, with other names and settings; to deploy the cluster the samples run on with Bicep or Terraform, use [bicep/](bicep/) and [terraform/](terraform/) instead.

| Tutorial | Description |
| ------ | ----------- |
Expand Down
Loading
Loading