Skip to content

Add configurable and basic AKS cluster scripts and seed the blob samples - #46

Merged
paolosalvatori merged 11 commits into
mainfrom
aks-cluster-scripts
Oct 22, 2026
Merged

paolosalvatori merged 11 commits into
mainfrom
aks-cluster-scripts

Conversation

@paolosalvatori

@paolosalvatori paolosalvatori commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes SMF-969

Changes

Two new cluster scripts next to the two production-like ones, a kubelogin check in all four, three sample activities in the two blob samples, PostgreSQL 18 in the three PostgreSQL samples, and the Terraform tutorial on azurerm 5.

 scripts/
+├── 01-basic-cluster.sh                      # no questions: the fastest cluster that runs the samples, for demos
+├── 01-configurable-cluster.sh               # asks which features to provision; Enter at every question = the originals
+├── README.md                                # what each cluster script provisions, and the configurable script's variables
 ├── 01-system-assigned-managed-identity.sh   # + warns when kubelogin is missing
 └── 01-user-assigned-managed-identity.sh     # + warns when kubelogin is missing
 samples/
 ├── web-app-blob-storage/*/scripts/01-deploy-resources.sh       # + uploads 3 sample activities
 ├── web-app-managed-identity/*/scripts/01-deploy-resources.sh   # + uploads 3 sample activities
 ├── web-app-postgresql-flexible-server/*/scripts/00-variables.sh # PG_VERSION 16 -> 18
 ├── web-app-app-configuration/*/scripts/00-variables.sh         # PG_VERSION 16 -> 18
 ├── web-app-in-cluster-postgresql/*/scripts/statefulset.yml     # postgres:16 -> postgres:18
 └── */*/scripts/01-deploy-resources.sh       # --admin-enabled "true" -> --admin-enabled true (20 files, same behavior)
 tutorials/terraform/tags-labels-taints/      # azurerm 5.10.0 and azapi 2.13.0
 README.md                                    # the cluster-script table lists all four scripts
  • scripts/01-configurable-cluster.sh asks, or reads from environment variables, which features to provision: identity, network plugin and policy, cluster autoscaler, Workload ID, Key Vault with the CSI secrets provider, Container Insights, custom virtual network and Bastion, user node pool and availability zones, KEDA, Gateway API (optionally with NGINX Gateway Fabric and cert-manager), Entra ID with Azure RBAC, and the Azure Files and Azure Disk CSI drivers.
    • Pressing Enter at every question provisions the original scripts' features.
    • --dry-run prints every command and runs none; --yes runs unattended.
    • Independent resources are created in parallel, and Bastion off the critical path.
    • If local-aks-test already exists with a different configuration, including other Entra ID admin groups or other node pool sizes (the node count, or the autoscaler range when the autoscaler is on), it stops before creating anything and lists the differences.
  • scripts/01-basic-cluster.sh asks nothing: system-assigned identity, Azure CNI Overlay with the Azure network policy, one node with the cluster autoscaler (1 to 3 nodes), Workload ID, Entra ID with Azure RBAC (admin groups from AAD_ADMIN_GROUP_OBJECT_IDS), ACNS and the attached registry.
    • The Azure Files and Azure Disk CSI drivers and the snapshot controller are off to save provisioning time, so web-app-file-storage and web-app-in-cluster-postgresql do not run on it.
    • No virtual network, Bastion, Key Vault, Log Analytics, user node pool, KEDA or Gateway API.
    • If local-aks-test already exists with other settings, including other Entra ID admin groups, it stops before creating anything and lists the differences.
  • kubelogin: with Entra ID, kubectl on Azure signs in through kubelogin. All four scripts warn when it is missing; it is only a warning, because the emulator and this CI do not need it. When the final kubectl call of a new script fails, the script says what Azure needs: kubelogin and an account in one of the admin groups.
  • Blob samples: after creating the activities container, 01-deploy-resources.sh uploads three activities, one blob each, with the names and texts web-app-file-storage seeds, so the app does not start empty. A re-run uploads only the missing ones.
  • PostgreSQL 18: web-app-postgresql-flexible-server and web-app-app-configuration create their flexible server with version 18, generally available on Azure since January 2026 and the engine the emulator runs for every flexible server. web-app-in-cluster-postgresql runs the postgres:18 image; its StatefulSet sets PGDATA explicitly, so the image's new default data directory does not apply.
  • Terraform tutorial: tutorials/terraform/tags-labels-taints moves from azurerm 4.81.0 and azapi 2.10.0 to azurerm 5.10.0 and azapi 2.13.0. azurerm 5 requires a node_provisioning_profile block, set to mode = "Manual", the AKS default, so the cluster does not change. It also no longer registers resource providers by default, so on Azure the stack sets resource_provider_registrations = "legacy", the 4.x behaviour.

Evidence

