Infrastructure as Code for Azure — Terraform modules, Azure Verified Modules (AVM), Helm/Kustomize deployments, AKS Deployment Safeguards, azd integration, and systematic debugging. Use when working with Terraform, AVM, azurerm, azapi, helm_release, kubernetes_manifest, AKS safeguards, deployment failures, policy violations, infrastructure verification, or any IaC architecture decisions. Also use for debugging infrastructure issues and verifying deployments are complete. Not for: application code, OSDU service APIs, CI/CD pipeline execution, or project-specific setup (use the setup skill for missing CLI tools).
Terraform, Helm, and Kubernetes infrastructure for Azure, with systematic debugging and evidence-based verification.
Before first use, verify tools are available:
terraform --version && helm version --short && kubectl version --client
If any command is not found, stop and use the setup skill to install missing dependencies.
Do NOT attempt to install tools yourself — the setup skill handles installation with the correct
sources, user approval, and verification.
If installed, go straight to the section you need below.
Two-layer Terraform architecture managed by azd:
project-root/
├── azure.yaml # azd project definition
├── infra/ # Layer 1: Azure infrastructure (azd-managed)
│ ├── main.tf # Root module — calls AVM modules
│ ├── variables.tf # Input variables
│ ├── outputs.tf # Outputs consumed by platform layer
│ ├── versions.tf # Provider version constraints
│ ├── provider.tf # Provider configuration + backend
│ └── modules/ # Local modules wrapping AVM
├── platform/ # Layer 2: Kubernetes workloads
│ ├── main.tf # Helm releases, K8s resources
│ └── kustomize/ # Postrender overlays
└── scripts/ # PowerShell automation (azd hooks)
Key separation:
Always prefer AVM over hand-written resources:
module "aks" {
source = "Azure/avm-res-containerservice-managedcluster/azurerm"
version = "0.5.2"
name = "aks-${var.environment}"
resource_group_name = azurerm_resource_group.this.name
location = var.location
managed_identities = { system_assigned = true }
tags = var.tags
}
AVM standard interfaces: tags, managed_identities, diagnostic_settings,
role_assignments, lock, private_endpoints, customer_managed_key.
For detailed AVM patterns: references/avm-patterns.md
terraform {
required_version = ">= 1.5.0"
required_providers {
azurerm = { source = "hashicorp/azurerm", version = ">= 4.0, < 5.0" }
azapi = { source = "Azure/azapi", version = ">= 2.0, < 3.0" }
}
}
Use azapi for day-zero resources or features not yet in azurerm.
Resource block ordering: count/for_each → required args → optional args → tags → depends_on → lifecycle
Naming: azurerm_resource_group.this (singleton), var.resource_group_name, underscores not hyphens.
Count vs for_each: count for boolean toggles, for_each for named collections.
# azure.yaml