From cimpl
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).
How this skill is triggered — by the user, by Claude, or both
Slash command
/cimpl:iacThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Terraform, Helm, and Kubernetes infrastructure for Azure, with systematic debugging
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
name: my-project
infra:
provider: terraform
azd runs terraform init/plan/apply, passes env vars as TF_VAR_*, stores state at .azure/<env>/infra/terraform.tfstate.
For complete azd details: references/azd-integration.md
resource "helm_release" "nginx_ingress" {
count = var.enable_nginx_ingress ? 1 : 0
name = "ingress-nginx"
repository = "https://kubernetes.github.io/ingress-nginx"
chart = "ingress-nginx"
version = "4.8.3"
namespace = "ingress-nginx"
create_namespace = true
values = [templatefile("${path.module}/values/nginx-ingress.yaml", {
replica_count = var.ingress_replicas
})]
}
Charts that don't expose safeguard fields need postrender:
resource "helm_release" "operator" {
name = "my-operator"
chart = "my-operator"
postrender {
binary_path = "${path.module}/kustomize/postrender.sh"
}
}
For complete Helm/Kustomize patterns: references/helm-kustomize.md
AKS Automatic enforces safeguards that cannot be bypassed. All workloads must comply:
| Requirement | Applies to |
|---|---|
readinessProbe + livenessProbe | ALL containers |
resources.requests (cpu + memory) | ALL containers |
Specific image tag (no :latest) | ALL containers |
seccompProfile: RuntimeDefault | Pod spec |
topologySpreadConstraints or podAntiAffinity | Replicas > 1 |
| No privileged containers | ALL pods |
What does NOT work: az aks safeguards update --level Warn, namespace exclusions, policy exemptions, Gatekeeper constraint modifications.
For detailed safeguards: references/aks-safeguards.md
NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST
Quick fixes mask deeper problems. A "working" deployment you don't understand will break again.
| Phase | Action | Output |
|---|---|---|
| 1. Gather Evidence | Collect logs, state, errors | Evidence document |
| 2. Recent Changes | git history, terraform state | Change list |
| 3. Hypothesis | Form single testable theory | Clear hypothesis |
| 4. Verify Fix | Test minimal change, document | Verified solution |
STOP. Do not attempt any fix yet.
# Terraform state
terraform state list
terraform plan 2>&1 | tee plan-output.txt
# Kubernetes state
kubectl get pods -A | grep -v Running
kubectl describe pod <failing-pod> -n <namespace>
# AKS Safeguards
kubectl get constraints -o wide
# Azure Activity Log
az monitor activity-log list --resource-group <rg> --status Failed --max-events 10
git log --oneline -10
git diff HEAD~3 -- infra/ platform/ scripts/
helm history <release> -n <namespace>
"The deployment fails because [specific cause] which results in [observed symptom]"
Change ONE variable at a time. Use terraform plan before apply. If 3+ hypotheses fail, question your architecture.
| Thought | Reality |
|---|---|
| "Let me just try this quick fix" | You don't understand the problem |
| "I'll add a retry/sleep" | You're masking the real issue |
| "This is the 4th thing I've tried" | Step back, question architecture |
| Issue | Investigation | Root cause |
|---|---|---|
| Pods stuck Pending | kubectl get constraints -o wide | Missing probes, resources, or anti-affinity |
| "Resource already exists" | terraform state list | Manual changes outside Terraform |
| Helm stuck pending-install | helm history <release> | Failed previous install, needs rollback |
| Gatekeeper not ready | kubectl get pods -n gatekeeper-system | Azure Policy eventual consistency |
NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE
"Terraform apply succeeded" does not mean it works. "No errors" does not mean correct.
1. IDENTIFY → What command(s) prove this claim?
2. RUN → Execute the command(s) fresh
3. READ → Full output, check exit codes
4. VERIFY → Does output actually confirm the claim?
5. ONLY THEN → Make the claim with evidence
# Cluster health
kubectl get nodes # All Ready
kubectl get pods -A | grep -v Running | grep -v Completed # Should be empty
kubectl get constraints -o wide # 0 violations
# Terraform state
terraform plan # No unexpected changes
terraform output # Values correct
# Pre-PR checks
terraform fmt -check -recursive ./infra
terraform fmt -check -recursive ./platform
After deploying: pods Running, 0 constraint violations, component health check, logs clean.
After fixing a bug: original error gone, no new errors, related components still work.
Before creating PR: fmt passes, no secrets in code, docs updated, all components healthy.
npx claudepluginhub danielscholl/claude-osdu --plugin cimplGenerates, debugs, and manages Terraform infrastructure code for AWS (6.0), AzureRM (4.x), and GCP providers. Handles version upgrades (1.10+), security scanning, Stacks, and policy-as-code.
Outlines requirements for certifying Azure Terraform modules with AVM, including providers, code style, variables, outputs, testing, documentation, and compliance.
Generates Azure deployment infrastructure (Bicep/Terraform), azure.yaml, and Dockerfiles. Use for creating or modernizing apps to deploy on Azure.