A production-ready Terraform configuration for deploying Azure Kubernetes Service (AKS) with Workload Identity, Azure ContainSee AZD-QUICKSTART.md for details.
Common Issuesgistry (ACR), and private Azure Storage. The deployment follows Azure and Terraform best practices with a modular architecture.
Deploy a complete AKS cluster with workload identity in under 5 minutes:
git clone <repository-url>
cd aks-workloadidentity-sample
./deploy-now.shThat's it! The script will:
- β Check prerequisites (Azure CLI, Terraform, kubectl)
- β Log you into Azure
- β Auto-configure terraform.tfvars with your subscription
- β Fetch the latest AKS version
- β Deploy the infrastructure
- β Validate the deployment
- β Show you how to test it
Ensure you have these tools installed:
- Azure CLI: Install guide
- Terraform: Install guide
- kubectl: Install guide
π‘ In a dev container? All tools are pre-installed! Just run
./deploy-now.sh
If you prefer manual control or want to customize settings:
cd infra/tf
cp terraform.tfvars.example terraform.tfvars
vim terraform.tfvars # Customize your settings./deploy.sh # Deploy everything
./validate.sh # Validate deploymentkubectl apply -f examples/test-workload-identity-simple.yaml
kubectl logs workload-identity-test-simpleThis deployment creates a secure, production-ready AKS environment:
- Azure AD Integration: Enterprise authentication with group-based admin access
- Workload Identity: Pods access Azure services without storing secrets
- Private Storage: Azure Storage accessible only through private endpoints
- Managed Identities: Separate identities for different purposes (principle of least privilege)
- No Local Accounts: Azure AD-only authentication
- AKS Cluster: Azure AD integrated, workload identity enabled
- Azure Container Registry: Connected with managed identity authentication
- Azure Storage: Private endpoint for secure access
- Virtual Network: Custom VNet with dedicated subnets for AKS and private endpoints
- Managed Identities: Three separate identities for different roles
- Consistent naming following Azure best practices
- Comprehensive tagging for cost management
- Modular Terraform architecture for maintainability
Test workload identity with these examples:
# Simple test - verify workload identity authentication
kubectl apply -f examples/test-workload-identity-simple.yaml
kubectl logs workload-identity-test-simple
# Private storage test - verify private endpoint connectivity
kubectl apply -f examples/test-private-storage.yaml
kubectl logs private-storage-test
# Azure Resource Manager test - verify Azure API access
kubectl apply -f examples/test-workload-identity-arm.yaml
kubectl logs workload-identity-test-keyvaultEdit infra/tf/terraform.tfvars to customize:
project_name = "mycompany" # Your company/project name (max 10 chars)
environment = "dev" # dev, staging, prod
location = "East US" # Your preferred Azure region
kubernetes_version = "1.33.1" # AKS version (auto-updated)
node_count = 3 # Number of worker nodes
vm_size = "Standard_B2s" # VM size for nodesAdd Azure AD groups for cluster admin access:
admin_group_object_ids = [
"12345678-1234-1234-1234-123456789012" # Your Azure AD group Object ID
]Find group Object IDs:
# Azure CLI
az ad group show --group "AKS-Admins" --query id --output tsv
# PowerShell
(Get-AzADGroup -DisplayName "AKS-Admins").IdRemove all deployed resources:
cd infra/tf
./cleanup.sh
β οΈ Warning: This will delete all Azure resources created by the deployment
For detailed technical information:
- οΏ½ Quick Start Guide - 5-minute deployment guide
- οΏ½ποΈ Documentation Hub - Complete technical documentation
- π Azure AD Admin Groups - Advanced admin access configuration
- π Azure Federated Token File - Workload identity deep dive
- ποΈ Private Storage Architecture - Private endpoint details
- π Network Workflow - Detailed pod-to-storage network flow analysis
- π§ͺ Examples Guide - Test cases and validation
- ποΈ Infrastructure Guide - Terraform module details
For a simpler approach, you can also use Azure Developer CLI:
azd up # One command deployment with azdSee AZD-QUICKSTART.md for details.
"Cannot access storage account"
- Add your IP to the storage account firewall in Azure Portal
- Navigate to: Storage accounts β [storage-name] β Networking β Add your IP
"Access denied to AKS cluster"
- Ensure you're added to the auto-created Azure AD admin group
- Or add your Azure AD group to
admin_group_object_idsin terraform.tfvars
"Pod cannot access Azure services"
- Verify workload identity is properly configured:
kubectl describe sa workload-identity-sa - Check pod has the correct label:
azure.workload.identity/use: "true"
Run the validation script for detailed diagnostics:
cd infra/tf && ./validate.shFor more help, see the Documentation Hub.
π― Ready to deploy? Run ./deploy-now.sh for a seamless experience!
- Azure CLI installed and configured (
az login) - Terraform (>= 1.5) installed
- kubectl installed (for cluster management)
- Azure subscription with Owner or Contributor permissions
- Bash shell (for deployment scripts)
- Azure AD group for admin access (recommended)
aks-workloadidentity-sample/
βββ π README.md # This comprehensive guide
βββ π NAMING.md # Resource naming conventions (quick reference)
βββ π start.sh # Navigation helper script
βββ π .copilot/ # Development and AI instructions
β βββ prompts.md # GitHub Copilot development guide
β βββ security-config.md # Security configuration reference
βββ π docs/ # π Comprehensive documentation hub
β βββ README.md # ποΈ Master documentation index
β βββ azure-ad-admin-groups.md # π Azure AD group setup guide
β βββ azure-federated-token-file.md # π Token mechanism deep dive
βββ π examples/ # π§ͺ Example applications and test cases
β βββ README.md # π Examples and testing guide
β βββ test-storage-access.yaml # π Workload identity connectivity test
β βββ inspect-token.yaml # π Token inspection and debugging
βββ π infra/tf/ # Terraform deployment
βββ main.tf # Main configuration
βββ variables.tf # Input variables
βββ outputs.tf # Output values
βββ terraform.tfvars # Configuration values
βββ backend.hcl.template # Backend configuration template
βββ deploy.sh # π Main deployment script
βββ cleanup.sh # π§Ή Cleanup script
βββ validate.sh # β
Validation script
βββ modules/ # Terraform modules
βββ aks/ # AKS cluster
βββ container_registry/ # Azure Container Registry
βββ managed_identity/ # User Assigned Managed Identities
βββ storage/ # Storage account
βββ workload_identity/ # Workload identity configuration
-
Navigate to Terraform directory:
cd infra/tf -
Update
terraform.tfvarswith your settings:# Basic Configuration project_name = "myproject" # Max 10 chars, lowercase alphanumeric environment = "dev" # dev, staging, prod location = "East US" # Azure region kubernetes_version = "1.30.12" # Supported AKS version # Admin Access (REQUIRED) admin_group_object_ids = [ "12345678-1234-1234-1234-123456789012" # Your Azure AD group Object ID ] # Optional Customization node_count = 3 # Number of nodes vm_size = "Standard_B2s" # Node VM size namespace = "default" # K8s namespace service_account_name = "workload-identity-sa"
Option A: Automated Deployment (Recommended)
./deploy.shOption B: Manual Deployment
# Initialize Terraform
terraform init -backend-config=backend.hcl.template
# Plan and apply
terraform plan -out=tfplan
terraform apply tfplan
# Configure kubectl
az aks get-credentials --resource-group $(terraform output -raw resource_group_name) --name $(terraform output -raw aks_cluster_name)# Check cluster access
kubectl get nodes
# Verify workload identity service account
kubectl get serviceaccount workload-identity-sa
# List managed identities
az identity list --resource-group $(terraform output -raw resource_group_name)
# Test workload identity with example pod
kubectl apply -f ../../examples/test-pod.yamlOnce deployed, your pods can authenticate to Azure services without storing secrets:
apiVersion: v1
kind: Pod
metadata:
name: workload-identity-test
namespace: default
spec:
serviceAccountName: workload-identity-sa # Uses the created service account
containers:
- name: azure-cli
image: mcr.microsoft.com/azure-cli:latest
command: ["/bin/bash", "-c", "sleep 3600"]
env:
- name: AZURE_CLIENT_ID
value: "$(terraform output -raw workload_identity_client_id)"# Deploy test pod
kubectl apply -f examples/test-pod.yaml
# Test Azure authentication from within the pod
kubectl exec -it workload-identity-test -- az account show
# The pod should authenticate automatically using workload identity# Grant workload identity access to storage account
az role assignment create \
--assignee $(terraform output -raw workload_identity_principal_id) \
--role "Storage Blob Data Contributor" \
--scope /subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.Storage/storageAccounts/<storage-name>
# Grant access to Key Vault
az role assignment create \
--assignee $(terraform output -raw workload_identity_principal_id) \
--role "Key Vault Secrets User" \
--scope /subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.KeyVault/vaults/<keyvault-name>| Variable | Description | Default | Example |
|---|---|---|---|
project_name |
Short project identifier | akswlid |
myapp |
environment |
Environment name | dev |
dev, staging, prod |
location |
Azure region | centralus |
East US, West Europe |
admin_group_object_ids |
Azure AD admin groups | [] |
["12345678-1234-1234-1234-123456789012"] |
kubernetes_version |
AKS version | 1.30.12 |
1.29.9, 1.30.12 |
node_count |
Number of nodes | 3 |
2, 5, 10 |
vm_size |
Node VM size | Standard_B2s |
Standard_D2s_v3 |
π Full reference: See
variables.tffor all configuration options
After deployment, use these outputs to integrate with your applications:
# Get cluster connection command
terraform output kubeconfig_command
# Get workload identity details
terraform output workload_identity_client_id
terraform output workload_identity_principal_id
# Get resource information
terraform output resource_group_name
terraform output aks_cluster_name
terraform output container_registry_login_serverThis deployment uses modular Terraform architecture:
modules/aks/: AKS cluster with Azure AD integration and workload identitymodules/container_registry/: Azure Container Registry with managed identity accessmodules/managed_identity/: Three User Assigned Managed Identitiesmodules/storage/: Storage account for Terraform state and application datamodules/workload_identity/: Federated credentials and Kubernetes service account
Terraform state is stored in Azure Storage for team collaboration:
- Storage Account: Auto-created or specified in
backend.hcl - Container:
tfstate - State File:
aks-workloadidentity/terraform.tfstate
β
No Secrets Stored: Workload identity uses federated credentials
β
Least Privilege: Separate managed identities for different purposes
β
Azure AD Only: Local cluster accounts disabled
β
RBAC Enabled: Fine-grained permissions with Azure RBAC
β
Tagged Resources: Consistent tagging for governance
Scale the cluster:
node_count = 5
vm_size = "Standard_D2s_v3"Multiple admin groups:
admin_group_object_ids = [
"group-1-object-id",
"group-2-object-id"
]Different environment:
environment = "production"
location = "West Europe"| Issue | Solution |
|---|---|
| Authentication errors | Run az login and ensure correct subscription |
| Terraform init fails | Check backend.hcl configuration and storage account access |
| kubectl access denied | Verify you're a member of the configured admin groups |
| Workload identity not working | Check service account annotations and federated credentials |
# Check Azure authentication
az account show
# Validate Terraform configuration
cd infra/tf && terraform validate
# Check cluster status
az aks show --resource-group $(terraform output -raw resource_group_name) --name $(terraform output -raw aks_cluster_name)
# Verify workload identity setup
kubectl describe serviceaccount workload-identity-sa
kubectl describe federatedidentitycredential
# Test cluster connectivity
kubectl get nodes -v=6 # Verbose output for debugging- Check the troubleshooting section above
- Review Azure documentation: AKS Troubleshooting
- Workload Identity docs: Azure Workload Identity
- Open an issue in this repository
To remove all deployed resources:
cd infra/tf
./cleanup.shOr manually:
terraform destroy
β οΈ Warning: This will permanently delete all resources. Ensure you have backups if needed.
- ποΈ Documentation Hub: Master index and navigation guide
- π Naming Conventions: Resource naming guidelines (quick reference)
- π Azure AD Groups Guide: Detailed admin access setup
- π Token Deep Dive: Understanding workload identity internals
- π§ͺ Examples & Testing: Validation and troubleshooting examples
- ποΈ Infrastructure Guide: Architecture and module documentation
- π€ Development Guide: Instructions for developers and AI
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests if applicable
- Update documentation
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
Questions? Open an issue or check the troubleshooting section above.