On the LocalStack for Azure emulator:

  • Before: the CI's cluster command, printf '1\n\n\n' | ./01-system-assigned-managed-identity.sh, took 456 s.
    After: ./01-basic-cluster.sh --yes took 155 to 180 s, over 9 runs.
  • Each of these Python samples passed tests/test-vacation-planner.sh on its own new basic cluster: app-configuration, blob-storage, cosmosdb-mongodb-api, cosmosdb-nosql-api, managed-identity, mysql-flexible-server, postgresql-flexible-server, sql-database.
  • ./01-configurable-cluster.sh --yes </dev/null provisioned the original scripts' features. Run against a basic cluster with the Azure Files driver wanted, it turned the driver on in place.
  • With kubelogin missing from PATH, the CI's cluster command printed the warning first and still finished with exit 0.
  • Re-runs against an existing basic cluster: the same settings report a match and carry on. Other AAD_ADMIN_GROUP_OBJECT_IDS stop the run with Entra ID admin groups: cluster has [...], this run wants [...]. 01-configurable-cluster.sh with SYSTEM_NODE_COUNT=5 stops with System pool autoscaler range: cluster has [1-3], this run wants [1-5].
  • Terraform tutorial with azurerm 5.10.0: deploy.sh passed 25 of its 26 checks. The failing one, a no-op plan right after apply, is documented in deploy.sh as failing on the emulator. web-app-managed-identity passed tests/test-vacation-planner.sh on that cluster, and terraform destroy removed all 16 resources.
  • shellcheck reports nothing on the two new scripts.
  • CI on b9e795b: all 20 sample jobs passed (run). The four blob sample jobs each uploaded the three activities. Every job printed the kubelogin warning, because the runners have no kubelogin, and still passed.

Nothing was run on Azure.

Merge Danger

Door: two-way

The new scripts are opt-in, and the other changes add to existing scripts.

Blast Radius: small

  • The PR changes scripts/01-system-assigned-managed-identity.sh, so CI runs all 20 sample jobs.
  • The two blob samples' 01-deploy-resources.sh now stop with exit 1 when a sample upload fails.
  • The Terraform tutorial moves azurerm up a major version, so its first terraform init after this change needs -upgrade (its deploy.sh already passes it).

🤖 Generated with Claude Code

https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ

paolosalvatori and others added 7 commits October 21, 2026 19:09
01-configurable-cluster.sh asks which optional features to provision,
with a default and an environment variable for every question; pressing
Enter provisions the same features as the two existing cluster scripts.
It supports --dry-run and --yes, creates independent resources in
parallel, and stops before creating anything when an existing cluster
was built with different answers.

01-basic-cluster.sh creates the smallest cluster that runs every
sample's default path, without questions.

scripts/README.md documents the scripts and the variables, and the root
README lists the new scripts. The existing scripts are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
01-basic-cluster.sh now passes --disable-file-driver, --disable-disk-driver
and --disable-snapshot-controller to save provisioning time, and enables
Microsoft Entra ID authentication with Azure RBAC, with the admin groups
taken from AAD_ADMIN_GROUP_OBJECT_IDS. It no longer runs the step that
re-enabled the Azure Files driver, and it warns that the Azure Files and
in-cluster PostgreSQL samples need the drivers it turns off.

01-configurable-cluster.sh asks whether to enable the Azure Files and the
Azure Disk CSI drivers, both defaulting to yes. Both scripts compare the
two drivers when they find an existing cluster.

The samples' 01-deploy-resources.sh scripts pass --admin-enabled true
without quotes, as the cluster scripts do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
01-basic-cluster.sh now creates its node pool with the cluster autoscaler,
between 1 and 3 nodes as in the original scripts, so the cluster grows when
several samples share it. The summary, the existing-cluster check and both
READMEs say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
…lace

Both cluster scripts warn when kubelogin is missing (the configurable one
only with Entra ID on), because on Azure kubectl signs in to a cluster with
Entra ID through it. When the final kubectl call cannot reach the cluster,
they now say what is needed: kubelogin and an account in one of the admin
groups. Both READMEs say the same.

The configurable script's existing-cluster check no longer rejects a
cluster whose Azure Files CSI driver is off when the run wants it on: the
repair step turns the driver on with az aks update, as the original
scripts do. It also adds the Microsoft.Storage service endpoint only with
the Azure Files CSI driver, whose NFS volumes are its only user.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
Both original cluster scripts enable Entra ID, so on Azure kubectl signs in
to the cluster through kubelogin. They now print the same warning as the
configurable and basic scripts when it is not installed. It is a warning,
not an error: the emulator does not need kubelogin, and the samples
workflow runs 01-system-assigned-managed-identity.sh without it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
01-deploy-resources.sh, Python and .NET, now uploads three sample
activities to the activities container right after creating it, so the
app does not start with an empty list. Each one is a blob in the format
the app reads and writes, YYYY-MM-DD-HH-MM-SS-activity.txt holding the
activity text, with the names and texts the web-app-file-storage sample
seeds. The names are fixed, so a re-run uploads only the missing ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
01-deploy-resources.sh, Python and .NET, now uploads the same three sample
activities as the managed identity sample right after creating the
activities container, one blob each in the format the app reads and
writes, so the app does not start with an empty list. A re-run uploads
only the missing ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
Copilot AI balanced review requested due to automatic review settings October 22, 2026 12:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Existing-cluster checks silently accept administrator-group and node-sizing changes without applying them or reporting mismatches.

