Skip to content

feat(azure): foundations module — VNet, AKS Standard + NAP, identities - #25

Open
Garinlu wants to merge 6 commits into
mainfrom
feat/azure-foundations-module
Open

Garinlu wants to merge 6 commits into
mainfrom
feat/azure-foundations-module

Conversation

@Garinlu

@Garinlu Garinlu commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • The Azure sprint's deliverable: opentofu/azure/ — VNet, AKS Standard + Node Auto-Provisioning cluster, identities, built on the sprint's four research docs (docs(azure): decide Standard + NAP over AKS Automatic #21, docs(azure): decide the managed scope for upgrades, add-ons, identity #22, docs(azure): decide network & security baseline #23, docs(azure): cloud observability — supervision hors K8s (offre B) #24, all merged).
  • Every decision traces to a doc: sku_tier = "Standard" + node_provisioning_profile { mode = "Auto" }, network_plugin = "none" (BYO CNI, Cilium installed later by the factory), automatic_upgrade_channel = "stable" + KubernetesOfficial support plan, private cluster with the public FQDN disabled, Entra Workload ID, Managed Prometheus + Container Insights.
  • Two things decided during implementation, not in the research docs: Deployment Safeguards has no azurerm attribute (4.x series) and no open-source GitOps equivalent, so it's left out of this empty-shell module rather than guessed at via azapi; Microsoft Defender for Containers is a subscription-level singleton (same shape as AWS's GuardDuty), so it's excluded entirely rather than exposed as a variable.
  • examples/minimal, tests/ (12 tofu test runs — mocked, since azurerm has no offline-plan path the way aws/google do), and tests/emulator (a fixture wrapping the module for CI, required because azurerm has no environment-only configuration path either).
  • CI: integration.yaml's azure leg points at the fixture and enables TLS on floci-az. Known red, not blocking (continue-on-error): floci-az's self-signed certificate fails Go's x509 validation, so the plan fails at provider configuration, before any resource — a floci-az bug, not something this repo can fix.
  • Validated against a real Azure subscription (Socle-staging, examples/minimal, francecentral): full apply succeeded — resource group, VNet, NAT Gateway, private AKS cluster, Container Insights, Managed Prometheus. Surfaced and fixed one genuine bug: default_node_pool.upgrade_settings gets server-side defaults from AKS regardless of whether it's declared, producing a perpetual plan diff — now declared explicitly. Also exposed zones and system_node_pool_vm_size as passthrough variables on examples/minimal, since both are subscription/region-specific in practice (VM family quota and AZ support vary per subscription — hit both during this validation).
  • Addressed the three Trivy code-scanning findings: RBAC (already the provider default, now declared explicitly) fixed directly; network policy and disk encryption set suppressed with #trivy:ignore + inline rationale, matching the pattern already used in opentofu/aws/cluster.tf and opentofu/gcp/cluster.tf (network_policy has no valid value under BYO CNI; a customer-managed disk encryption key is a client's own compliance choice, same class as Defender).

Test plan

  • tofu fmt -check -recursive, tofu validate — module root and examples/minimal
  • tofu test — 12/12 passing
  • tflint (real tflint-ruleset-azurerm 0.32.0) — clean
  • terraform-docs --output-check — clean, both locations
  • actionlint / yamllint on integration.yaml — clean
  • trivy config — 0 misconfigurations (verified locally and in CI)
  • Real Azure sandbox: tofu apply/destroy against a live subscription — succeeded, one real bug found and fixed
  • floci-az emulator leg — known red (TLS certificate bug in floci-az itself, outside this repo's control); what a working plan would additionally surface (real VNet/AKS/Monitor resource acceptance) stays untested

🤖 Generated with Claude Code

Garinlu and others added 3 commits September 15, 2026 16:44
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
azurerm has no environment-only config path (unlike aws), so the bare
module can't be planned against the emulator directly — a fixture with
its own provider block is the only option, same shape as GCP's. The
plan still fails at provider configuration: floci-az's self-signed TLS
cert fails Go's x509 validation, a floci-az bug outside this repo's
control. continue-on-error keeps it from blocking unrelated PRs while
it's outstanding.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The README still said "no fixture directory" after the emulator fixture
landed, and didn't mention the known TLS failure.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Comment thread opentofu/azure/cluster.tf Fixed
Comment thread opentofu/azure/cluster.tf Fixed
Comment thread opentofu/azure/cluster.tf Fixed
Comment thread opentofu/azure/cluster.tf Fixed
Comment thread opentofu/azure/cluster.tf Fixed
Comment thread opentofu/azure/cluster.tf Fixed
@Garinlu
Garinlu marked this pull request as draft September 16, 2026 12:24
Garinlu and others added 3 commits September 17, 2026 11:11
…rrides

Real-sandbox validation (first tofu apply against a live subscription)
surfaced a genuine perpetual-diff bug: AKS assigns default_node_pool's
upgrade_settings server-side defaults regardless of whether the block is
declared, so an undeclared block produced a permanent plan diff. Declared
it explicitly, matching Azure's own default, so plan converges.

Also surfaced that examples/minimal had no way to override zones or the
system node pool's vm_size without editing the file — both are
subscription/region-specific in practice (VM family quota and AZ support
vary per subscription), so exposed them as passthrough variables like
every other module input.

Fixed a pre-existing tofu fmt drift in tests/emulator/main.tf found along
the way.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
RBAC (AZU-0042): already the provider's default and has been mandatory on
AKS for years — declared explicitly so the scanner sees what the API
already returns, no behavior change.

Network policy (AZU-0043) and disk encryption set (AZU-0067): both
structurally out of scope for this empty-shell module. network_policy has
no valid value under BYO CNI (network_plugin = "none" only pairs with
"azure"); Cilium is the real enforcement once the factory installs it. A
customer-managed disk encryption key is a client's own compliance choice
on their own Key Vault, the same class of call as Defender for Containers.
Both suppressed with #trivy:ignore and argued inline, matching the pattern
already used in opentofu/aws/cluster.tf and opentofu/gcp/cluster.tf.

Verified locally with trivy config: 0 misconfigurations.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Garinlu Garinlu self-assigned this Sep 17, 2026
@Garinlu
Garinlu marked this pull request as ready for review September 17, 2026 09:58
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