Skip to content

Send the cluster's logs and metrics to Log Analytics, and deploy the cluster with Bicep or Terraform - #50

Merged
paolosalvatori merged 4 commits into
mainfrom
diagnostic-settings-and-iac-cluster
Oct 30, 2026
Merged

paolosalvatori merged 4 commits into
mainfrom
diagnostic-settings-and-iac-cluster

Conversation

@paolosalvatori

@paolosalvatori paolosalvatori commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

The cluster scripts create a Log Analytics workspace, but no diagnostic settings, so the platform logs and metrics of the cluster's resources never reach it.
The only Bicep and Terraform code in the repository, under tutorials/, deploys a different cluster, with random names, no Bastion host, Managed OS disks and no autoscaler, on which the samples, which look up local-aks-test and localacrtest by name, cannot run.
This sends the logs and metrics of every resource of the cluster to the workspace, and adds Bicep and Terraform deployments of exactly the cluster the scripts create.

Fixes SMF-1011

Changes

  • scripts/01-system-assigned-managed-identity.sh, scripts/01-user-assigned-managed-identity.sh and scripts/01-configurable-cluster.sh create a diagnostic setting named default on the AKS cluster, the virtual network, the Bastion public IP address, the Bastion host, the container registry and the key vault. Each sends AllMetrics and the resource's main log categories to the cluster's workspace, the AKS control plane logs to resource-specific tables, with kube-audit-admin rather than kube-audit, whose volume Microsoft warns can be costly. The configurable script creates them only with monitoring on, and only for the resources it creates, and its dry run prints the commands. scripts/01-basic-cluster.sh is unchanged.
  • tests/test-diagnostic-settings.sh checks that every resource of the cluster has its default setting, and scripts/README.md documents the categories in a new Monitoring section.
  • bicep/ and terraform/ create the cluster of the system-assigned script or, with the UserAssigned identity type, the one of the user-assigned script: the same resources, names and defaults, the network option of the scripts' menu as an input, the diagnostic settings, the Container Insights data collection rule and association, and the role assignments the scripts and az aks create make, in the order they make them. Each has a deploy.sh that works on the emulator and on Azure, and a README with the parameters or variables mapped to the script variables they mirror, and the emulator notes.
  • The samples workflow adds a Bicep job and a Terraform job, which create the cluster with bicep/deploy.sh or terraform/deploy.sh and run only the Python web-app-managed-identity sample on it, to keep the run short; every sample still runs on the cluster the system-assigned script creates. Every job checks the diagnostic settings with tests/test-diagnostic-settings.sh. In changed mode, a change under bicep/ or terraform/ runs only that deployment's job.
  • The root README lists the two deployments and the diagnostic settings.

Tests

  • bash -n on every changed script, az bicep build without warnings, terraform fmt -check and terraform validate, actionlint, and the repository's pre-commit hooks (zizmor, gitleaks).
  • On the emulator, each of the three scripts on a fresh emulator, then tests/test-diagnostic-settings.sh: no setting missing, and a second run of each script finds them all. The test failed on all six resources before the scripts created the settings. The configurable script's dry runs print six settings by default, none with monitoring off, and only the cluster's and the registry's without the virtual network and the key vault.
  • On the emulator, a normalized inventory of each cluster (resources, cluster settings, node pools, role assignments, diagnostic settings) diffed against the one the scripts create, for both identity types: the Bicep cluster has no difference; the Terraform cluster differs only in what azurerm adds, listed in terraform/README.md. A second run of each deploy.sh keeps the cluster's Kubernetes version and replaces nothing.
  • Every sample, in Python and .NET, deployed with its scripts and checked with tests/test-vacation-planner.sh, one after the other on a Bicep cluster and on a Terraform cluster, each on a fresh emulator: all 20 apps pass on each cluster, and so does the in-cluster PostgreSQL app, deployed twice more in each language on each cluster.
  • On Azure, bicep/deploy.sh and terraform/deploy.sh with both identity types, and the system-assigned script: every deployment succeeds, tests/test-diagnostic-settings.sh finds the setting on all six resources, so Azure accepted every log category, and kubectl reaches the nodes through kubelogin. All the resources were deleted afterwards.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NGfV8ZjaYFYFbgQDLnwhWt

paolosalvatori and others added 2 commits October 30, 2026 09:09
The system-assigned, user-assigned and configurable cluster scripts create a
diagnostic setting named default on the AKS cluster, the virtual network, the
Bastion public IP address, the Bastion host, the container registry and the key
vault, which sends AllMetrics and the resource's main log categories to the
cluster's Log Analytics workspace. The configurable script creates them only
with monitoring on, and only for the resources it creates.
tests/test-diagnostic-settings.sh checks that every resource of the cluster has
its setting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGfV8ZjaYFYFbgQDLnwhWt
bicep/ and terraform/ create the cluster of the system-assigned script or, with
the UserAssigned identity type, the one of the user-assigned script: the same
resources, names and defaults, diagnostic settings included, on the emulator
and on Azure, so every sample runs on them as on a cluster the scripts create.

The samples workflow adds a Bicep and a Terraform job, which create the cluster
with bicep/deploy.sh or terraform/deploy.sh and run only the Python
web-app-managed-identity sample on it, and every job checks the diagnostic
settings of the cluster's resources.

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

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

Missing network-role dependencies in Terraform and Bicep allow user-assigned AKS clusters and user node pools to deploy before required permissions are granted, risking subnet authorization failures on fresh deployments.

4 open issues
What changed in this PR