2 open issues
What changed in this PR

Adds lightweight and configurable AKS provisioning options alongside the existing full-cluster scripts, and seeds the blob-backed samples so they start with example activities.

Changes:

  • Adds basic and configurable cluster scripts with dry-run support, existing-cluster checks, and feature documentation.
  • Adds missing-kubelogin warnings to the original cluster scripts.
  • Seeds three activities in the Python and .NET blob-backed samples and normalizes registry flags without changing their behavior.
File Description
scripts/​README.md Documents cluster options, variables, and sample requirements.
scripts/​01-user-assigned-managed-identity.sh Adds a missing-kubelogin warning.
scripts/​01-system-assigned-managed-identity.sh Adds a missing-kubelogin warning.
scripts/​01-configurable-cluster.sh Adds configurable provisioning and parallel resource creation.
scripts/​01-basic-cluster.sh Adds lightweight demo-cluster provisioning.
samples/​web-app-sql-database/​python/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-sql-database/​dotnet/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-postgresql-flexible-server/​python/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-postgresql-flexible-server/​dotnet/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-mysql-flexible-server/​python/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-mysql-flexible-server/​dotnet/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-managed-identity/​python/​scripts/​01-deploy-resources.sh Seeds missing activities and normalizes the registry flag.
samples/​web-app-managed-identity/​python/​README.md Documents activity seeding.
samples/​web-app-managed-identity/​dotnet/​scripts/​01-deploy-resources.sh Seeds missing activities and normalizes the registry flag.
samples/​web-app-managed-identity/​dotnet/​README.md Documents activity seeding.
samples/​web-app-in-cluster-postgresql/​python/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-in-cluster-postgresql/​dotnet/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-file-storage/​python/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-file-storage/​dotnet/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-cosmosdb-nosql-api/​python/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-cosmosdb-nosql-api/​dotnet/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-cosmosdb-mongodb-api/​python/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-cosmosdb-mongodb-api/​dotnet/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-blob-storage/​python/​scripts/​01-deploy-resources.sh Seeds missing activities and normalizes the registry flag.
samples/​web-app-blob-storage/​python/​README.md Documents activity seeding.
samples/​web-app-blob-storage/​dotnet/​scripts/​01-deploy-resources.sh Seeds missing activities and normalizes the registry flag.
samples/​web-app-blob-storage/​dotnet/​README.md Documents activity seeding.
samples/​web-app-app-configuration/​python/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
samples/​web-app-app-configuration/​dotnet/​scripts/​01-deploy-resources.sh Normalizes the registry admin flag.
README.md Introduces all four cluster scripts and authentication requirements.

Review effort: Balanced

Comment thread scripts/01-configurable-cluster.sh
Comment thread scripts/01-configurable-cluster.sh
paolosalvatori and others added 4 commits October 22, 2026 15:40
When local-aks-test already exists, 01-basic-cluster.sh and
01-configurable-cluster.sh now compare its Entra ID admin groups with
AAD_ADMIN_GROUP_OBJECT_IDS, in any order and letter case, and stop before
creating anything when they differ. A re-run with other groups used to
report a match and leave the old groups in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
When local-aks-test already exists, 01-configurable-cluster.sh now
compares each node pool's size with the answers before creating anything:
the autoscaler range when the autoscaler is on, since the autoscaler
itself changes the node count, and the node count when it is off. It
checks the user pool when the cluster has one and the run wants one. A
re-run with another node count used to report a match and change nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
tutorials/terraform/tags-labels-taints pinned azurerm 4.81.0 and azapi
2.10.0. azurerm 5 needs two changes to keep the same cluster:

- azurerm_kubernetes_cluster now requires a node_provisioning_profile
  block. It is set to mode = "Manual", the AKS default, so node
  auto-provisioning stays off as before.
- The provider no longer registers resource providers by default. On
  Azure the stack sets resource_provider_registrations = "legacy", the
  4.x behaviour; the emulator keeps "none".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
web-app-postgresql-flexible-server and web-app-app-configuration now
create their flexible server with PG_VERSION 18, generally available on
Azure since January 2026 and the engine the emulator runs for every
flexible server. web-app-in-cluster-postgresql runs the postgres:18
image: its StatefulSet sets PGDATA explicitly, so the image's new default
data directory does not apply.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kq47SouBiqFa1ffW7jEDQ
@paolosalvatori
paolosalvatori merged commit 4703cd8 into main Oct 22, 2026
22 checks passed
@paolosalvatori
paolosalvatori deleted the aks-cluster-scripts branch October 22, 2026 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants