
Deploying On Azure
- 53 installs
- 426 repo stars
- Updated December 11, 2025
- ancoleman/ai-design-components
Deploying-on-azure is a Claude Code skill that designs and implements Azure cloud architectures using the Well-Architected Framework and best practices.
About
Deploying-on-azure is a Claude Code skill for designing and implementing Azure cloud architectures. A developer uses it when building applications on Microsoft Azure or migrating workloads to Azure. It provides service-selection frameworks for compute (Container Apps, AKS, Functions, App Service, VMs), storage tiers, databases, Azure OpenAI integration, networking, and governance, following the Azure Well-Architected Framework.
- Compute selection: Container Apps, AKS, Functions, App Service, VMs
- Storage tiers, database selection, and Azure OpenAI integration
- Azure Well-Architected Framework five pillars
Deploying On Azure by the numbers
- 53 all-time installs (skills.sh)
- Ranked #707 of 1,039 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
deploying-on-azure capabilities & compatibility
- Capabilities
- deploying on azure · deploying on aws · deploying applications · configuring firewalls
- Works with
- azure
- Use cases
- devops
What deploying-on-azure says it does
Design and implement Azure cloud architectures using best practices for compute, storage, databases, AI services, networking, and governance.
Start with Azure Container Apps for 80% of containerized workloads (simpler and cheaper than AKS).
npx skills add https://github.com/ancoleman/ai-design-components --skill deploying-on-azureAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 53 |
|---|---|
| repo stars | ★ 426 |
| Last updated | December 11, 2025 |
| Repository | ancoleman/ai-design-components ↗ |
What it does
Design an Azure architecture by selecting compute, storage, and database services for a workload.
Who is it for?
Selecting Azure compute, storage, and database services for a workload.
Skip if: Non-Azure clouds or application code.
When should I use this skill?
Designing an Azure architecture or selecting Azure services for a workload.
What you get
Well-architected Azure service selections following the five pillars, cost-aware and secure.
- Compute service selection
- Storage tier selection
- Database selection
By the numbers
- Azure offers 200+ services
- Container Apps recommended for 80% of containerized workloads
Files
Azure Patterns
Design and implement Azure cloud architectures following Microsoft's Well-Architected Framework and best practices for service selection, cost optimization, and security.
When to Use
Use this skill when:
- Designing new applications for Azure cloud
- Selecting Azure compute services (Container Apps, AKS, Functions, App Service)
- Architecting storage solutions (Blob Storage, Files, Cosmos DB)
- Integrating Azure OpenAI or Cognitive Services
- Implementing messaging patterns (Service Bus, Event Grid, Event Hubs)
- Designing secure networks with Private Endpoints
- Applying Azure governance and compliance policies
- Optimizing Azure costs and performance
Core Concepts
Service Selection Philosophy
Azure offers 200+ services. Choose based on: 1. Managed vs. IaaS - Prefer fully managed services (lower operational burden) 2. Cost Model - Consumption vs. dedicated capacity 3. Integration Requirements - Microsoft 365, Active Directory, hybrid cloud 4. Control vs. Simplicity - More control = more operational overhead
Azure Well-Architected Framework (Five Pillars)
| Pillar | Focus | Key Practices |
|---|---|---|
| Cost Optimization | Maximize value within budget | Reserved Instances, auto-scaling, lifecycle management |
| Operational Excellence | Run reliable systems | Azure Policy, automation, monitoring |
| Performance Efficiency | Scale to meet demand | Autoscaling, caching, CDN |
| Reliability | Recover from failures | Availability Zones, multi-region, backup |
| Security | Protect data and assets | Managed Identity, Private Endpoints, Key Vault |
Reference references/well-architected.md for detailed pillar implementation patterns.
Compute Service Selection
Decision Framework
Container-based workload?
YES → Need Kubernetes control plane?
YES → Azure Kubernetes Service (AKS)
NO → Azure Container Apps (recommended)
NO → Event-driven function?
YES → Azure Functions
NO → Web application?
YES → Azure App Service
NO → Legacy/specialized → Virtual MachinesService Comparison
| Service | Best For | Pricing Model | Operational Overhead |
|---|---|---|---|
| Container Apps | Microservices, APIs, background jobs | Consumption or dedicated | Low |
| AKS | Complex K8s workloads, service mesh | Node-based | High |
| Functions | Event-driven, short tasks (<10 min) | Consumption or premium | Low |
| App Service | Web apps, simple APIs | Dedicated plans | Low |
| Virtual Machines | Legacy apps, specialized software | VM-based | High |
Recommendation: Start with Azure Container Apps for 80% of containerized workloads (simpler and cheaper than AKS).
Reference references/compute-services.md for detailed comparison with Bicep and Terraform examples.
Storage Architecture
Blob Storage Tier Selection
| Tier | Access Pattern | Cost/GB/Month | Minimum Storage Duration |
|---|---|---|---|
| Hot | Daily access | $0.018 | None |
| Cool | <1/month access | $0.010 | 30 days |
| Cold | <90 days access | $0.0045 | 90 days |
| Archive | Rare access | $0.00099 | 180 days |
Pattern: Use lifecycle management policies to automatically move data to lower-cost tiers.
Storage Service Decision
File system interface required?
YES → Protocol?
SMB → Azure Files (or NetApp Files for high performance)
NFS → Azure Files (NFS 4.1)
NO → Object storage → Blob Storage
Block storage → Managed Disks (Standard/Premium SSD/Ultra)
Analytics → Data Lake Storage Gen2Reference references/storage-patterns.md for lifecycle policies, redundancy options, and performance tuning.
Database Service Selection
Decision Framework
Relational data?
YES → SQL Server compatible?
YES → Need VM-level access?
YES → SQL Managed Instance
NO → Azure SQL Database
NO → Open source?
PostgreSQL → PostgreSQL Flexible Server
MySQL → MySQL Flexible Server
NO → Data model?
Document/JSON → Cosmos DB (NoSQL API)
Graph → Cosmos DB (Gremlin API)
Wide-column → Cosmos DB (Cassandra API)
Key-value cache → Azure Cache for Redis
Time-series → Azure Data ExplorerCosmos DB Consistency Levels
| Level | Use Case | Latency | Throughput |
|---|---|---|---|
| Strong | Financial transactions, inventory | Highest | Lowest |
| Bounded Staleness | Real-time leaderboards with acceptable lag | High | Low |
| Session | Shopping carts, user sessions (default) | Medium | Medium |
| Consistent Prefix | Social feeds, IoT telemetry | Low | High |
| Eventual | Analytics, ML training data | Lowest | Highest |
Reference references/database-selection.md for capacity planning, indexing strategies, and migration patterns.
AI and Machine Learning Integration
Azure OpenAI Service
Use Cases:
- Chatbots and conversational AI (GPT-4)
- Content generation and summarization
- Semantic search with embeddings (RAG pattern)
- Code generation and completion
- Function calling for structured outputs
Key Advantages:
- Enterprise data privacy (no model training on customer data)
- Regional deployment for data residency
- Microsoft enterprise SLAs
- Built-in content filtering
Integration Pattern:
from openai import AzureOpenAI
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
client = AzureOpenAI(
azure_endpoint="https://myopenai.openai.azure.com",
azure_ad_token_provider=token_provider,
api_version="2024-02-15-preview"
)
response = client.chat.completions.create(
model="gpt-4-turbo",
messages=[{"role": "user", "content": "Hello!"}]
)Other AI Services
| Service | Purpose | Common Use Cases |
|---|---|---|
| Cognitive Services | Pre-built AI models | Vision, Speech, Language, Decision |
| Azure Machine Learning | Custom model training | MLOps, model deployment, feature engineering |
| Azure AI Search | Semantic search engine | RAG patterns, document search |
Reference references/ai-integration.md for RAG architecture, function calling, and fine-tuning patterns.
Messaging and Integration
Service Selection Matrix
| Service | Pattern | Message Size | Ordering | Transactions | Best For |
|---|---|---|---|---|---|
| Service Bus | Queue/Topic | 256 KB - 100 MB | Yes (sessions) | Yes | Enterprise messaging |
| Event Grid | Pub/Sub | 1 MB | No | No | Event-driven architectures |
| Event Hubs | Streaming | 1 MB | Yes (partitions) | No | Big data ingestion, telemetry |
| Storage Queues | Simple queue | 64 KB | No | No | Async work, <500k msgs/sec |
When to Use What:
- Service Bus: Reliable messaging with transactions (e.g., order processing)
- Event Grid: React to Azure resource events (e.g., blob created, VM stopped)
- Event Hubs: High-throughput streaming (e.g., IoT telemetry, application logs)
Reference references/messaging-patterns.md for implementation examples, retry policies, and dead-letter handling.
Networking Architecture
Private Endpoints vs. Service Endpoints
| Aspect | Private Endpoint | Service Endpoint |
|---|---|---|
| Security Model | Private IP in VNet | Optimized route to public endpoint |
| Data Exfiltration Protection | Yes (network-isolated) | Limited (service firewall only) |
| Cost | ~$7.30/month per endpoint | Free |
| Recommendation | Production workloads | Dev/test environments |
Best Practice: Use Private Endpoints for all PaaS services in production (treat public endpoints as anti-pattern).
Hub-and-Spoke Topology
Components:
- Hub VNet: Shared services (Azure Firewall, VPN Gateway, Private Endpoints)
- Spoke VNets: Application workloads (isolated per environment or team)
- VNet Peering: Low-latency connectivity between hub and spokes
Benefits:
- Centralized security (firewall, DNS)
- Cost optimization (shared egress)
- Simplified governance
Reference references/networking-architecture.md for hub-spoke Bicep templates, NSG patterns, and DNS configuration.
Identity and Access Management
Managed Identity Pattern
Always use Managed Identity instead of:
- Connection strings in code
- Storage account keys
- Service principal credentials
- API keys
System-Assigned vs. User-Assigned:
| Type | Lifecycle | Use Case |
|---|---|---|
| System-Assigned | Tied to resource | Single resource needs access |
| User-Assigned | Independent | Multiple resources share identity |
Example Flow: 1. Enable Managed Identity on Container App 2. Grant identity access to Key Vault (RBAC or Access Policy) 3. Application authenticates automatically (no credentials)
from azure.identity import DefaultAzureCredential
# Works automatically with Managed Identity
credential = DefaultAzureCredential()
keyvault_client = SecretClient(vault_url="...", credential=credential)Azure RBAC Best Practices
- Use built-in roles when possible (Owner, Contributor, Reader)
- Apply least privilege principle
- Assign roles at resource group level (not subscription)
- Use Azure AD groups for user management
- Audit role assignments regularly
Reference references/identity-access.md for Entra ID integration, Conditional Access policies, and B2C patterns.
Governance and Compliance
Azure Policy for Guardrails
Common Policy Patterns:
- Require tags on all resources (Environment, Owner, CostCenter)
- Restrict allowed Azure regions
- Enforce TLS 1.2 minimum
- Require Private Endpoints for storage accounts
- Deny public IP addresses on VMs
Policy Effects:
- Deny: Block non-compliant resource creation
- Audit: Log non-compliance but allow creation
- DeployIfNotExists: Auto-remediate missing configurations
- Modify: Change resource properties during deployment
Cost Management
Optimization Strategies:
| Pattern | Savings | Use Case |
|---|---|---|
| Reserved Instances (1-year) | 40-50% | Steady-state workloads (databases, VMs) |
| Reserved Instances (3-year) | 60-70% | Long-term commitments |
| Spot VMs | Up to 90% | Fault-tolerant batch processing |
| Auto-shutdown | Variable | Dev/test resources (off-hours) |
| Storage lifecycle policies | 50-90% | Move to Cool/Archive tiers |
Monitoring:
- Set budgets and alerts in Azure Cost Management
- Review Azure Advisor cost recommendations weekly
- Tag resources for cost allocation
- Use FinOps Toolkit for Power BI dashboards
Reference references/governance-compliance.md for Azure Landing Zones, Policy definitions, and Blueprints.
Infrastructure as Code
Tool Selection
| Tool | Best For | Azure Integration | Multi-Cloud |
|---|---|---|---|
| Bicep | Azure-native projects | Excellent (official) | No |
| Terraform | Multi-cloud environments | Good (azurerm provider) | Yes |
| Pulumi | Developer-first approach | Good (native SDK) | Yes |
| Azure CLI | Scripts and automation | Excellent | No |
Recommendation:
- Use Bicep for Azure-only infrastructure (best Azure integration, native type safety)
- Use Terraform for multi-cloud or existing Terraform shops
- Use Azure CLI for quick scripts and CI/CD automation
Bicep Best Practices
- Use parameter files for environment-specific values
- Leverage Azure Verified Modules (AVM) for tested patterns
- Organize by resource lifecycle (networking, data, compute)
- Use symbolic names (not string interpolation)
- Enable linting and validation in CI/CD
Reference Bicep and Terraform examples in examples/bicep/ and examples/terraform/ directories.
Security Best Practices
Essential Security Controls
| Control | Implementation | Priority |
|---|---|---|
| Managed Identity | Enable on all compute resources | Critical |
| Private Endpoints | All PaaS services in production | Critical |
| Key Vault | Store secrets, keys, certificates | Critical |
| Network Segmentation | NSGs, application security groups | High |
| Microsoft Defender | Enable for all resource types | High |
| Azure Policy | Preventive controls | High |
| Just-In-Time Access | VMs and privileged access | Medium |
Defense-in-Depth Layers
1. Network: Private Endpoints, NSGs, Azure Firewall 2. Identity: Entra ID, Managed Identity, Conditional Access 3. Application: Web Application Firewall, API Management 4. Data: Encryption at rest, encryption in transit (TLS 1.2+) 5. Monitoring: Microsoft Defender, Azure Monitor, Sentinel
Reference references/security-architecture.md (see also security-hardening and auth-security skills).
Cost Estimation
Pricing Considerations
Compute:
- Container Apps: ~$60/month (1 vCPU, 2GB RAM, 24/7)
- AKS: ~$400/month (3-node D4s_v5 cluster)
- App Service P1v3: ~$145/month (2 vCPU, 8GB RAM)
- Functions Consumption: ~$0.20 per 1M executions
Storage:
- Blob Hot: $0.018/GB/month
- Blob Cool: $0.010/GB/month
- Blob Archive: $0.00099/GB/month
- Managed Disks Premium SSD: $0.15/GB/month
Database:
- Azure SQL Database (2 vCores): ~$280/month
- Cosmos DB Serverless: Pay per RU consumed
- PostgreSQL Flexible (2 vCores): ~$125/month
Use Azure Pricing Calculator: https://azure.microsoft.com/pricing/calculator/
Quick Reference Tables
Compute Service Decision Matrix
| If You Need... | Choose |
|---|---|
| Kubernetes features (CRDs, operators) | Azure Kubernetes Service |
| Microservices without K8s complexity | Azure Container Apps |
| Event-driven functions (<10 min) | Azure Functions |
| Traditional web app (Node, .NET, Python) | Azure App Service |
| Batch processing, HPC | Azure Batch or VM Scale Sets |
| Legacy application migration | Virtual Machines |
Storage Service Decision Matrix
| If You Need... | Choose |
|---|---|
| SMB file shares | Azure Files |
| NFS file shares | Azure Files (NFS 4.1) |
| Object storage (images, backups) | Blob Storage |
| High-performance file storage | Azure NetApp Files |
| Block storage for VMs | Managed Disks |
| Big data analytics | Data Lake Storage Gen2 |
Database Service Decision Matrix
| If You Need... | Choose |
|---|---|
| SQL Server features (T-SQL, SQL Agent) | Azure SQL Database or Managed Instance |
| PostgreSQL | PostgreSQL Flexible Server |
| MySQL | MySQL Flexible Server |
| Global distribution, multi-model | Cosmos DB |
| In-memory cache | Azure Cache for Redis |
| Graph database | Cosmos DB (Gremlin API) |
| Time-series data | Azure Data Explorer |
Integration with Other Skills
- infrastructure-as-code: Implement Azure patterns using Bicep or Terraform
- kubernetes-operations: AKS-specific configuration and operations
- deploying-applications: Container Apps and App Service deployment
- building-ci-pipelines: Azure DevOps and GitHub Actions integration
- auth-security: Entra ID authentication and authorization patterns
- observability: Azure Monitor and Application Insights
- ai-chat: Azure OpenAI Service for chat applications
- databases-nosql: Cosmos DB implementation details
- secret-management: Azure Key Vault integration patterns
Reference Documentation
For detailed implementation guidance, see:
- `references/compute-services.md` - Container Apps, AKS, Functions, App Service with Bicep/Terraform
- `references/storage-patterns.md` - Blob Storage, Files, Disks, lifecycle management
- `references/database-selection.md` - SQL Database, Cosmos DB, PostgreSQL patterns
- `references/ai-integration.md` - Azure OpenAI, RAG architecture, function calling
- `references/messaging-patterns.md` - Service Bus, Event Grid, Event Hubs examples
- `references/networking-architecture.md` - Hub-spoke, Private Endpoints, DNS configuration
- `references/identity-access.md` - Entra ID, Managed Identity, RBAC
- `references/governance-compliance.md` - Azure Policy, Landing Zones, cost optimization
- `references/well-architected.md` - Five pillars implementation guide
Code Examples
Working examples available in:
- `examples/bicep/` - Infrastructure templates (Container Apps, AKS, networking, databases)
- `examples/terraform/` - Multi-cloud IaC examples
- `examples/sdk/python/` - Python SDK integration (OpenAI, Managed Identity, messaging)
- `examples/sdk/typescript/` - TypeScript SDK examples
Additional Resources
- Azure Architecture Center: https://learn.microsoft.com/azure/architecture/
- Azure Well-Architected Framework: https://learn.microsoft.com/azure/well-architected/
- Azure Verified Modules: https://aka.ms/avm
- Azure Charts (Service Comparison): https://azurecharts.com/
- Azure Updates: https://azure.microsoft.com/updates/
/**
* Azure Container Apps - Complete Production Example
*
* This template deploys a production-ready Container Apps environment with:
* - VNet integration and Private Endpoints
* - Managed Identity authentication
* - Key Vault integration
* - Azure Container Registry
* - Log Analytics monitoring
* - Autoscaling rules (HTTP, queue, schedule)
*
* Usage:
* az deployment group create \
* --resource-group my-rg \
* --template-file main.bicep \
* --parameters environment=production location=eastus
*/
@description('Environment name (dev, staging, production)')
@allowed(['dev', 'staging', 'production'])
param environment string = 'production'
@description('Azure region')
param location string = resourceGroup().location
@description('Container image tag')
param imageTag string = 'latest'
@description('Database connection string (stored in Key Vault)')
@secure()
param dbConnectionString string
// Variables
var baseName = 'myapp-${environment}'
var tags = {
Environment: environment
ManagedBy: 'Bicep'
Application: 'MyApp'
}
// Virtual Network
resource vnet 'Microsoft.Network/virtualNetworks@2023-05-01' = {
name: '${baseName}-vnet'
location: location
tags: tags
properties: {
addressSpace: {
addressPrefixes: ['10.0.0.0/16']
}
subnets: [
{
name: 'container-apps-subnet'
properties: {
addressPrefix: '10.0.0.0/23'
delegations: [
{
name: 'Microsoft.App/environments'
properties: {
serviceName: 'Microsoft.App/environments'
}
}
]
}
}
{
name: 'private-endpoints-subnet'
properties: {
addressPrefix: '10.0.2.0/24'
privateEndpointNetworkPolicies: 'Disabled'
}
}
]
}
}
// Log Analytics Workspace
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
name: '${baseName}-logs'
location: location
tags: tags
properties: {
sku: {
name: 'PerGB2018'
}
retentionInDays: 30
}
}
// Azure Container Registry
resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
name: replace('${baseName}acr', '-', '')
location: location
tags: tags
sku: {
name: 'Premium' // Required for Private Endpoints
}
properties: {
adminUserEnabled: false
publicNetworkAccess: 'Disabled'
}
}
// ACR Private Endpoint
resource acrPrivateEndpoint 'Microsoft.Network/privateEndpoints@2023-05-01' = {
name: '${baseName}-acr-pe'
location: location
tags: tags
properties: {
subnet: {
id: '${vnet.id}/subnets/private-endpoints-subnet'
}
privateLinkServiceConnections: [
{
name: 'acr-connection'
properties: {
privateLinkServiceId: acr.id
groupIds: ['registry']
}
}
]
}
}
// Key Vault
resource keyVault 'Microsoft.KeyVault/vaults@2023-02-01' = {
name: '${baseName}-kv'
location: location
tags: tags
properties: {
sku: {
family: 'A'
name: 'standard'
}
tenantId: subscription().tenantId
enableRbacAuthorization: true
publicNetworkAccess: 'Disabled'
}
}
// Store database connection string
resource dbConnectionSecret 'Microsoft.KeyVault/vaults/secrets@2023-02-01' = {
parent: keyVault
name: 'db-connection-string'
properties: {
value: dbConnectionString
}
}
// Key Vault Private Endpoint
resource kvPrivateEndpoint 'Microsoft.Network/privateEndpoints@2023-05-01' = {
name: '${baseName}-kv-pe'
location: location
tags: tags
properties: {
subnet: {
id: '${vnet.id}/subnets/private-endpoints-subnet'
}
privateLinkServiceConnections: [
{
name: 'kv-connection'
properties: {
privateLinkServiceId: keyVault.id
groupIds: ['vault']
}
}
]
}
}
// Container App Environment
resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' = {
name: '${baseName}-env'
location: location
tags: tags
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: logAnalytics.properties.customerId
sharedKey: logAnalytics.listKeys().primarySharedKey
}
}
zoneRedundant: environment == 'production'
vnetConfiguration: {
infrastructureSubnetId: '${vnet.id}/subnets/container-apps-subnet'
internal: true
}
}
}
// User-Assigned Managed Identity
resource userIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${baseName}-identity'
location: location
tags: tags
}
// Grant identity AcrPull role on ACR
resource acrPullRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(acr.id, userIdentity.id, 'AcrPull')
scope: acr
properties: {
principalId: userIdentity.properties.principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
principalType: 'ServicePrincipal'
}
}
// Grant identity Key Vault Secrets User role
resource kvSecretsUserRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(keyVault.id, userIdentity.id, 'KeyVaultSecretsUser')
scope: keyVault
properties: {
principalId: userIdentity.properties.principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')
principalType: 'ServicePrincipal'
}
}
// Container App (API Service)
resource apiContainerApp 'Microsoft.App/containerApps@2024-03-01' = {
name: '${baseName}-api'
location: location
tags: tags
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${userIdentity.id}': {}
}
}
properties: {
managedEnvironmentId: containerAppEnvironment.id
configuration: {
activeRevisionsMode: 'Single'
ingress: {
external: true
targetPort: 8080
transport: 'http2'
allowInsecure: false
traffic: [
{
latestRevision: true
weight: 100
}
]
}
secrets: [
{
name: 'db-connection-string'
keyVaultUrl: dbConnectionSecret.properties.secretUri
identity: userIdentity.id
}
]
registries: [
{
server: acr.properties.loginServer
identity: userIdentity.id
}
]
}
template: {
containers: [
{
name: 'api'
image: '${acr.properties.loginServer}/api:${imageTag}'
resources: {
cpu: json('1.0')
memory: '2Gi'
}
env: [
{
name: 'DATABASE_URL'
secretRef: 'db-connection-string'
}
{
name: 'ENVIRONMENT'
value: environment
}
{
name: 'LOG_LEVEL'
value: environment == 'production' ? 'info' : 'debug'
}
]
probes: [
{
type: 'Liveness'
httpGet: {
path: '/health'
port: 8080
}
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
}
{
type: 'Readiness'
httpGet: {
path: '/ready'
port: 8080
}
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
}
]
}
]
scale: {
minReplicas: environment == 'production' ? 3 : 1
maxReplicas: environment == 'production' ? 50 : 10
rules: [
{
name: 'http-scaling-rule'
http: {
metadata: {
concurrentRequests: '100'
}
}
}
{
name: 'business-hours-rule'
custom: {
type: 'cron'
metadata: {
timezone: 'America/New_York'
start: '0 8 * * MON-FRI'
end: '0 18 * * MON-FRI'
desiredReplicas: environment == 'production' ? '20' : '5'
}
}
}
]
}
}
}
dependsOn: [
acrPullRole
kvSecretsUserRole
]
}
// Outputs
output containerAppUrl string = 'https://${apiContainerApp.properties.configuration.ingress.fqdn}'
output containerRegistryLoginServer string = acr.properties.loginServer
output keyVaultName string = keyVault.name
output logAnalyticsWorkspaceId string = logAnalytics.id
"""
Azure OpenAI RAG (Retrieval-Augmented Generation) Example
This example demonstrates:
- Azure OpenAI integration with Managed Identity
- Vector embeddings generation
- Azure AI Search integration
- RAG pattern implementation
- Semantic search with hybrid scoring
Dependencies:
pip install openai azure-identity azure-search-documents azure-core
Usage:
python azure-openai-rag.py
Environment Variables (if not using Managed Identity):
AZURE_OPENAI_ENDPOINT - Azure OpenAI endpoint URL
AZURE_SEARCH_ENDPOINT - Azure AI Search endpoint URL
"""
import os
import json
from typing import List, Dict, Any, Optional
from dataclasses import dataclass
from openai import AzureOpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from azure.search.documents import SearchClient
from azure.search.documents.models import VectorizedQuery, QueryType
from azure.core.credentials import AzureKeyCredential
@dataclass
class SearchResult:
"""Search result from Azure AI Search"""
content: str
title: str
category: str
score: float
class AzureOpenAIRAG:
"""
RAG implementation using Azure OpenAI and Azure AI Search.
This class handles:
- Generating embeddings for queries
- Performing vector search in Azure AI Search
- Constructing prompts with retrieved context
- Generating answers using Azure OpenAI
"""
def __init__(
self,
openai_endpoint: Optional[str] = None,
search_endpoint: Optional[str] = None,
search_index_name: str = "documents",
embedding_model: str = "text-embedding-ada-002",
chat_model: str = "gpt-4-turbo"
):
"""
Initialize Azure OpenAI RAG client.
Args:
openai_endpoint: Azure OpenAI endpoint (uses env var if not provided)
search_endpoint: Azure AI Search endpoint (uses env var if not provided)
search_index_name: Name of the search index
embedding_model: Deployment name for embeddings model
chat_model: Deployment name for chat model
"""
# Setup Managed Identity authentication
self.credential = DefaultAzureCredential()
# Azure OpenAI setup
openai_endpoint = openai_endpoint or os.environ.get("AZURE_OPENAI_ENDPOINT")
if not openai_endpoint:
raise ValueError("AZURE_OPENAI_ENDPOINT must be set")
token_provider = get_bearer_token_provider(
self.credential,
"https://cognitiveservices.azure.com/.default"
)
self.openai_client = AzureOpenAI(
azure_endpoint=openai_endpoint,
azure_ad_token_provider=token_provider,
api_version="2024-02-15-preview"
)
# Azure AI Search setup
search_endpoint = search_endpoint or os.environ.get("AZURE_SEARCH_ENDPOINT")
if not search_endpoint:
raise ValueError("AZURE_SEARCH_ENDPOINT must be set")
self.search_client = SearchClient(
endpoint=search_endpoint,
index_name=search_index_name,
credential=self.credential
)
self.embedding_model = embedding_model
self.chat_model = chat_model
def generate_embedding(self, text: str) -> List[float]:
"""
Generate embedding vector for text using Azure OpenAI.
Args:
text: Text to embed
Returns:
Embedding vector (1536 dimensions for ada-002)
"""
response = self.openai_client.embeddings.create(
model=self.embedding_model,
input=text
)
return response.data[0].embedding
def search_documents(
self,
query: str,
top_k: int = 3,
use_hybrid_search: bool = True
) -> List[SearchResult]:
"""
Search documents using vector similarity and optional keyword search.
Args:
query: Search query
top_k: Number of results to return
use_hybrid_search: Use both vector and keyword search
Returns:
List of search results with content and metadata
"""
# Generate embedding for query
query_embedding = self.generate_embedding(query)
# Setup vector query
vector_query = VectorizedQuery(
vector=query_embedding,
k_nearest_neighbors=top_k,
fields="contentVector"
)
# Perform search
search_text = query if use_hybrid_search else None
search_results = self.search_client.search(
search_text=search_text,
vector_queries=[vector_query],
query_type=QueryType.SEMANTIC if use_hybrid_search else None,
select=["content", "title", "category"],
top=top_k
)
# Convert to SearchResult objects
results = []
for result in search_results:
results.append(SearchResult(
content=result.get("content", ""),
title=result.get("title", ""),
category=result.get("category", ""),
score=result.get("@search.score", 0.0)
))
return results
def generate_answer(
self,
question: str,
context_results: List[SearchResult],
temperature: float = 0.2,
max_tokens: int = 500,
include_citations: bool = True
) -> str:
"""
Generate answer using retrieved context and Azure OpenAI.
Args:
question: User question
context_results: Retrieved documents from search
temperature: Sampling temperature (0-1)
max_tokens: Maximum tokens in response
include_citations: Include document citations in answer
Returns:
Generated answer
"""
# Build context from search results
context_parts = []
for i, result in enumerate(context_results, 1):
context_parts.append(
f"[Document {i}]\n"
f"Category: {result.category}\n"
f"Title: {result.title}\n"
f"Content: {result.content}\n"
f"Relevance Score: {result.score:.2f}\n"
)
context = "\n".join(context_parts)
# System message with instructions
system_message = """You are a helpful assistant that answers questions based on provided context.
Instructions:
1. Only use information from the provided documents
2. If the answer is not in the context, say "I don't have enough information to answer that question based on the available documents."
3. Be concise and accurate
4. Cite which document(s) you used (e.g., "According to Document 1...")
5. If multiple documents provide relevant information, synthesize them
Be professional and helpful."""
# Construct user message
if include_citations:
user_message = f"""Context:
{context}
Question: {question}
Please provide a clear answer based on the context above, citing which document(s) you used."""
else:
user_message = f"Context:\n{context}\n\nQuestion: {question}"
# Generate answer
response = self.openai_client.chat.completions.create(
model=self.chat_model,
messages=[
{"role": "system", "content": system_message},
{"role": "user", "content": user_message}
],
temperature=temperature,
max_tokens=max_tokens,
top_p=0.95
)
return response.choices[0].message.content
def query(
self,
question: str,
top_k: int = 3,
use_hybrid_search: bool = True,
temperature: float = 0.2,
verbose: bool = False
) -> Dict[str, Any]:
"""
Complete RAG pipeline: search + generate.
Args:
question: User question
top_k: Number of documents to retrieve
use_hybrid_search: Use both vector and keyword search
temperature: Sampling temperature
verbose: Print intermediate steps
Returns:
Dictionary with answer, sources, and metadata
"""
if verbose:
print(f"Question: {question}\n")
print("Searching documents...")
# Search for relevant documents
search_results = self.search_documents(
query=question,
top_k=top_k,
use_hybrid_search=use_hybrid_search
)
if verbose:
print(f"Found {len(search_results)} relevant documents\n")
for i, result in enumerate(search_results, 1):
print(f" {i}. {result.title} (score: {result.score:.2f})")
print("\nGenerating answer...")
# Generate answer
answer = self.generate_answer(
question=question,
context_results=search_results,
temperature=temperature
)
if verbose:
print(f"\nAnswer: {answer}\n")
return {
"answer": answer,
"sources": [
{
"title": r.title,
"category": r.category,
"score": r.score,
"content_preview": r.content[:200] + "..." if len(r.content) > 200 else r.content
}
for r in search_results
],
"metadata": {
"model": self.chat_model,
"temperature": temperature,
"top_k": top_k,
"hybrid_search": use_hybrid_search
}
}
def main():
"""Example usage of Azure OpenAI RAG"""
# Initialize RAG client
rag = AzureOpenAIRAG(
openai_endpoint="https://myopenai.openai.azure.com",
search_endpoint="https://myaisearch.search.windows.net",
search_index_name="product-docs",
embedding_model="text-embedding-ada-002",
chat_model="gpt-4-turbo"
)
# Example questions
questions = [
"What are the key features of Azure Container Apps?",
"How do I implement autoscaling for my application?",
"What is the difference between Azure Functions and Container Apps?"
]
for question in questions:
print("=" * 80)
result = rag.query(
question=question,
top_k=3,
use_hybrid_search=True,
temperature=0.2,
verbose=True
)
print(f"\nSources used: {len(result['sources'])}")
for i, source in enumerate(result['sources'], 1):
print(f" {i}. {source['title']} (score: {source['score']:.2f})")
print("=" * 80)
print()
if __name__ == "__main__":
main()
skill: "deploying-on-azure"
version: "1.0"
domain: "cloud"
base_outputs:
# Core Azure infrastructure files - ALWAYS produced
- path: "infrastructure/azure/main.bicep"
must_contain: ["targetScope", "resource", "module"]
description: "Main Bicep template with resource definitions"
- path: "infrastructure/azure/parameters.json"
must_contain: ["parameters", "$schema"]
description: "Parameter file for environment-specific values"
- path: "infrastructure/azure/main.parameters.json"
must_contain: ["parameters", "value"]
description: "Default parameter values for Bicep deployment"
- path: "infrastructure/azure/variables.bicep"
must_contain: ["var", "@description"]
description: "Bicep variables for computed values and naming conventions"
- path: "infrastructure/azure/outputs.bicep"
must_contain: ["output"]
description: "Bicep outputs for deployed resource endpoints and identifiers"
- path: "infrastructure/azure/networking.bicep"
must_contain: ["Microsoft.Network/virtualNetworks", "subnets"]
description: "VNet configuration with subnets and NSG definitions"
- path: "infrastructure/azure/identity.bicep"
must_contain: ["Microsoft.ManagedIdentity/userAssignedIdentities", "roleAssignments"]
description: "Managed identities and RBAC role assignments"
- path: ".github/workflows/deploy-azure.yml"
must_contain: ["azure/login", "azure/arm-deploy"]
description: "GitHub Actions workflow for Azure deployment automation"
conditional_outputs:
maturity:
starter:
- path: "infrastructure/azure/README.md"
must_contain: ["Prerequisites", "az login", "Deployment Steps"]
description: "Deployment guide with Azure CLI setup and step-by-step instructions"
- path: "infrastructure/azure/deploy.sh"
must_contain: ["az deployment group create", "bicep"]
description: "Simple deployment script using Azure CLI"
- path: "infrastructure/azure/parameters.example.json"
must_contain: ["# Example configuration", "value"]
description: "Example parameter values with comments explaining each setting"
- path: ".azureconfig"
must_contain: ["[defaults]", "location", "group"]
description: "Azure CLI default configuration for simplified commands"
intermediate:
- path: "infrastructure/azure/environments/dev.parameters.json"
must_contain: ["parameters", "environment", "dev"]
description: "Development environment parameter file"
- path: "infrastructure/azure/environments/staging.parameters.json"
must_contain: ["parameters", "environment", "staging"]
description: "Staging environment parameter file"
- path: "infrastructure/azure/environments/prod.parameters.json"
must_contain: ["parameters", "environment", "prod"]
description: "Production environment parameter file"
- path: "infrastructure/azure/monitoring.bicep"
must_contain: ["Microsoft.Insights/", "diagnosticSettings"]
description: "Azure Monitor, Application Insights, and diagnostic settings"
- path: "infrastructure/azure/private-endpoints.bicep"
must_contain: ["Microsoft.Network/privateEndpoints", "privateDnsZoneGroups"]
description: "Private Endpoints configuration for PaaS services"
- path: "infrastructure/azure/keyvault.bicep"
must_contain: ["Microsoft.KeyVault/vaults", "accessPolicies"]
description: "Key Vault for secrets, keys, and certificates management"
- path: "scripts/deploy-environment.sh"
must_contain: ["az deployment", "environment", "bicep"]
description: "Environment-aware deployment script with validation"
advanced:
- path: "infrastructure/azure/modules/README.md"
must_contain: ["Reusable Bicep modules"]
description: "Documentation for custom reusable Bicep modules"
- path: "infrastructure/azure/hub-spoke.bicep"
must_contain: ["virtualNetworkPeerings", "hub", "spoke"]
description: "Hub-and-spoke network topology with VNet peering"
- path: "infrastructure/azure/policy.bicep"
must_contain: ["Microsoft.Authorization/policyDefinitions", "policyAssignments"]
description: "Azure Policy definitions and assignments for governance"
- path: "infrastructure/azure/waf.bicep"
must_contain: ["Microsoft.Network/FrontDoorWebApplicationFirewallPolicies"]
description: "Web Application Firewall rules for application protection"
- path: "infrastructure/azure/backup.bicep"
must_contain: ["Microsoft.RecoveryServices/vaults", "backupPolicies"]
description: "Azure Backup configuration for automated backups"
- path: "infrastructure/azure/disaster-recovery.bicep"
must_contain: ["Microsoft.RecoveryServices/", "replicationPolicies"]
description: "Azure Site Recovery for disaster recovery and failover"
- path: "infrastructure/azure/cost-management.bicep"
must_contain: ["Microsoft.CostManagement/", "budgets"]
description: "Cost Management budgets, alerts, and optimization rules"
- path: "infrastructure/azure/compliance.bicep"
must_contain: ["Microsoft.Security/", "assessments"]
description: "Microsoft Defender and compliance monitoring"
- path: "infrastructure/azure/landing-zone.bicep"
must_contain: ["managementGroups", "subscriptions", "resourceGroups"]
description: "Azure Landing Zone architecture with management groups"
infrastructure:
kubernetes: # AKS
- path: "infrastructure/azure/aks-cluster.bicep"
must_contain: ["Microsoft.ContainerService/managedClusters", "agentPoolProfiles"]
description: "AKS cluster with system and user node pools"
- path: "infrastructure/azure/aks-addons.bicep"
must_contain: ["addonProfiles", "omsagent", "azureKeyvaultSecretsProvider"]
description: "AKS add-ons (monitoring, Key Vault CSI, ingress controller)"
- path: "infrastructure/azure/aks-workload-identity.bicep"
must_contain: ["Microsoft.ManagedIdentity/", "federatedIdentityCredentials"]
description: "Workload Identity for AKS service accounts to access Azure resources"
- path: "infrastructure/azure/acr.bicep"
must_contain: ["Microsoft.ContainerRegistry/registries"]
description: "Azure Container Registry for container images"
- path: "infrastructure/azure/database.bicep"
must_contain: ["Microsoft.DBforPostgreSQL/flexibleServers", "privateEndpoint"]
description: "PostgreSQL Flexible Server or Azure SQL Database"
- path: "infrastructure/azure/storage.bicep"
must_contain: ["Microsoft.Storage/storageAccounts", "blobServices"]
description: "Azure Storage Account with blob containers and lifecycle policies"
- path: "infrastructure/azure/redis.bicep"
must_contain: ["Microsoft.Cache/redis", "privateEndpoint"]
description: "Azure Cache for Redis with Private Endpoint"
- path: "k8s/manifests/namespace.yaml"
must_contain: ["kind: Namespace", "apiVersion"]
description: "Kubernetes namespace definitions"
- path: "k8s/manifests/deployment.yaml"
must_contain: ["kind: Deployment", "spec", "containers"]
description: "Kubernetes deployment manifests"
- path: "k8s/manifests/service.yaml"
must_contain: ["kind: Service", "spec", "ports"]
description: "Kubernetes service manifests"
- path: "k8s/manifests/ingress.yaml"
must_contain: ["kind: Ingress", "nginx"]
description: "Kubernetes ingress with nginx or Application Gateway"
managed_platform: # Container Apps / App Service
- path: "infrastructure/azure/container-apps.bicep"
must_contain: ["Microsoft.App/containerApps", "managedEnvironments"]
description: "Azure Container Apps with managed environment"
- path: "infrastructure/azure/container-apps-environment.bicep"
must_contain: ["Microsoft.App/managedEnvironments", "vnetConfiguration"]
description: "Container Apps environment with VNet integration"
- path: "infrastructure/azure/container-apps-dapr.bicep"
must_contain: ["dapr", "componentType"]
description: "Dapr components for Container Apps (state, pub/sub, bindings)"
- path: "infrastructure/azure/app-service.bicep"
must_contain: ["Microsoft.Web/serverfarms", "Microsoft.Web/sites"]
description: "App Service Plan and Web App configuration"
- path: "infrastructure/azure/app-service-vnet.bicep"
must_contain: ["virtualNetworkSubnetId", "vnetRouteAllEnabled"]
description: "App Service VNet integration for outbound traffic"
- path: "infrastructure/azure/functions.bicep"
must_contain: ["Microsoft.Web/sites", "kind: functionapp"]
description: "Azure Functions app with consumption or premium plan"
- path: "infrastructure/azure/acr.bicep"
must_contain: ["Microsoft.ContainerRegistry/registries"]
description: "Azure Container Registry for container images"
- path: "infrastructure/azure/database.bicep"
must_contain: ["Microsoft.DBforPostgreSQL/flexibleServers", "Microsoft.Sql/servers"]
description: "Azure SQL Database or PostgreSQL Flexible Server"
- path: "infrastructure/azure/cosmos-db.bicep"
must_contain: ["Microsoft.DocumentDB/databaseAccounts", "locations"]
description: "Cosmos DB account with consistency level and replication"
- path: "infrastructure/azure/service-bus.bicep"
must_contain: ["Microsoft.ServiceBus/namespaces", "queues", "topics"]
description: "Service Bus namespace with queues and topics for messaging"
- path: "infrastructure/azure/storage.bicep"
must_contain: ["Microsoft.Storage/storageAccounts", "privateEndpoint"]
description: "Azure Storage Account with Private Endpoint"
- path: "Dockerfile"
must_contain: ["FROM", "EXPOSE", "CMD"]
description: "Container image for Container Apps or App Service deployment"
- path: ".dockerignore"
must_contain: ["node_modules", ".git", "*.md"]
description: "Files to exclude from Docker build context"
docker_compose: # VM-based
- path: "infrastructure/azure/vm.bicep"
must_contain: ["Microsoft.Compute/virtualMachines", "osProfile"]
description: "Virtual Machine configuration with OS profile"
- path: "infrastructure/azure/vmss.bicep"
must_contain: ["Microsoft.Compute/virtualMachineScaleSets"]
description: "Virtual Machine Scale Set with auto-scaling rules"
- path: "infrastructure/azure/load-balancer.bicep"
must_contain: ["Microsoft.Network/loadBalancers", "backendAddressPools"]
description: "Azure Load Balancer for VM traffic distribution"
- path: "infrastructure/azure/vm-extensions.bicep"
must_contain: ["Microsoft.Compute/virtualMachines/extensions", "commandToExecute"]
description: "VM extensions for Docker installation and configuration"
- path: "infrastructure/azure/disks.bicep"
must_contain: ["Microsoft.Compute/disks", "diskSizeGB"]
description: "Managed disks for persistent storage"
- path: "docker-compose.yml"
must_contain: ["version:", "services:"]
description: "Docker Compose configuration for multi-container setup"
- path: "scripts/vm-init.sh"
must_contain: ["#!/bin/bash", "docker", "docker-compose"]
description: "VM initialization script for Docker and app setup"
- path: ".env.example"
must_contain: ["AZURE_SUBSCRIPTION_ID", "RESOURCE_GROUP"]
description: "Environment variable template for Docker Compose"
scaffolding:
- path: "infrastructure/azure/bicepconfig.json"
reason: "Bicep configuration for linting rules and module aliases"
- path: "infrastructure/azure/.bicep/modules/"
reason: "Cached Bicep modules (auto-generated)"
- path: "infrastructure/azure/terraform.tfstate"
reason: "Terraform state file if using Terraform instead of Bicep"
- path: "infrastructure/azure/.terraform/"
reason: "Terraform plugins directory if using Terraform"
- path: "scripts/validate-deployment.sh"
reason: "Post-deployment validation and health checks"
- path: "docs/architecture.md"
reason: "Architecture diagram and design decisions"
- path: "docs/runbook.md"
reason: "Operational procedures and troubleshooting guide"
- path: ".github/workflows/bicep-validate.yml"
reason: "CI pipeline for Bicep validation and linting"
- path: ".github/workflows/terraform-plan.yml"
reason: "CI pipeline for Terraform validation (if using Terraform)"
metadata:
primary_blueprints: ["cloud"]
contributes_to:
- "Azure infrastructure provisioning"
- "VNet and networking with Private Endpoints"
- "Managed Identity and RBAC configuration"
- "Compute deployment (Container Apps, AKS, Functions, App Service, VMs)"
- "Database setup (Azure SQL, Cosmos DB, PostgreSQL, MySQL)"
- "Storage configuration (Blob Storage, Files, Disks)"
- "AI integration (Azure OpenAI, Cognitive Services)"
- "Messaging patterns (Service Bus, Event Grid, Event Hubs)"
- "Monitoring and observability (Azure Monitor, Application Insights)"
- "Security and compliance (Key Vault, Policy, Defender)"
- "CI/CD automation (GitHub Actions, Azure DevOps)"
- "Cost optimization and governance"
common_combinations:
- skill: "infrastructure-as-code"
reason: "Bicep and Terraform best practices for Azure"
- skill: "kubernetes-operations"
reason: "AKS cluster management and workload deployment"
- skill: "building-ci-pipelines"
reason: "Azure DevOps and GitHub Actions integration"
- skill: "secret-management"
reason: "Azure Key Vault and Managed Identity patterns"
- skill: "observability"
reason: "Azure Monitor, Application Insights, and Log Analytics"
- skill: "auth-security"
reason: "Entra ID authentication and Conditional Access"
- skill: "ai-chat"
reason: "Azure OpenAI Service integration"
- skill: "databases-nosql"
reason: "Cosmos DB deployment and optimization"
- skill: "implementing-mlops"
reason: "Azure Machine Learning and AI infrastructure"
Azure AI Integration Reference
Comprehensive guide to integrating Azure OpenAI Service, Cognitive Services, and Azure Machine Learning.
Table of Contents
1. Azure OpenAI Service 2. Retrieval-Augmented Generation (RAG) 3. Function Calling 4. Cognitive Services 5. Azure Machine Learning
---
Azure OpenAI Service
Enterprise-grade access to GPT-4, GPT-3.5, embeddings, and other OpenAI models
Key Advantages
| Feature | Benefit |
|---|---|
| Data Privacy | Customer data not used for model training |
| Regional Deployment | Data residency compliance |
| Enterprise SLA | 99.9% uptime guarantee |
| Content Filtering | Built-in abuse monitoring |
| Microsoft Support | Enterprise support contracts |
| Managed Identity | Secure authentication without API keys |
Available Models (2025)
| Model | Use Case | Context Window | Cost per 1K tokens |
|---|---|---|---|
| GPT-4 Turbo | Complex reasoning, coding | 128K | $0.01 input, $0.03 output |
| GPT-4 | Advanced tasks | 8K | $0.03 input, $0.06 output |
| GPT-3.5 Turbo | Simple tasks, chatbots | 16K | $0.0005 input, $0.0015 output |
| text-embedding-ada-002 | Embeddings for RAG | 8K | $0.0001 |
Python SDK Setup
# requirements.txt
openai==1.10.0
azure-identity==1.15.0
azure-search-documents==11.4.0
azure-core==1.29.0
# app.py
import os
from openai import AzureOpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
# Use Managed Identity (recommended)
credential = DefaultAzureCredential()
token_provider = get_bearer_token_provider(
credential,
"https://cognitiveservices.azure.com/.default"
)
client = AzureOpenAI(
azure_endpoint="https://myopenai.openai.azure.com",
azure_ad_token_provider=token_provider,
api_version="2024-02-15-preview"
)
# Chat completion
response = client.chat.completions.create(
model="gpt-4-turbo",
messages=[
{
"role": "system",
"content": "You are a helpful assistant that provides concise answers."
},
{
"role": "user",
"content": "What is the capital of France?"
}
],
temperature=0.2,
max_tokens=500,
top_p=0.95,
frequency_penalty=0,
presence_penalty=0
)
print(response.choices[0].message.content)TypeScript SDK Setup
// package.json
{
"dependencies": {
"@azure/openai": "^1.0.0-beta.11",
"@azure/identity": "^4.0.0"
}
}
// app.ts
import { OpenAIClient, AzureKeyCredential } from "@azure/openai";
import { DefaultAzureCredential } from "@azure/identity";
// Use Managed Identity
const credential = new DefaultAzureCredential();
const endpoint = "https://myopenai.openai.azure.com";
const client = new OpenAIClient(endpoint, credential);
async function getChatCompletion() {
const deploymentName = "gpt-4-turbo";
const messages = [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "What is the capital of France?" }
];
const result = await client.getChatCompletions(deploymentName, messages, {
temperature: 0.2,
maxTokens: 500,
topP: 0.95
});
for (const choice of result.choices) {
console.log(choice.message?.content);
}
}
getChatCompletion();Bicep Deployment
resource openAI 'Microsoft.CognitiveServices/accounts@2023-10-01-preview' = {
name: 'myopenai'
location: location
kind: 'OpenAI'
sku: {
name: 'S0'
}
properties: {
customSubDomainName: 'myopenai'
publicNetworkAccess: 'Disabled' // Use Private Endpoint
networkAcls: {
defaultAction: 'Deny'
}
}
}
// Deploy GPT-4 Turbo model
resource gpt4Deployment 'Microsoft.CognitiveServices/accounts/deployments@2023-10-01-preview' = {
parent: openAI
name: 'gpt-4-turbo'
sku: {
name: 'Standard'
capacity: 10 // Tokens per minute (thousands)
}
properties: {
model: {
format: 'OpenAI'
name: 'gpt-4'
version: 'turbo-2024-04-09'
}
}
}
// Deploy embedding model
resource embeddingDeployment 'Microsoft.CognitiveServices/accounts/deployments@2023-10-01-preview' = {
parent: openAI
name: 'text-embedding-ada-002'
sku: {
name: 'Standard'
capacity: 10
}
properties: {
model: {
format: 'OpenAI'
name: 'text-embedding-ada-002'
version: '2'
}
}
}
// Private Endpoint for OpenAI
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-05-01' = {
name: 'openai-pe'
location: location
properties: {
subnet: {
id: subnet.id
}
privateLinkServiceConnections: [
{
name: 'openai-connection'
properties: {
privateLinkServiceId: openAI.id
groupIds: ['account']
}
}
]
}
}---
Retrieval-Augmented Generation (RAG)
Combine Azure OpenAI with Azure AI Search for grounded responses
RAG Architecture
User Query
↓
Azure AI Search (vector search)
↓
Retrieve top-k relevant documents
↓
Construct prompt with context
↓
Azure OpenAI (GPT-4)
↓
Grounded responsePython RAG Implementation
import os
import json
from openai import AzureOpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from azure.search.documents import SearchClient
from azure.search.documents.models import VectorizedQuery
from azure.core.credentials import AzureKeyCredential
# Azure OpenAI setup
credential = DefaultAzureCredential()
token_provider = get_bearer_token_provider(
credential,
"https://cognitiveservices.azure.com/.default"
)
openai_client = AzureOpenAI(
azure_endpoint="https://myopenai.openai.azure.com",
azure_ad_token_provider=token_provider,
api_version="2024-02-15-preview"
)
# Azure AI Search setup
search_client = SearchClient(
endpoint="https://myaisearch.search.windows.net",
index_name="product-docs",
credential=credential
)
def generate_embedding(text: str) -> list[float]:
"""Generate embedding using Azure OpenAI."""
response = openai_client.embeddings.create(
model="text-embedding-ada-002",
input=text
)
return response.data[0].embedding
def rag_query(user_question: str, top_k: int = 3) -> str:
"""Answer question using RAG pattern with vector search."""
# 1. Generate embedding for user question
question_embedding = generate_embedding(user_question)
# 2. Perform vector search in Azure AI Search
vector_query = VectorizedQuery(
vector=question_embedding,
k_nearest_neighbors=top_k,
fields="contentVector"
)
search_results = search_client.search(
search_text=None, # Pure vector search
vector_queries=[vector_query],
select=["content", "title", "category"]
)
# 3. Build context from search results
context_parts = []
for i, doc in enumerate(search_results, 1):
context_parts.append(
f"Document {i} (Category: {doc['category']}):\n"
f"Title: {doc['title']}\n"
f"Content: {doc['content']}\n"
)
context = "\n".join(context_parts)
# 4. Generate answer with context
system_message = """You are a helpful assistant that answers questions based on the provided context.
Rules:
- Only use information from the provided documents
- If the answer is not in the context, say "I don't have enough information to answer that question."
- Cite which document(s) you used
- Be concise and accurate
"""
response = openai_client.chat.completions.create(
model="gpt-4-turbo",
messages=[
{"role": "system", "content": system_message},
{"role": "user", "content": f"Context:\n{context}\n\nQuestion: {user_question}"}
],
temperature=0.2,
max_tokens=500
)
return response.choices[0].message.content
# Example usage
if __name__ == "__main__":
question = "What are the key features of Azure Container Apps?"
answer = rag_query(question)
print(f"Question: {question}\n")
print(f"Answer: {answer}")Azure AI Search Index Setup
resource searchService 'Microsoft.Search/searchServices@2023-11-01' = {
name: 'myaisearch'
location: location
sku: {
name: 'basic' // basic, standard, standard2, standard3
}
properties: {
replicaCount: 1
partitionCount: 1
hostingMode: 'default'
publicNetworkAccess: 'disabled' // Use Private Endpoint
}
}
// Note: Index schema defined via SDK or REST APIIndex Schema Example (Python SDK)
from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import (
SearchIndex,
SearchField,
SearchFieldDataType,
VectorSearch,
HnswAlgorithmConfiguration,
VectorSearchProfile
)
index_client = SearchIndexClient(
endpoint="https://myaisearch.search.windows.net",
credential=credential
)
# Define index schema
index = SearchIndex(
name="product-docs",
fields=[
SearchField(
name="id",
type=SearchFieldDataType.String,
key=True,
sortable=True
),
SearchField(
name="content",
type=SearchFieldDataType.String,
searchable=True
),
SearchField(
name="title",
type=SearchFieldDataType.String,
searchable=True,
filterable=True
),
SearchField(
name="category",
type=SearchFieldDataType.String,
filterable=True,
facetable=True
),
SearchField(
name="contentVector",
type=SearchFieldDataType.Collection(SearchFieldDataType.Single),
searchable=True,
vector_search_dimensions=1536, # text-embedding-ada-002 dimension
vector_search_profile_name="my-vector-profile"
)
],
vector_search=VectorSearch(
profiles=[
VectorSearchProfile(
name="my-vector-profile",
algorithm_configuration_name="my-hnsw-config"
)
],
algorithms=[
HnswAlgorithmConfiguration(
name="my-hnsw-config",
parameters={
"m": 4,
"efConstruction": 400,
"efSearch": 500,
"metric": "cosine"
}
)
]
)
)
# Create index
index_client.create_or_update_index(index)---
Function Calling
Structured outputs and tool use with Azure OpenAI
Use Cases
- Extract structured data from unstructured text
- Execute actions based on user intent (book appointments, query databases)
- Multi-step workflows (agent patterns)
- API integration (call external services)
Python Function Calling Example
import json
from openai import AzureOpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
credential = DefaultAzureCredential()
token_provider = get_bearer_token_provider(
credential,
"https://cognitiveservices.azure.com/.default"
)
client = AzureOpenAI(
azure_endpoint="https://myopenai.openai.azure.com",
azure_ad_token_provider=token_provider,
api_version="2024-02-15-preview"
)
# Define available functions
def get_current_weather(location: str, unit: str = "celsius") -> dict:
"""Get current weather for a location (mock implementation)."""
# In production, call actual weather API
return {
"location": location,
"temperature": 22,
"unit": unit,
"conditions": "Partly cloudy"
}
def book_appointment(date: str, time: str, service: str) -> dict:
"""Book an appointment (mock implementation)."""
return {
"confirmation": "APT-12345",
"date": date,
"time": time,
"service": service,
"status": "confirmed"
}
# Define function schemas for the model
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "The temperature unit"
}
},
"required": ["location"]
}
}
},
{
"type": "function",
"function": {
"name": "book_appointment",
"description": "Book an appointment for a service",
"parameters": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "The appointment date in YYYY-MM-DD format"
},
"time": {
"type": "string",
"description": "The appointment time in HH:MM format"
},
"service": {
"type": "string",
"description": "The service type (e.g., haircut, consultation)"
}
},
"required": ["date", "time", "service"]
}
}
}
]
# Map function names to actual functions
available_functions = {
"get_current_weather": get_current_weather,
"book_appointment": book_appointment
}
def run_conversation(user_message: str) -> str:
"""Run conversation with function calling."""
messages = [
{"role": "system", "content": "You are a helpful assistant that can check weather and book appointments."},
{"role": "user", "content": user_message}
]
# Initial API call with tools
response = client.chat.completions.create(
model="gpt-4-turbo",
messages=messages,
tools=tools,
tool_choice="auto" # Let model decide when to use functions
)
response_message = response.choices[0].message
messages.append(response_message)
# Check if model wants to call functions
if response_message.tool_calls:
# Execute each function call
for tool_call in response_message.tool_calls:
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
print(f"Calling function: {function_name}")
print(f"Arguments: {function_args}")
# Call the function
function_response = available_functions[function_name](**function_args)
# Add function response to messages
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"name": function_name,
"content": json.dumps(function_response)
})
# Get final response after function execution
second_response = client.chat.completions.create(
model="gpt-4-turbo",
messages=messages
)
return second_response.choices[0].message.content
else:
return response_message.content
# Example usage
if __name__ == "__main__":
# Weather query
result = run_conversation("What's the weather like in Seattle?")
print(f"Result: {result}\n")
# Appointment booking
result = run_conversation("Book me a haircut appointment tomorrow at 2pm")
print(f"Result: {result}")---
Cognitive Services
Pre-built AI models for vision, speech, language, and decision
Service Categories
| Category | Services | Use Cases |
|---|---|---|
| Vision | Computer Vision, Custom Vision, Face | OCR, object detection, image classification |
| Speech | Speech-to-Text, Text-to-Speech, Translation | Transcription, voice assistants, real-time translation |
| Language | Text Analytics, Translator, Language Understanding | Sentiment analysis, entity extraction, NER |
| Decision | Anomaly Detector, Content Moderator | Fraud detection, content filtering |
Computer Vision Example
from azure.cognitiveservices.vision.computervision import ComputerVisionClient
from azure.identity import DefaultAzureCredential
from msrest.authentication import CognitiveServicesCredentials
# Using API key (or use Managed Identity)
credential = CognitiveServicesCredentials(os.environ["VISION_KEY"])
client = ComputerVisionClient(
endpoint="https://myregion.api.cognitive.microsoft.com",
credentials=credential
)
# Analyze image
image_url = "https://example.com/image.jpg"
features = ["categories", "description", "tags", "objects", "brands", "faces"]
analysis = client.analyze_image(image_url, visual_features=features)
print(f"Description: {analysis.description.captions[0].text}")
print(f"Tags: {[tag.name for tag in analysis.tags]}")
print(f"Objects detected: {len(analysis.objects)}")
for obj in analysis.objects:
print(f" - {obj.object_property} (confidence: {obj.confidence:.2f})")Text Analytics Example
from azure.ai.textanalytics import TextAnalyticsClient
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
client = TextAnalyticsClient(
endpoint="https://myregion.api.cognitive.microsoft.com",
credential=credential
)
documents = [
"The food was delicious and the service was excellent!",
"I had a terrible experience. The product broke after one day."
]
# Sentiment analysis
result = client.analyze_sentiment(documents, show_opinion_mining=True)
for idx, doc in enumerate(result):
print(f"\nDocument {idx + 1}: {documents[idx]}")
print(f"Sentiment: {doc.sentiment} (confidence: {doc.confidence_scores})")
# Opinion mining
for sentence in doc.sentences:
for opinion in sentence.mined_opinions:
print(f" Target: {opinion.target.text} ({opinion.target.sentiment})")
for assessment in opinion.assessments:
print(f" Assessment: {assessment.text} ({assessment.sentiment})")
# Named Entity Recognition (NER)
entities_result = client.recognize_entities(documents)
for doc in entities_result:
for entity in doc.entities:
print(f"Entity: {entity.text} (Type: {entity.category}, Confidence: {entity.confidence_score:.2f})")---
Azure Machine Learning
End-to-end platform for custom model training and MLOps
When to Use Azure ML
Choose Azure ML when:
- Training custom models (pre-built Cognitive Services insufficient)
- Need MLOps capabilities (experiment tracking, model versioning)
- Require distributed training (multi-GPU, multi-node)
- Building feature engineering pipelines
- Deploying models to managed endpoints
Azure ML Workspace Bicep
resource mlWorkspace 'Microsoft.MachineLearningServices/workspaces@2023-10-01' = {
name: 'ml-workspace'
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
friendlyName: 'ML Workspace'
storageAccount: storageAccount.id
keyVault: keyVault.id
applicationInsights: appInsights.id
containerRegistry: acr.id
publicNetworkAccess: 'Disabled'
}
}
// Compute cluster for training
resource computeCluster 'Microsoft.MachineLearningServices/workspaces/computes@2023-10-01' = {
parent: mlWorkspace
name: 'gpu-cluster'
location: location
properties: {
computeType: 'AmlCompute'
properties: {
vmSize: 'Standard_NC6s_v3'
vmPriority: 'Dedicated'
scaleSettings: {
minNodeCount: 0
maxNodeCount: 4
nodeIdleTimeBeforeScaleDown: 'PT120S'
}
}
}
}Python SDK Training Example
from azure.ai.ml import MLClient, command, Input
from azure.identity import DefaultAzureCredential
# Connect to workspace
credential = DefaultAzureCredential()
ml_client = MLClient(
credential=credential,
subscription_id="<subscription-id>",
resource_group_name="<resource-group>",
workspace_name="ml-workspace"
)
# Define training job
job = command(
code="./src",
command="python train.py --data ${{inputs.training_data}} --epochs ${{inputs.epochs}}",
inputs={
"training_data": Input(
type="uri_folder",
path="azureml://datastores/workspaceblobstore/paths/training-data/"
),
"epochs": 10
},
environment="azureml:sklearn-env@latest",
compute="gpu-cluster",
display_name="train-model-v1"
)
# Submit job
returned_job = ml_client.jobs.create_or_update(job)
print(f"Job URL: {returned_job.studio_url}")---
Summary
| Service | Best For | Complexity | Cost Model |
|---|---|---|---|
| Azure OpenAI | Chat, embeddings, content generation | Low | Per token |
| Cognitive Services | Pre-built AI (vision, speech, language) | Low | Per transaction |
| Azure ML | Custom models, MLOps | High | Compute + storage |
| Azure AI Search | Semantic search, RAG patterns | Medium | Index size + queries |
Recommendation: Start with Azure OpenAI and Cognitive Services for 90% of AI use cases. Use Azure ML only when custom model training required.
Azure Compute Services Reference
Comprehensive guide to Azure compute service selection, configuration, and implementation patterns.
Table of Contents
1. Azure Container Apps 2. Azure Kubernetes Service (AKS) 3. Azure Functions 4. Azure App Service 5. Virtual Machines 6. Cost Comparison
---
Azure Container Apps
Best For: Microservices, APIs, background workers, event-driven applications
Key Features:
- Fully managed container platform (no node management)
- Built-in KEDA for event-driven autoscaling
- Dapr integration for microservices patterns
- Automatic HTTPS with custom domains
- Traffic splitting for blue-green deployments
When to Use Container Apps
Choose Container Apps when:
- Building microservices architecture
- Need Kubernetes benefits without operational overhead
- Event-driven scaling (HTTP, queue depth, custom metrics)
- Want lower cost than AKS
- Dapr integration for distributed patterns
Avoid Container Apps when:
- Need full Kubernetes control plane access
- Require custom CRDs or operators
- Complex service mesh (Istio, Linkerd)
- Existing Helm chart dependencies
Bicep Implementation
// Container App Environment (shared by multiple apps)
resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' = {
name: 'production-env'
location: location
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: logAnalytics.properties.customerId
sharedKey: logAnalytics.listKeys().primarySharedKey
}
}
zoneRedundant: true
vnetConfiguration: {
infrastructureSubnetId: subnet.id
internal: true // Private environment
}
}
}
// Container App with autoscaling
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
name: 'api-service'
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
managedEnvironmentId: containerAppEnvironment.id
configuration: {
activeRevisionsMode: 'Single'
ingress: {
external: true
targetPort: 8080
transport: 'http2'
allowInsecure: false
traffic: [
{
latestRevision: true
weight: 100
}
]
customDomains: [
{
name: 'api.example.com'
bindingType: 'SniEnabled'
certificateId: certificate.id
}
]
}
secrets: [
{
name: 'db-connection-string'
keyVaultUrl: 'https://keyvault.vault.azure.net/secrets/db-conn'
identity: 'system'
}
{
name: 'api-key'
value: apiKey
}
]
registries: [
{
server: 'myregistry.azurecr.io'
identity: 'system'
}
]
}
template: {
containers: [
{
name: 'api'
image: 'myregistry.azurecr.io/api:latest'
resources: {
cpu: json('1.0')
memory: '2Gi'
}
env: [
{
name: 'DATABASE_URL'
secretRef: 'db-connection-string'
}
{
name: 'API_KEY'
secretRef: 'api-key'
}
{
name: 'ENVIRONMENT'
value: 'production'
}
]
probes: [
{
type: 'Liveness'
httpGet: {
path: '/health'
port: 8080
}
initialDelaySeconds: 10
periodSeconds: 10
}
{
type: 'Readiness'
httpGet: {
path: '/ready'
port: 8080
}
initialDelaySeconds: 5
periodSeconds: 5
}
]
}
]
scale: {
minReplicas: 2
maxReplicas: 50
rules: [
// HTTP concurrency scaling
{
name: 'http-scaling-rule'
http: {
metadata: {
concurrentRequests: '100'
}
}
}
// Azure Service Bus queue scaling
{
name: 'queue-scaling-rule'
custom: {
type: 'azure-servicebus'
metadata: {
queueName: 'orders'
messageCount: '10'
namespace: 'myservicebus'
}
auth: [
{
secretRef: 'servicebus-connection'
triggerParameter: 'connection'
}
]
}
}
// Time-based scaling (business hours)
{
name: 'business-hours-rule'
custom: {
type: 'cron'
metadata: {
timezone: 'America/New_York'
start: '0 8 * * MON-FRI'
end: '0 18 * * MON-FRI'
desiredReplicas: '20'
}
}
}
]
}
}
}
}Terraform Implementation
resource "azurerm_container_app_environment" "main" {
name = "production-env"
location = var.location
resource_group_name = azurerm_resource_group.main.name
log_analytics_workspace_id = azurerm_log_analytics_workspace.main.id
zone_redundancy_enabled = true
infrastructure_subnet_id = azurerm_subnet.container_apps.id
internal_load_balancer_enabled = true
}
resource "azurerm_container_app" "api" {
name = "api-service"
container_app_environment_id = azurerm_container_app_environment.main.id
resource_group_name = azurerm_resource_group.main.name
revision_mode = "Single"
identity {
type = "SystemAssigned"
}
registry {
server = "myregistry.azurecr.io"
identity = "system"
}
secret {
name = "db-connection-string"
key_vault_secret_id = azurerm_key_vault_secret.db_conn.id
identity = "system"
}
template {
container {
name = "api"
image = "myregistry.azurecr.io/api:latest"
cpu = 1.0
memory = "2Gi"
env {
name = "DATABASE_URL"
secret_name = "db-connection-string"
}
liveness_probe {
transport = "HTTP"
port = 8080
path = "/health"
}
readiness_probe {
transport = "HTTP"
port = 8080
path = "/ready"
}
}
min_replicas = 2
max_replicas = 50
http_scale_rule {
name = "http-scaling"
concurrent_requests = 100
}
custom_scale_rule {
name = "queue-scaling"
custom_rule_type = "azure-servicebus"
metadata = {
queueName = "orders"
messageCount = "10"
namespace = "myservicebus"
}
authentication {
secret_name = "servicebus-connection"
trigger_parameter = "connection"
}
}
}
ingress {
external_enabled = true
target_port = 8080
transport = "http2"
custom_domain {
name = "api.example.com"
certificate_id = azurerm_container_app_certificate.main.id
}
traffic_weight {
latest_revision = true
percentage = 100
}
}
}---
Azure Kubernetes Service (AKS)
Best For: Complex Kubernetes workloads, service mesh, multi-tenant clusters, custom operators
Key Features:
- Fully managed Kubernetes control plane
- Multiple node pools with different VM sizes
- Azure CNI or Kubenet networking
- Workload Identity for pod-level authentication
- Integrated monitoring with Azure Monitor
When to Use AKS
Choose AKS when:
- Need full Kubernetes control plane access
- Using Helm charts with complex dependencies
- Implementing service mesh (Istio, Linkerd)
- Require custom CRDs and operators
- Multi-tenant cluster with advanced RBAC
- Existing Kubernetes expertise
Avoid AKS when:
- Simple container hosting needs
- Limited Kubernetes knowledge
- Want to minimize operational overhead
- Cost-sensitive (Container Apps cheaper for most workloads)
Bicep Implementation
resource aks 'Microsoft.ContainerService/managedClusters@2024-01-01' = {
name: 'production-aks'
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
dnsPrefix: 'production-aks'
kubernetesVersion: '1.28'
enableRBAC: true
aadProfile: {
managed: true
enableAzureRBAC: true
adminGroupObjectIDs: [
adminGroupId
]
}
networkProfile: {
networkPlugin: 'azure' // Azure CNI
networkPolicy: 'calico'
loadBalancerSku: 'standard'
serviceCidr: '10.0.0.0/16'
dnsServiceIP: '10.0.0.10'
outboundType: 'loadBalancer'
}
agentPoolProfiles: [
// System node pool (for kube-system pods)
{
name: 'systempool'
count: 3
vmSize: 'Standard_D4s_v5'
mode: 'System'
osType: 'Linux'
osSKU: 'AzureLinux'
availabilityZones: ['1', '2', '3']
enableAutoScaling: true
minCount: 3
maxCount: 6
nodeTaints: [
'CriticalAddonsOnly=true:NoSchedule'
]
}
// User node pool (for application workloads)
{
name: 'userpool'
count: 3
vmSize: 'Standard_D8s_v5'
mode: 'User'
osType: 'Linux'
osSKU: 'AzureLinux'
availabilityZones: ['1', '2', '3']
enableAutoScaling: true
minCount: 3
maxCount: 20
maxPods: 110
}
// GPU node pool (for ML workloads)
{
name: 'gpupool'
count: 0
vmSize: 'Standard_NC6s_v3'
mode: 'User'
osType: 'Linux'
enableAutoScaling: true
minCount: 0
maxCount: 5
nodeTaints: [
'nvidia.com/gpu=true:NoSchedule'
]
}
]
addonProfiles: {
azureKeyvaultSecretsProvider: {
enabled: true
config: {
enableSecretRotation: 'true'
rotationPollInterval: '2m'
}
}
azurepolicy: {
enabled: true
}
omsagent: {
enabled: true
config: {
logAnalyticsWorkspaceResourceID: logAnalytics.id
}
}
}
oidcIssuerProfile: {
enabled: true
}
securityProfile: {
workloadIdentity: {
enabled: true
}
defender: {
logAnalyticsWorkspaceResourceId: logAnalytics.id
securityMonitoring: {
enabled: true
}
}
}
autoUpgradeProfile: {
upgradeChannel: 'stable'
}
}
}
// Grant AKS access to pull images from ACR
resource acrPullRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(aks.id, acr.id, 'AcrPull')
scope: acr
properties: {
principalId: aks.properties.identityProfile.kubeletidentity.objectId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
}
}---
Azure Functions
Best For: Event-driven workloads, short-duration tasks, serverless APIs
Key Features:
- Multiple trigger types (HTTP, Timer, Queue, Blob, Event Hub)
- Consumption pricing (pay per execution)
- Premium plan for VNet integration and longer timeouts
- Durable Functions for stateful orchestrations
- Python, Node.js, .NET, Java, PowerShell support
Hosting Plans
| Plan | Max Duration | Pricing | VNet Integration | Use Case |
|---|---|---|---|---|
| Consumption | 5 minutes (default) | Per execution | No | Unpredictable traffic, cost-sensitive |
| Premium | 60 minutes (default) | Per hour running | Yes | Predictable traffic, VNet required |
| Dedicated (App Service) | Unlimited | App Service Plan | Yes | Existing App Service capacity |
Python Function Example
# function_app.py
import azure.functions as func
import logging
import json
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
from azure.storage.blob import BlobServiceClient
app = func.FunctionApp()
# HTTP trigger with Managed Identity
@app.function_name(name="ProcessOrder")
@app.route(route="orders", methods=["POST"], auth_level=func.AuthLevel.FUNCTION)
def process_order(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Processing order request')
try:
# Get order from request body
order = req.get_json()
# Use Managed Identity to access Key Vault
credential = DefaultAzureCredential()
keyvault_client = SecretClient(
vault_url="https://mykeyvault.vault.azure.net",
credential=credential
)
api_key = keyvault_client.get_secret("external-api-key").value
# Process order...
logging.info(f"Order {order['id']} processed successfully")
return func.HttpResponse(
json.dumps({"status": "success", "order_id": order['id']}),
mimetype="application/json",
status_code=200
)
except ValueError as e:
return func.HttpResponse(
json.dumps({"error": "Invalid JSON"}),
mimetype="application/json",
status_code=400
)
except Exception as e:
logging.error(f"Error processing order: {e}")
return func.HttpResponse(
json.dumps({"error": "Internal server error"}),
mimetype="application/json",
status_code=500
)
# Queue trigger (Azure Storage Queue)
@app.function_name(name="ProcessQueueMessage")
@app.queue_trigger(arg_name="msg", queue_name="orders", connection="AzureWebJobsStorage")
def process_queue_message(msg: func.QueueMessage) -> None:
logging.info(f'Processing queue message: {msg.id}')
order = json.loads(msg.get_body().decode('utf-8'))
logging.info(f"Order ID: {order['id']}, Total: {order['total']}")
# Process order asynchronously...
# Timer trigger (runs every 5 minutes)
@app.function_name(name="CleanupOldData")
@app.schedule(schedule="0 */5 * * * *", arg_name="timer", run_on_startup=False)
def cleanup_old_data(timer: func.TimerRequest) -> None:
if timer.past_due:
logging.info('Timer is past due!')
logging.info('Running cleanup job...')
# Cleanup old data, send reports, etc.
# Blob trigger (fires when blob created)
@app.function_name(name="ProcessUploadedImage")
@app.blob_trigger(arg_name="blob", path="uploads/{name}", connection="AzureWebJobsStorage")
@app.blob_output(arg_name="outputblob", path="processed/{name}", connection="AzureWebJobsStorage")
def process_uploaded_image(blob: func.InputStream, outputblob: func.Out[bytes]) -> None:
logging.info(f'Processing blob: {blob.name}, Size: {blob.length} bytes')
# Read blob content
content = blob.read()
# Process image (resize, compress, etc.)
processed_content = content # Placeholder
# Write to output blob
outputblob.set(processed_content)Bicep Deployment
resource functionApp 'Microsoft.Web/sites@2023-01-01' = {
name: 'my-function-app'
location: location
kind: 'functionapp,linux'
identity: {
type: 'SystemAssigned'
}
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
siteConfig: {
linuxFxVersion: 'Python|3.11'
appSettings: [
{
name: 'AzureWebJobsStorage__accountName'
value: storageAccount.name
}
{
name: 'FUNCTIONS_EXTENSION_VERSION'
value: '~4'
}
{
name: 'FUNCTIONS_WORKER_RUNTIME'
value: 'python'
}
{
name: 'KEY_VAULT_URL'
value: 'https://mykeyvault.vault.azure.net'
}
]
ftpsState: 'Disabled'
minTlsVersion: '1.2'
}
}
}---
Azure App Service
Best For: Web applications, REST APIs, mobile backends
Key Features:
- Built-in CI/CD with GitHub Actions
- Deployment slots for staging/production
- Auto-scaling based on metrics
- Custom domains and SSL certificates
- Multiple language support (.NET, Node.js, Python, PHP, Java)
When to Use App Service
Choose App Service when:
- Building traditional web applications
- Need easy deployment slots (blue-green)
- Want integrated CI/CD
- Simple autoscaling requirements
- Multi-language support needed
Service Plan Tiers
| Tier | vCPUs | RAM | Auto-scale | VNet | Price/Month |
|---|---|---|---|---|---|
| F1 (Free) | Shared | 1 GB | No | No | $0 |
| B1 (Basic) | 1 | 1.75 GB | No | No | ~$13 |
| S1 (Standard) | 1 | 1.75 GB | Yes | No | ~$70 |
| P1v3 (Premium) | 2 | 8 GB | Yes | Yes | ~$145 |
| I1v2 (Isolated) | 2 | 8 GB | Yes | Yes (dedicated) | ~$400 |
Bicep Implementation
resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
name: 'production-plan'
location: location
sku: {
name: 'P1v3'
tier: 'PremiumV3'
capacity: 3
}
kind: 'linux'
properties: {
reserved: true // Required for Linux
zoneRedundant: true
}
}
resource webApp 'Microsoft.Web/sites@2023-01-01' = {
name: 'myapp'
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
clientAffinityEnabled: false // Disable sticky sessions for stateless apps
siteConfig: {
linuxFxVersion: 'NODE|18-lts'
minTlsVersion: '1.2'
ftpsState: 'Disabled'
http20Enabled: true
alwaysOn: true
appSettings: [
{
name: 'DATABASE_URL'
value: '@Microsoft.KeyVault(VaultName=mykeyvault;SecretName=db-connection-string)'
}
{
name: 'WEBSITE_RUN_FROM_PACKAGE'
value: '1'
}
]
healthCheckPath: '/health'
}
}
}
// Deployment slot (staging)
resource stagingSlot 'Microsoft.Web/sites/slots@2023-01-01' = {
parent: webApp
name: 'staging'
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
linuxFxVersion: 'NODE|18-lts'
appSettings: [
{
name: 'ENVIRONMENT'
value: 'staging'
}
]
}
}
}
// Autoscale rule
resource autoscale 'Microsoft.Insights/autoscalesettings@2022-10-01' = {
name: 'app-autoscale'
location: location
properties: {
targetResourceUri: appServicePlan.id
enabled: true
profiles: [
{
name: 'Auto scale condition'
capacity: {
minimum: '3'
maximum: '20'
default: '3'
}
rules: [
{
metricTrigger: {
metricName: 'CpuPercentage'
metricResourceUri: appServicePlan.id
timeGrain: 'PT1M'
statistic: 'Average'
timeWindow: 'PT5M'
timeAggregation: 'Average'
operator: 'GreaterThan'
threshold: 70
}
scaleAction: {
direction: 'Increase'
type: 'ChangeCount'
value: '2'
cooldown: 'PT5M'
}
}
{
metricTrigger: {
metricName: 'CpuPercentage'
metricResourceUri: appServicePlan.id
timeGrain: 'PT1M'
statistic: 'Average'
timeWindow: 'PT5M'
timeAggregation: 'Average'
operator: 'LessThan'
threshold: 30
}
scaleAction: {
direction: 'Decrease'
type: 'ChangeCount'
value: '1'
cooldown: 'PT10M'
}
}
]
}
]
}
}---
Virtual Machines
Best For: Legacy applications, specialized software, lift-and-shift migrations
When to Use VMs:
- Legacy applications requiring specific OS configurations
- Third-party software with licensing requirements
- Lift-and-shift migrations
- Applications requiring VM-level access
When to Avoid VMs:
- PaaS options available (Container Apps, App Service)
- Modern cloud-native applications
- Cost-sensitive workloads (VMs more expensive to operate)
VM Size Selection
| Series | CPU:RAM Ratio | Use Case | Example Sizes |
|---|---|---|---|
| B-series | Burstable | Dev/test, low CPU | B2s, B4ms |
| D-series | Balanced (1:4) | General purpose web apps | D4s_v5, D8s_v5 |
| E-series | Memory (1:8) | Databases, caching | E4s_v5, E8s_v5 |
| F-series | Compute (1:2) | Batch processing, analytics | F4s_v2, F8s_v2 |
| N-series | GPU | ML training, rendering | NC6s_v3, ND96asr_v4 |
---
Cost Comparison
Approximate Monthly Costs (US East, 24/7 operation, 2025)
| Service | Configuration | Cost/Month | Notes |
|---|---|---|---|
| Container Apps | 1 vCPU, 2GB RAM | ~$60 | Consumption model, actual usage |
| Container Apps | 4 vCPU, 8GB RAM | ~$240 | High-traffic API |
| AKS | 3-node D4s_v5 | ~$400 | Plus node costs |
| Functions | Premium EP1 (1 vCPU, 3.5GB) | ~$140 | 24/7 premium plan |
| Functions | Consumption | ~$20 | 1M executions, 400ms avg |
| App Service | P1v3 (2 vCPU, 8GB) | ~$145 | Includes 3 deployment slots |
| VM | D4s_v5 (4 vCPU, 16GB) | ~$140 | Plus OS, storage, egress |
Cost Optimization Strategies
1. Use Reserved Instances: 40-60% savings for predictable workloads (VMs, App Service) 2. Leverage Consumption Pricing: Functions, Container Apps for variable traffic 3. Auto-scaling: Scale down during off-hours 4. Spot VMs: Up to 90% savings for fault-tolerant batch workloads 5. Right-sizing: Monitor and resize VMs based on actual usage
---
Summary Decision Matrix
| If You Need... | Choose | Why |
|---|---|---|
| Kubernetes features | AKS | Full control, CRDs, operators |
| Microservices without K8s | Container Apps | Simpler, cheaper, KEDA built-in |
| Event-driven functions | Functions | Pay per execution, multiple triggers |
| Web app with CI/CD | App Service | Deployment slots, easy GitHub integration |
| Legacy migration | VMs | VM-level access, specialized software |
| Batch processing | Azure Batch or Spot VMs | Cost-effective for fault-tolerant jobs |
Azure Database Selection Reference
Comprehensive guide to selecting and configuring Azure database services.
Table of Contents
1. Azure SQL Database 2. Cosmos DB 3. PostgreSQL Flexible Server 4. MySQL Flexible Server 5. Azure Cache for Redis
---
Azure SQL Database
Managed relational database service with elastic scalability and built-in high availability.
Service Tiers
| Tier | vCores | RAM | Max Storage | Use Case |
|---|---|---|---|---|
| Serverless | 0.5-40 | Auto | 4 TB | Variable workloads |
| Provisioned (General Purpose) | 2-80 | 5-415 GB | 4 TB | Most workloads |
| Hyperscale | 2-80 | 5-415 GB | 100 TB | Large databases |
| Business Critical | 2-80 | 5-415 GB | 4 TB | Low latency, HA |
---
Cosmos DB
Globally distributed, multi-model NoSQL database with multiple consistency models and APIs.
API Selection
| API | Data Model | Use Case |
|---|---|---|
| NoSQL | Document (JSON) | General purpose, new apps |
| MongoDB | Document (BSON) | MongoDB compatibility |
| Cassandra | Wide-column | Time-series, IoT |
| Gremlin | Graph | Social networks, recommendations |
| Table | Key-value | Simple key-value storage |
---
PostgreSQL Flexible Server
Azure-managed PostgreSQL with flexible configuration options.
Advantages:
- Zone-redundant HA
- Flexible maintenance windows
- Built-in connection pooling (PgBouncer)
- Point-in-time restore
---
MySQL Flexible Server
Azure-managed MySQL with enterprise features.
Advantages:
- Zone-redundant HA
- Read replicas
- Automatic backups
- Burstable tier for dev/test
---
Azure Cache for Redis
In-memory cache for session state, caching, and real-time analytics.
Tiers
| Tier | Clustering | Persistence | Use Case |
|---|---|---|---|
| Basic | No | No | Dev/test |
| Standard | No | No | Production cache |
| Premium | Yes | Yes | Enterprise, HA |
| Enterprise | Yes | Yes | Active geo-replication |
Azure Governance and Compliance Reference
Comprehensive guide to Azure Policy, Blueprints, and cost management.
Table of Contents
1. Azure Policy 2. Azure Blueprints 3. Cost Management 4. Resource Tagging 5. Azure Landing Zones
---
Azure Policy
Governance service to enforce organizational standards and assess compliance at scale.
Policy Effects
| Effect | Behavior | Use Case |
|---|---|---|
| Deny | Block resource creation/update | Prevent non-compliant resources |
| Audit | Log compliance | Visibility without blocking |
| AuditIfNotExists | Check for related resources | Ensure diagnostics enabled |
| DeployIfNotExists | Auto-remediate | Deploy missing configurations |
| Modify | Change properties | Add missing tags |
| Disabled | Turn off policy | Testing |
Common Policies
- Allowed resource types
- Allowed locations
- Required tags
- Storage account encryption
- Network security rules
- SQL Database TDE
---
Azure Blueprints
Repeatable environment deployment with policy, RBAC, and ARM templates.
Blueprint Components
1. Artifacts: Policy assignments, role assignments, ARM templates 2. Parameters: Environment-specific values 3. Versions: Track changes over time
Use Cases
- Regulatory compliance (ISO 27001, HIPAA, PCI-DSS)
- Landing zone deployment
- Multi-region rollouts
---
Cost Management
Monitor, allocate, and optimize Azure spending across organization.
Cost Allocation Tags
Required tags for cost tracking:
- Environment (dev, staging, production)
- CostCenter (billing code)
- Owner (team responsible)
- Project (initiative)
Azure Advisor Cost Recommendations
- Right-size underutilized VMs
- Delete unattached disks
- Purchase Reserved Instances
- Enable auto-pause for SQL serverless
- Optimize storage tiers
---
Resource Tagging
Tag Strategy
| Tag Name | Values | Purpose |
|---|---|---|
| Environment | dev, staging, production | Lifecycle management |
| Owner | team@example.com | Accountability |
| CostCenter | CC-1234 | Chargeback |
| Project | project-alpha | Initiative tracking |
| Criticality | low, medium, high | SLA/support priority |
| Compliance | pci, hipaa, sox | Regulatory requirements |
Tag Inheritance
Tags on Resource Groups do NOT inherit to resources automatically (use Azure Policy to enforce).
---
Azure Landing Zones
Enterprise-scale architecture for Azure adoption.
Core Components
1. Management Groups: Hierarchical organization 2. Subscriptions: Billing and resource boundaries 3. Policies: Governance guardrails 4. Networking: Hub-spoke topology 5. Identity: Entra ID integration 6. Security: Microsoft Defender for Cloud
Reference Architectures
- CAF (Cloud Adoption Framework) Landing Zones
- Azure Landing Zone Accelerator
- Industry-specific landing zones (FSI, healthcare)
Azure Identity and Access Management Reference
Comprehensive guide to Azure Entra ID, Managed Identity, and RBAC patterns.
Table of Contents
1. Managed Identity 2. Azure RBAC 3. Entra ID (Azure AD) 4. Conditional Access
---
Managed Identity
Azure-managed identity for applications to authenticate to Azure services without storing credentials.
System-Assigned vs. User-Assigned
| Aspect | System-Assigned | User-Assigned |
|---|---|---|
| Lifecycle | Tied to resource | Independent |
| Sharing | One resource only | Multiple resources |
| Use Case | Single resource needs access | Shared identity across resources |
| Deletion | Auto-deleted with resource | Manual deletion |
Common Access Patterns
from azure.identity import DefaultAzureCredential
# Works with both system and user-assigned identities
credential = DefaultAzureCredential()
# Use with any Azure SDK
from azure.keyvault.secrets import SecretClient
client = SecretClient(vault_url="https://mykv.vault.azure.net", credential=credential)---
Azure RBAC
Role-Based Access Control for fine-grained permissions.
Built-In Roles
| Role | Permissions | Use Case |
|---|---|---|
| Owner | Full access + manage access | Subscription/RG admins |
| Contributor | Full access (no access mgmt) | Developers, operators |
| Reader | Read-only | Auditors, viewers |
| Key Vault Secrets User | Read secrets | Apps accessing secrets |
| Storage Blob Data Contributor | Read/write blobs | Apps using Blob Storage |
Best Practices
- Assign roles at Resource Group level (not subscription)
- Use built-in roles when possible
- Create custom roles only when necessary
- Assign to Azure AD groups (not individual users)
- Audit role assignments quarterly
---
Entra ID (Azure AD)
Cloud-based identity and access management service.
Authentication Patterns
- OAuth 2.0 / OpenID Connect
- SAML 2.0 (for legacy apps)
- Managed Identity (for Azure resources)
Multi-Tenant Applications
Register app in Entra ID for multi-org SaaS applications.
---
Conditional Access
Risk-based access policies.
Common Policies
- Require MFA for admins
- Block legacy authentication
- Require compliant devices
- Restrict access by location
- Require approved client apps
Azure Messaging Patterns Reference
Comprehensive guide to Azure messaging and event services.
Table of Contents
1. Azure Service Bus 2. Azure Event Grid 3. Azure Event Hubs 4. Storage Queues
---
Azure Service Bus
Enterprise messaging service with queues and publish-subscribe topics.
Queue vs. Topic
| Feature | Queue | Topic/Subscription |
|---|---|---|
| Pattern | Point-to-point | Publish-subscribe |
| Receivers | Single consumer | Multiple subscribers |
| Filtering | No | Yes (SQL filters) |
| Use Case | Task distribution | Event broadcasting |
Sessions for Ordered Processing
Enable sessions for FIFO (first-in-first-out) message processing within a session.
---
Azure Event Grid
Event routing service for reactive programming.
Event Domains
Group related topics for multi-tenant scenarios.
Advanced Filtering
Filter events by subject, data fields, and event type before delivery.
---
Azure Event Hubs
Big data streaming platform for telemetry and event ingestion.
Partitioning Strategy
Partition by key (e.g., device ID) for ordered processing within partition.
Capture Feature
Automatically archive events to Blob Storage or Data Lake.
---
Storage Queues
Simple queue for asynchronous messaging.
When to Use:
- Simple task queues
- Cost-sensitive (<500k messages/sec)
- No advanced features needed (transactions, sessions)
Azure Networking Architecture Reference
Comprehensive guide to Azure networking patterns and architectures.
Table of Contents
1. Hub-and-Spoke Topology 2. Private Endpoints 3. Network Security Groups 4. Load Balancing 5. DNS Configuration
---
Hub-and-Spoke Topology
Centralized network architecture with shared services in hub and workloads in spokes.
Hub VNet Components
- Azure Firewall (centralized traffic filtering)
- VPN Gateway (hybrid connectivity)
- Azure Bastion (secure VM access)
- Private Endpoints (shared PaaS services)
- DNS forwarders
Spoke VNet Components
- Application workloads
- Environment isolation (dev, staging, prod)
- Team isolation
VNet Peering
- Low-latency, high-bandwidth connectivity
- No data egress charges between peered VNets in same region
- Hub-spoke peering: Enable "Allow Gateway Transit" in hub, "Use Remote Gateway" in spoke
---
Private Endpoints
Network interface that connects privately and securely to a service powered by Azure Private Link.
Supported Services
100+ Azure services support Private Endpoints including:
- Storage (Blob, Files, Queue, Table)
- Databases (SQL, Cosmos DB, PostgreSQL, MySQL)
- Azure OpenAI, Cognitive Services
- Key Vault, App Configuration
- Container Registry, Event Hub, Service Bus
Private DNS Zones
Required for automatic DNS resolution of privatelink FQDNs.
---
Network Security Groups
Stateful firewall rules for subnet and NIC level filtering.
Rule Priority
- Lower numbers = higher priority
- Default rules (65000-65500) allow VNet traffic, deny internet
- Custom rules (100-4096) take precedence
---
Load Balancing
Distribute network traffic across multiple backends for high availability and scalability.
Service Comparison
| Service | Layer | Scope | Use Case |
|---|---|---|---|
| Azure Front Door | L7 (HTTP/S) | Global | Global routing, WAF |
| Application Gateway | L7 (HTTP/S) | Regional | Regional load balancing, WAF |
| Load Balancer | L4 (TCP/UDP) | Regional | Non-HTTP traffic |
| Traffic Manager | DNS | Global | DNS-based routing |
---
DNS Configuration
Azure Private DNS Zones
Link private DNS zones to VNets for automatic resolution of Private Endpoints.
DNS Forwarding
Conditional forwarders for hybrid DNS resolution (on-premises ↔ Azure).
Azure Security Architecture Reference
Reference security patterns and best practices.
Table of Contents
1. Defense-in-Depth 2. Zero Trust Architecture 3. Microsoft Defender for Cloud
---
Defense-in-Depth
Multi-layered security approach protecting data and resources at every level.
Security Layers
1. Physical: Azure datacenter security 2. Identity: Entra ID, MFA, Conditional Access 3. Perimeter: Azure Firewall, DDoS Protection 4. Network: NSGs, Private Endpoints, WAF 5. Compute: Disk encryption, secure boot 6. Application: Code scanning, secrets management 7. Data: Encryption at rest, TLS 1.2+
---
Zero Trust Architecture
"Never trust, always verify"
Principles
- Verify explicitly (MFA, Conditional Access)
- Use least privilege (RBAC)
- Assume breach (segmentation, monitoring)
---
Microsoft Defender for Cloud
Unified security management and threat protection.
Key Features
- Security posture management (Secure Score)
- Vulnerability assessment
- Just-In-Time VM access
- Adaptive application controls
- File integrity monitoring
- Threat detection and alerts
Azure Storage Patterns Reference
Comprehensive guide to Azure storage services, tier selection, and lifecycle management.
Table of Contents
1. Blob Storage 2. Azure Files 3. Managed Disks 4. Data Lake Storage Gen2
---
Blob Storage
Azure Blob Storage provides scalable object storage for unstructured data with multiple access tiers.
Storage Redundancy Options
| Type | Copies | Scope | Use Case | Cost Multiplier |
|---|---|---|---|---|
| LRS | 3 | Single datacenter | Dev/test, non-critical | 1x |
| ZRS | 3 | 3 availability zones | Production, zone failures | 1.25x |
| GRS | 6 | 2 regions (async) | Disaster recovery | 2x |
| GZRS | 6 | Zones + regions | Mission-critical | 2.5x |
---
Azure Files
Managed file shares with SMB and NFS protocols.
Service Tiers
| Tier | Performance | Use Case | Cost/GB |
|---|---|---|---|
| Transaction Optimized | Standard | General purpose | Medium |
| Hot | Standard | Frequently accessed | Higher |
| Cool | Standard | Archival | Lower |
| Premium | SSD-backed | Low latency, high IOPS | Highest |
---
Managed Disks
Block storage for virtual machines.
Disk Types
| Type | Max IOPS | Max Throughput | Use Case |
|---|---|---|---|
| Standard HDD | 500 | 60 MB/s | Dev/test, infrequent access |
| Standard SSD | 6,000 | 750 MB/s | Web servers, light apps |
| Premium SSD | 20,000 | 900 MB/s | Production databases |
| Ultra Disk | 160,000 | 4,000 MB/s | SAP HANA, top-tier databases |
---
Data Lake Storage Gen2
Hierarchical namespace for big data analytics built on Blob Storage.
When to Use:
- Big data analytics (Spark, Databricks)
- Data warehousing pipelines
- Machine learning feature stores
- Requires POSIX-compliant file system operations
Azure Well-Architected Framework Implementation
Implementation guide for the five pillars of Azure Well-Architected Framework.
Table of Contents
1. Cost Optimization 2. Operational Excellence 3. Performance Efficiency 4. Reliability 5. Security
---
Cost Optimization
Maximize value delivered within budget constraints
Reserved Instances Strategy
Workload Analysis
↓
Steady-state (24/7, 1-3 years)? → Reserved Instances (40-60% savings)
↓
Variable traffic? → Consumption pricing (Functions, Container Apps)
↓
Fault-tolerant batch? → Spot VMs (up to 90% savings)Implementation Patterns
1. Storage Lifecycle Management
resource lifecyclePolicy 'Microsoft.Storage/storageAccounts/managementPolicies@2023-01-01' = {
parent: storageAccount
name: 'default'
properties: {
policy: {
rules: [
{
name: 'move-to-lower-tiers'
enabled: true
type: 'Lifecycle'
definition: {
filters: {
blobTypes: ['blockBlob']
prefixMatch: ['logs/']
}
actions: {
baseBlob: {
tierToCool: {
daysAfterModificationGreaterThan: 30
}
tierToCold: {
daysAfterModificationGreaterThan: 90
}
tierToArchive: {
daysAfterModificationGreaterThan: 365
}
delete: {
daysAfterModificationGreaterThan: 2555 // 7 years
}
}
}
}
}
]
}
}
}Savings: Hot ($0.018/GB) → Cool ($0.010/GB) → Archive ($0.00099/GB) = 94% reduction
2. Auto-Shutdown for Dev/Test Resources
resource vmAutoshutdown 'Microsoft.DevTestLab/schedules@2018-09-15' = {
name: 'shutdown-computevm-${vm.name}'
location: location
properties: {
status: 'Enabled'
taskType: 'ComputeVmShutdownTask'
dailyRecurrence: {
time: '1900' // 7 PM
}
timeZoneId: 'Eastern Standard Time'
notificationSettings: {
status: 'Enabled'
timeInMinutes: 30
emailRecipient: 'devteam@example.com'
}
targetResourceId: vm.id
}
}Savings: ~65% for dev/test resources (off 18 hours/day + weekends)
3. Cost Budgets and Alerts
resource budget 'Microsoft.Consumption/budgets@2023-11-01' = {
name: 'monthly-budget'
properties: {
category: 'Cost'
amount: 10000 // $10,000 per month
timeGrain: 'Monthly'
timePeriod: {
startDate: '2025-01-01'
}
notifications: {
warning80: {
enabled: true
operator: 'GreaterThan'
threshold: 80
contactEmails: [
'finance@example.com'
'engineering@example.com'
]
}
critical100: {
enabled: true
operator: 'GreaterThan'
threshold: 100
contactEmails: [
'finance@example.com'
]
}
}
}
}Cost Optimization Checklist
- [ ] Tag all resources (Environment, Owner, CostCenter)
- [ ] Purchase Reserved Instances for predictable workloads
- [ ] Enable auto-scaling (scale down during off-hours)
- [ ] Use Spot VMs for fault-tolerant batch jobs
- [ ] Implement storage lifecycle policies
- [ ] Right-size VMs (review Azure Advisor recommendations)
- [ ] Delete unused resources (unattached disks, orphaned IPs)
- [ ] Set budgets and cost alerts
- [ ] Review monthly cost reports
---
Operational Excellence
Run reliable, manageable systems at scale
Azure Policy for Governance
Common Policy Patterns:
// Require tags on all resources
resource requireTagsPolicy 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
name: 'require-tags-policy'
properties: {
policyType: 'Custom'
mode: 'Indexed'
displayName: 'Require tags: Environment, Owner, CostCenter'
policyRule: {
if: {
anyOf: [
{ field: 'tags.Environment', exists: false }
{ field: 'tags.Owner', exists: false }
{ field: 'tags.CostCenter', exists: false }
]
}
then: {
effect: 'deny'
}
}
}
}
// Enforce allowed Azure regions
resource allowedLocationsPolicy 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
name: 'allowed-locations-policy'
properties: {
policyType: 'Custom'
mode: 'Indexed'
displayName: 'Allowed Azure regions'
policyRule: {
if: {
not: {
field: 'location'
in: ['eastus', 'eastus2', 'westus2', 'centralus']
}
}
then: {
effect: 'deny'
}
}
}
}
// Enforce TLS 1.2 minimum
resource enforceTlsPolicy 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
name: 'enforce-tls-policy'
properties: {
policyType: 'Custom'
mode: 'All'
displayName: 'Enforce TLS 1.2 minimum for storage accounts'
policyRule: {
if: {
allOf: [
{ field: 'type', equals: 'Microsoft.Storage/storageAccounts' }
{
field: 'Microsoft.Storage/storageAccounts/minimumTlsVersion'
notEquals: 'TLS1_2'
}
]
}
then: {
effect: 'deny'
}
}
}
}Azure Blueprints for Repeatable Environments
Blueprint Components:
- Resource Groups
- Policy Assignments
- Role Assignments
- ARM Templates (Bicep)
Use Case: Deploy compliant production environments in minutes
Infrastructure as Code Best Practices
Bicep Organization:
infrastructure/
├── main.bicep # Entry point
├── parameters/
│ ├── dev.json
│ ├── staging.json
│ └── production.json
├── modules/
│ ├── networking.bicep # VNets, NSGs, Private Endpoints
│ ├── compute.bicep # Container Apps, AKS, VMs
│ ├── data.bicep # Databases, storage
│ └── monitoring.bicep # Log Analytics, App Insights
└── policies/
└── governance.bicep # Azure Policy definitionsDeployment:
az deployment sub create \
--location eastus \
--template-file main.bicep \
--parameters parameters/production.json---
Performance Efficiency
Scale to meet demand efficiently
Autoscaling Patterns
Container Apps Multi-Rule Scaling:
scale: {
minReplicas: 2
maxReplicas: 50
rules: [
// HTTP concurrency
{
name: 'http-rule'
http: {
metadata: {
concurrentRequests: '100'
}
}
}
// Queue depth
{
name: 'queue-rule'
custom: {
type: 'azure-servicebus'
metadata: {
queueName: 'orders'
messageCount: '10'
}
}
}
// Business hours boost
{
name: 'business-hours'
custom: {
type: 'cron'
metadata: {
timezone: 'America/New_York'
start: '0 8 * * MON-FRI'
end: '0 18 * * MON-FRI'
desiredReplicas: '20'
}
}
}
]
}Caching Strategy
Azure Cache for Redis:
resource redis 'Microsoft.Cache/redis@2023-08-01' = {
name: 'mycache'
location: location
properties: {
sku: {
name: 'Premium' // Basic, Standard, Premium
family: 'P'
capacity: 1
}
enableNonSslPort: false
minimumTlsVersion: '1.2'
redisConfiguration: {
'maxmemory-policy': 'allkeys-lru'
}
publicNetworkAccess: 'Disabled' // Use Private Endpoint
}
}Cache Patterns:
- Cache-Aside: Application manages cache (most common)
- Read-Through: Cache fetches from database automatically
- Write-Behind: Cache writes to database asynchronously
CDN for Static Content
resource cdn 'Microsoft.Cdn/profiles@2023-05-01' = {
name: 'mycdn'
location: 'global'
sku: {
name: 'Standard_Microsoft' // or Premium_Verizon, Premium_Akamai
}
}
resource endpoint 'Microsoft.Cdn/profiles/endpoints@2023-05-01' = {
parent: cdn
name: 'static-assets'
location: 'global'
properties: {
originHostHeader: 'mystorageaccount.blob.core.windows.net'
isHttpAllowed: false
isHttpsAllowed: true
origins: [
{
name: 'storage-origin'
properties: {
hostName: 'mystorageaccount.blob.core.windows.net'
}
}
]
}
}---
Reliability
Recover from failures and meet availability commitments
Availability Zones
Zone-Redundant Deployment:
// VM Scale Set across 3 zones
resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2023-09-01' = {
name: 'app-vmss'
location: location
zones: ['1', '2', '3']
sku: {
name: 'Standard_D4s_v5'
capacity: 6 // 2 per zone
}
properties: {
zoneBalance: true
platformFaultDomainCount: 1
singlePlacementGroup: false
}
}
// Zone-redundant storage
resource storage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: 'mystorageaccount'
location: location
sku: {
name: 'Standard_ZRS' // Zone-Redundant Storage
}
kind: 'StorageV2'
}Availability SLAs:
- Single VM (Premium SSD): 99.9%
- Availability Set: 99.95%
- Availability Zones: 99.99%
Multi-Region Architecture
Traffic Manager for Global Routing:
resource trafficManager 'Microsoft.Network/trafficmanagerprofiles@2022-04-01' = {
name: 'myapp-traffic-manager'
location: 'global'
properties: {
profileStatus: 'Enabled'
trafficRoutingMethod: 'Performance' // or Priority, Weighted, Geographic
dnsConfig: {
relativeName: 'myapp'
ttl: 60
}
monitorConfig: {
protocol: 'HTTPS'
port: 443
path: '/health'
intervalInSeconds: 30
toleratedNumberOfFailures: 3
timeoutInSeconds: 10
}
endpoints: [
{
name: 'eastus-endpoint'
type: 'Microsoft.Network/trafficManagerProfiles/azureEndpoints'
properties: {
targetResourceId: webAppEastUs.id
endpointStatus: 'Enabled'
weight: 100
priority: 1
}
}
{
name: 'westeurope-endpoint'
type: 'Microsoft.Network/trafficManagerProfiles/azureEndpoints'
properties: {
targetResourceId: webAppWestEurope.id
endpointStatus: 'Enabled'
weight: 100
priority: 2
}
}
]
}
}Backup and Disaster Recovery
Azure Backup for VMs:
resource recoveryVault 'Microsoft.RecoveryServices/vaults@2023-01-01' = {
name: 'backup-vault'
location: location
sku: {
name: 'RS0'
tier: 'Standard'
}
properties: {}
}
resource backupPolicy 'Microsoft.RecoveryServices/vaults/backupPolicies@2023-01-01' = {
parent: recoveryVault
name: 'daily-backup'
properties: {
backupManagementType: 'AzureIaasVM'
schedulePolicy: {
schedulePolicyType: 'SimpleSchedulePolicy'
scheduleRunFrequency: 'Daily'
scheduleRunTimes: ['2025-01-01T02:00:00Z']
}
retentionPolicy: {
retentionPolicyType: 'LongTermRetentionPolicy'
dailySchedule: {
retentionTimes: ['2025-01-01T02:00:00Z']
retentionDuration: {
count: 30
durationType: 'Days'
}
}
}
}
}RPO/RTO Targets:
- RPO (Recovery Point Objective): How much data loss acceptable (e.g., 1 hour)
- RTO (Recovery Time Objective): How long to restore (e.g., 4 hours)
---
Security
Protect data, systems, and assets
Managed Identity Pattern
System-Assigned Identity:
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
name: 'api-service'
identity: {
type: 'SystemAssigned'
}
// ...
}
// Grant access to Key Vault
resource keyVaultAccessPolicy 'Microsoft.KeyVault/vaults/accessPolicies@2023-02-01' = {
parent: keyVault
name: 'add'
properties: {
accessPolicies: [
{
tenantId: subscription().tenantId
objectId: containerApp.identity.principalId
permissions: {
secrets: ['get', 'list']
}
}
]
}
}Private Endpoints
Isolate PaaS Services in VNet:
// Storage Account with Private Endpoint
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: 'mystorageaccount'
location: location
sku: {
name: 'Standard_LRS'
}
properties: {
publicNetworkAccess: 'Disabled'
allowBlobPublicAccess: false
minimumTlsVersion: 'TLS1_2'
}
}
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-05-01' = {
name: 'storage-pe'
location: location
properties: {
subnet: {
id: subnet.id
}
privateLinkServiceConnections: [
{
name: 'storage-connection'
properties: {
privateLinkServiceId: storageAccount.id
groupIds: ['blob']
}
}
]
}
}
// Private DNS Zone
resource privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = {
name: 'privatelink.blob.core.windows.net'
location: 'global'
}
resource dnsZoneLink 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = {
parent: privateDnsZone
name: 'vnet-link'
location: 'global'
properties: {
virtualNetwork: {
id: vnet.id
}
registrationEnabled: false
}
}Microsoft Defender for Cloud
Enable for All Resource Types:
resource defenderPlan 'Microsoft.Security/pricings@2023-01-01' = {
name: 'VirtualMachines'
properties: {
pricingTier: 'Standard'
}
}
resource defenderContainers 'Microsoft.Security/pricings@2023-01-01' = {
name: 'Containers'
properties: {
pricingTier: 'Standard'
}
}
resource defenderDatabases 'Microsoft.Security/pricings@2023-01-01' = {
name: 'SqlServers'
properties: {
pricingTier: 'Standard'
}
}Features:
- Vulnerability scanning
- Just-In-Time VM access
- Adaptive application controls
- Security alerts and recommendations
Network Security Groups
Micro-Segmentation:
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-05-01' = {
name: 'app-subnet-nsg'
location: location
properties: {
securityRules: [
{
name: 'allow-https'
properties: {
priority: 100
direction: 'Inbound'
access: 'Allow'
protocol: 'Tcp'
sourceAddressPrefix: '*'
sourcePortRange: '*'
destinationAddressPrefix: '*'
destinationPortRange: '443'
}
}
{
name: 'deny-all-inbound'
properties: {
priority: 4096
direction: 'Inbound'
access: 'Deny'
protocol: '*'
sourceAddressPrefix: '*'
sourcePortRange: '*'
destinationAddressPrefix: '*'
destinationPortRange: '*'
}
}
]
}
}---
Pillar Implementation Checklist
Cost Optimization
- [ ] Tag all resources
- [ ] Purchase Reserved Instances
- [ ] Implement lifecycle policies
- [ ] Set budgets and alerts
- [ ] Right-size resources
Operational Excellence
- [ ] Deploy Azure Policy
- [ ] Use Infrastructure as Code
- [ ] Implement CI/CD
- [ ] Enable diagnostics logging
- [ ] Document runbooks
Performance Efficiency
- [ ] Configure autoscaling
- [ ] Implement caching
- [ ] Use CDN for static content
- [ ] Monitor performance metrics
- [ ] Conduct load testing
Reliability
- [ ] Deploy across Availability Zones
- [ ] Implement health checks
- [ ] Configure backup policies
- [ ] Test disaster recovery
- [ ] Define SLAs
Security
- [ ] Enable Managed Identity
- [ ] Use Private Endpoints
- [ ] Enable Microsoft Defender
- [ ] Implement RBAC
- [ ] Encrypt data at rest and in transit
---
Use Azure Advisor for personalized recommendations across all five pillars.
Related skills
FAQ
What does it recommend for most containerized workloads?
Azure Container Apps, which the docs say is simpler and cheaper than AKS for 80% of containerized workloads.
Which framework does it follow?
The Azure Well-Architected Framework's five pillars: cost optimization, operational excellence, performance efficiency, reliability, and security.