This PR adds platform logging and metrics to the sample AKS infrastructure and introduces Bicep and Terraform deployments aligned with the existing cluster scripts.

Changes:

  • Adds diagnostic settings for six resource types, with AKS logs routed to resource-specific Log Analytics tables.
  • Adds modular Bicep and Terraform deployments supporting both cluster identity types, plus deployment scripts and documentation.
  • Extends CI with deployment-specific sample runs and diagnostic-setting checks.
File Description
tests/​test-diagnostic-settings.sh Checks diagnostic settings on deployed resources.
terraform/​variables.tf Defines deployment inputs and defaults.
terraform/​terraform.tfvars Supplies script-aligned default values.
terraform/​README.md Documents deployment, configuration, and emulator behavior.
terraform/​providers.tf Configures Azure and emulator providers.
terraform/​outputs.tf Exposes deployed resource names.
terraform/​modules/​virtual_network/​variables.tf Defines network and monitoring inputs.
terraform/​modules/​virtual_network/​outputs.tf Exposes network and subnet identifiers.
terraform/​modules/​virtual_network/​main.tf Creates subnets, storage endpoints, and diagnostics.
terraform/​modules/​log_analytics/​variables.tf Defines workspace inputs.
terraform/​modules/​log_analytics/​outputs.tf Exposes workspace identifiers.
terraform/​modules/​log_analytics/​main.tf Creates the shared monitoring workspace.
terraform/​modules/​key_vault/​variables.tf Defines vault and monitoring inputs.
terraform/​modules/​key_vault/​outputs.tf Exposes vault identifiers.
terraform/​modules/​key_vault/​main.tf Creates the RBAC-enabled vault and diagnostics.
terraform/​modules/​container_registry/​variables.tf Defines registry and monitoring inputs.
terraform/​modules/​container_registry/​outputs.tf Exposes registry identifiers.
terraform/​modules/​container_registry/​main.tf Creates the sample registry and diagnostics.
terraform/​modules/​bastion_host/​variables.tf Defines Bastion networking and monitoring inputs.
terraform/​modules/​bastion_host/​outputs.tf Exposes Bastion and public IP identifiers.
terraform/​modules/​bastion_host/​main.tf Creates Bastion, its public IP, and diagnostics.
terraform/​modules/​aks_node_pool/​variables.tf Defines user-pool settings.
terraform/​modules/​aks_node_pool/​outputs.tf Exposes user-pool identifiers.
terraform/​modules/​aks_node_pool/​main.tf Creates the autoscaling user node pool.
terraform/​modules/​aks_cluster/​variables.tf Defines cluster configuration inputs.
terraform/​modules/​aks_cluster/​outputs.tf Exposes cluster and identity identifiers.
terraform/​modules/​aks_cluster/​main.tf Creates AKS, add-ons, and monitoring resources.
terraform/​main.tf Connects modules, identities, permissions, and Gateway API.
terraform/​deploy.sh Automates deployment to Azure or the emulator.
scripts/​README.md Documents monitoring categories and configuration.
scripts/​01-user-assigned-managed-identity.sh Adds diagnostics to the user-assigned deployment.
scripts/​01-system-assigned-managed-identity.sh Adds diagnostics to the system-assigned deployment.
scripts/​01-configurable-cluster.sh Adds monitoring-aware, conditional diagnostic setup.
README.md Introduces infrastructure deployments and monitoring checks.
bicep/​README.md Documents parameters, deployment, and verification.
bicep/​modules/​virtual-network.bicep Creates the network, subnets, and diagnostics.
bicep/​modules/​managed-identity.bicep Creates the optional user-assigned cluster identity.
bicep/​modules/​log-analytics.bicep Creates the shared monitoring workspace.
bicep/​modules/​key-vault.bicep Creates the RBAC-enabled vault and diagnostics.
bicep/​modules/​container-registry.bicep Creates the sample registry and diagnostics.
bicep/​modules/​bastion-host.bicep Creates Bastion, its public IP, and diagnostics.
bicep/​modules/​aks-node-pool.bicep Creates the autoscaling user node pool.
bicep/​modules/​aks-cluster.bicep Creates AKS, add-ons, and monitoring resources.
bicep/​main.bicepparam Supplies defaults and reads the deployment password.
bicep/​main.bicep Connects infrastructure modules and role assignments.
bicep/​deploy.sh Validates and deploys the Bicep infrastructure.
.github/​workflows/​run-samples.yml Adds deployment-specific jobs and diagnostic checks.

Review effort: Balanced

Comment thread bicep/main.bicep Resolved
Comment thread bicep/main.bicep Resolved
Comment thread terraform/main.tf Resolved
Comment thread terraform/main.tf Resolved
paolosalvatori and others added 2 commits October 30, 2026 10:00
With a user-assigned identity, the Bicep and Terraform deployments grant it
Network Contributor on SystemSubnet before they create the cluster, as
az aks create --assign-identity --vnet-subnet-id does, and they add the user
node pool only once the cluster identity holds Network Contributor on the
virtual network, which the scripts grant before az aks nodepool add.

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

Today's emulator image returns the Windows profile of the cluster that the
scripts, Bicep and Terraform create. The Bicep README no longer says it is
missing. The Terraform README and the cluster module say it is missing only
on earlier versions, which the ignore_changes on it still covers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGfV8ZjaYFYFbgQDLnwhWt
@paolosalvatori
paolosalvatori merged commit 69bf446 into main Oct 30, 2026
25 checks passed
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