Design an Application Architecture — Lesson
AZ-305 › Unit 4 › Design an application architecture
Design an Application Architecture — Lesson
Modern cloud applications are rarely monolithic. They are composed of loosely coupled services that communicate through messages, events, APIs, and caches — each layer designed to scale, fail, and recover independently. This lesson integrates the six learning objectives that make up the Application Architecture topic: messaging architecture, event-driven design, API integration, caching, application configuration, and automated deployment. Together they form the blueprint an Azure solution architect uses to design resilient, performant, and operationally excellent applications. Reference: Ch. 4, §4.2, p. 148–158 of the AZ-305 exam book.
Why This Matters
The AZ-305 exam dedicates a significant portion of its question pool to application architecture — and for good reason. Every production workload on Azure eventually needs to decouple components, manage traffic spikes, cache hot data, secure configuration secrets, and ship updates without downtime. Employers expect Azure architects to recommend whether a scenario calls for Azure Service Bus or Event Grid, to know when Azure Managed Redis pays for itself, and to design deployment pipelines that enforce infrastructure-as-code. Mastering this topic is the difference between designing systems that survive Black Friday and systems that page you at 3 AM.
Prerequisites
- Azure compute fundamentals (App Service, Functions, AKS) — Can you explain when to choose a serverless function over a container-based microservice?
- Networking basics (VNets, Private Endpoints, DNS) — How would you restrict an API Management gateway to accept traffic only from your front-end VNet?
- Identity and access management (Entra ID, managed identities) — What is a managed identity and why does it eliminate the need to store credentials in code?
- Azure Resource Manager and Bicep basics — Can you describe what a Bicep module does and how parameters flow into it?
- Git fundamentals (branches, pull requests) — Have you merged a feature branch via a pull request in GitHub or Azure Repos?
Learning Objectives
- Design a messaging architecture that selects between
Azure Service BusandAzure Storage Queuesbased on ordering, size, and transactional requirements. - Evaluate event-driven patterns using
Azure Event GridandAzure Event Hubs, justifying each by throughput, delivery guarantees, and subscriber model. - Recommend an API integration strategy using
Azure API Management, including policies for throttling, transformation, and versioning. - Design a caching solution with
Azure Managed Redisthat addresses session state, data caching, and cache-aside patterns. - Architect a configuration and secrets management approach using
Azure App ConfigurationandAzure Key Vaultwith feature flags and dynamic refresh. - Design an automated deployment pipeline using
GitHub ActionsorAzure Pipelineswith Bicep templates, environment promotion, and rollback strategy.
Building Blocks
Azure Service Bus — Think of it as a "post office with guaranteed delivery." Service Bus is a fully managed enterprise message broker supporting queues (point-to-point) and topics (publish-subscribe). Messages are stored durably and delivered in order (FIFO with sessions), with support for transactions, dead-lettering, and duplicate detection. It matters because decoupling producers from consumers is the first step toward a resilient distributed system.
Azure Storage Queue — Think of it as a "simple drop box." Storage Queues provide basic, high-volume message queuing at very low cost. Messages can be up to 64 KB (or 256 KB with the newer API), and there is no ordering guarantee. It matters because many workloads need only simple, cheap decoupling — not the full feature set of Service Bus.
Azure Event Grid — Think of it as a "reactive switchboard." Event Grid routes discrete events (resource created, blob uploaded, custom app events) from publishers to subscribers with push-based, near-real-time delivery. It uses a topic-subscription model with filtering and supports at-least-once delivery. It matters because it lets you build reactive architectures where services respond to state changes without polling.
Azure Event Hubs — Think of it as a "high-speed conveyor belt." Event Hubs is a big-data streaming platform that ingests millions of events per second. Consumers read from partitions at their own pace using consumer groups. It matters because telemetry, IoT, and clickstream workloads generate volumes that neither Service Bus nor Event Grid is designed for.
Azure API Management (APIM) — Think of it as a "front door for your APIs." APIM provides a unified gateway that sits in front of your backend APIs, enforcing authentication, rate limiting, transformation, caching, and versioning. It matters because exposing raw backend APIs to consumers without governance leads to security holes, inconsistent contracts, and uncontrolled costs.
Azure Managed Redis — Think of it as a "speed-dial for hot data." Redis is an in-memory data store that serves cached responses in sub-millisecond latency. Azure manages the cluster, replication, and failover. It matters because databases buckle under repeated reads for the same data — caching absorbs that pressure and cuts response times by to .
Azure App Configuration — Think of it as a "centralised settings panel." App Configuration stores key-value pairs and feature flags in a single service, separate from code. Applications pull configuration at startup or subscribe to change notifications. It matters because scattering settings across appsettings.json files, environment variables, and Key Vault secrets makes configuration drift inevitable.
Azure Key Vault — Think of it as a "digital safe." Key Vault stores secrets (connection strings, API keys), certificates, and cryptographic keys in FIPS 140-2 validated hardware. Applications access secrets via managed identities — no credentials in code. It matters because a leaked secret in a Git repo is the most common attack vector for cloud breaches.
Bicep — Think of it as a "readable ARM template." Bicep is a domain-specific language that compiles to ARM JSON. It supports modules, parameters, loops, and conditions. It matters because infrastructure-as-code is the foundation of repeatable, auditable deployments — and Bicep is Azure's first-party IaC language.
GitHub Actions / Azure Pipelines — Think of them as "automated assembly lines." Both are CI/CD platforms that trigger on code pushes, run builds and tests, and deploy artifacts to Azure. GitHub Actions uses YAML workflow files in the repo; Azure Pipelines offers YAML and classic UI pipelines. They matter because manual deployments are error-prone, slow, and unauditable.
Deep Dive
LO34 — Designing a Messaging Architecture
Messaging decouples producers and consumers so that spikes in one service don't cascade into failures in another. The AZ-305 exam tests your ability to choose between Azure Service Bus and Azure Storage Queues.
Service Bus Queues vs. Storage Queues
| Feature | Service Bus Queue | Storage Queue |
|---|---|---|
| Max message size | 256 KB (Standard) / 100 MB (Premium) | 64 KB |
| Ordering guarantee | FIFO via sessions | None |
| Duplicate detection | Built-in (message ID window) | Manual (app-level) |
| Transactions | Yes (send + complete in one TX) | No |
| Dead-letter queue | Yes | No |
| Throughput | Thousands/sec per queue | Thousands/sec (scales with storage account) |
| Cost | Higher (per-message + base unit) | Very low (per-operation on storage) |
| Protocol | AMQP, HTTP | HTTP only |
When to choose Service Bus: you need FIFO ordering, transactions spanning send-and-complete, messages larger than 64 KB, dead-letter handling, or publish-subscribe via topics.
When to choose Storage Queues: you need simple, cheap, high-volume decoupling and can tolerate at-least-once, unordered delivery.
Service Bus Topics extend queues with a publish-subscribe pattern. A single message published to a topic can be delivered to multiple subscriptions, each with its own filter. This is ideal for fan-out: an order-placed message triggers billing, inventory, and notification subscribers simultaneously.
# Bicep snippet — Service Bus namespace + queue + topic
resource sbNamespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' = {
name: 'sb-orders-prod'
location: location
sku: { name: 'Standard', tier: 'Standard' }
}
resource queue 'Microsoft.ServiceBus/namespaces/queues@2022-10-01-preview' = {
parent: sbNamespace
name: 'processing-queue'
properties: {
maxDeliveryCount: 10
deadLetteringOnMessageExpiration: true
requiresSession: true // enables FIFO
}
}[!TIP] Enable
requiresSession: trueon a Service Bus queue only when you need strict per-session FIFO ordering. Sessions add overhead — if your workload is embarrassingly parallel (e.g., independent image-resize jobs), skip sessions and let consumers scale freely.
See the LO-level lesson for more on Service Bus Premium tier, auto-forwarding, and message batching.
LO35 — Designing an Event-Driven Architecture
Events differ from messages: a message carries a command or payload that the receiver must act on; an event is a notification that something happened — subscribers decide whether and how to react.
Event Grid vs. Event Hubs
| Feature | Event Grid | Event Hubs |
|---|---|---|
| Model | Push (webhook / subscriber) | Pull (consumer reads from partition) |
| Latency | Sub-second | Sub-second (but consumer-paced) |
| Throughput | Millions of events/sec | Millions of events/sec |
| Delivery | At-least-once (retry + dead-letter) | At-least-once (checkpoint-based) |
| Ordering | Per-topic (not guaranteed) | Per-partition (FIFO) |
| Retention | 24 hours (default) | 1–90 days (configurable) |
| Best for | Discrete state-change reactions | High-volume streaming / telemetry |
Event Grid patterns: blob-created triggers an Azure Function that generates thumbnails; resource-health event triggers a Logic App that pages on-call; custom domain event (order-shipped) triggers multiple subscribers.
Event Hubs patterns: IoT devices stream telemetry at 1M events/sec; clickstream data feeds a Spark analytics pipeline; application logs aggregate for Kusto ingestion.
// Event Grid subscription — filter on blob .csv uploads
{
"properties": {
"destination": {
"endpointType": "AzureFunction",
"properties": {
"resourceId": "/subscriptions/.../functions/ProcessCsv"
}
},
"filter": {
"subjectBeginsWith": "/blobServices/default/containers/uploads",
"subjectEndsWith": ".csv"
}
}
}[!WARNING] Event Grid retries delivery for up to 24 hours. If your subscriber endpoint is down longer than that, events are dead-lettered (if configured) or dropped. Always configure a dead-letter storage container to avoid silent data loss.
See the LO-level lesson for more on Event Grid custom topics, Event Hubs partitioning strategies, and Capture to ADLS.
LO36 — Designing an API Integration Strategy
Azure API Management is the gateway that unifies your API surface. It sits between consumers (mobile apps, SPAs, partners) and backends (App Service, Functions, AKS, Logic Apps).
APIM Tiers
| Tier | Use Case | SLA | VNet Integration | Price Range |
|---|---|---|---|---|
| Consumption | Serverless, low-volume | 99.95% | No | Pay-per-call |
| Developer | Dev/test | None | No | ~/mo |
| Basic | Small production | 99.95% | No | ~/mo |
| Standard | Medium production | 99.95% | External only | ~/mo |
| Premium | Enterprise, multi-region | 99.99% | Internal + external | ~/mo/unit |
Key policies architects must know:
rate-limit-by-key: Throttle by subscription key or IP — prevents one consumer from monopolising capacity.set-backend-service: Route to different backends by path or header — enables blue-green deployments.rewrite-uri: Transform the external URL to a different internal path.cache-lookup/cache-store: Cache GET responses in APIM's built-in cache or an external Redis.validate-jwt: Verify Entra ID tokens at the gateway — backend never sees unauthenticated traffic.
<!-- APIM policy: rate-limit + JWT validation -->
<inbound>
<rate-limit-by-key calls="100" renewal-period="60"
counter-key="@(context.Subscription.Id)" />
<validate-jwt header-name="Authorization"
failed-validation-httpcode="401">
<openid-config url="https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration" />
<required-claims>
<claim name="aud" match="all">
<value>{api-app-id}</value>
</claim>
</required-claims>
</validate-jwt>
</inbound>[!IMPORTANT] The Consumption tier has no built-in cache and cold-start latency of 1–3 seconds. For latency-sensitive production APIs, choose at least Basic. For internal VNet-only APIs, you need Premium (or Standard v2 in preview).
See the LO-level lesson for more on API versioning strategies, synthetic GraphQL, and self-hosted gateways.
LO37 — Designing a Caching Solution
Azure Managed Redis is the go-to caching layer. It absorbs repetitive reads, stores session state, and powers leaderboards and pub/sub channels.
Cache-Aside Pattern
- Application checks Redis for the key.
- Cache hit → return data (sub-millisecond).
- Cache miss → query the database, write to Redis with a TTL, return data.
This is the most common pattern on the exam. The critical design decision is the TTL (time-to-live): too short and you get excessive cache misses; too long and you serve stale data.
Redis Tiers
| Tier | Replication | Persistence | Max Size | Use Case |
|---|---|---|---|---|
| Basic | None | None | 53 GB | Dev/test |
| Standard | Primary + replica | None | 53 GB | Production (HA) |
| Premium | Primary + replica(s) | AOF / RDB | 120 GB | High perf, VNet, clustering |
| Enterprise | Active-active geo | Full | 100+ GB | Global distribution |
# Create a Premium Redis cache with clustering
az redis create \
--name cache-orders-prod \
--resource-group rg-app \
--location eastus \
--sku Premium \
--vm-size P1 \
--shard-count 3 \
--enable-non-ssl-port false[!TIP] For session state in a multi-instance
App Service, use Redis instead of in-memory sessions. In-memory sessions break when the load balancer routes a user to a different instance. Redis centralises state and survives instance restarts.
See the LO-level lesson for more on Redis data structures, eviction policies, and geo-replication.
LO38 — Designing Application Configuration Management
Azure App Configuration and Azure Key Vault work as a pair: App Configuration stores non-secret settings and feature flags; Key Vault stores secrets, certificates, and keys.
Why separate them? Access patterns differ. App Configuration supports rapid reads with low latency and change notifications — perfect for feature flags checked on every request. Key Vault is optimised for security: access is logged, secrets are encrypted at rest with HSM-backed keys, and access policies are granular.
Feature Flags
App Configuration provides built-in feature-flag support:
// Feature flag stored in App Configuration
{
"id": "Beta-Dashboard",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.Targeting",
"parameters": {
"Audience": {
"Groups": [{ "Name": "BetaTesters", "RolloutPercentage": 100 }],
"DefaultRolloutPercentage": 10
}
}
}
]
}
}Key Vault References
App Configuration can store Key Vault references — a pointer to a secret in Key Vault. The application reads the setting from App Configuration; the SDK transparently fetches the secret from Key Vault using a managed identity. This keeps secrets out of App Configuration while giving the app a single configuration endpoint.
// Key Vault with a secret + App Configuration reference
resource kv 'Microsoft.KeyVault/vaults@2023-07-01' = {
name: 'kv-app-prod'
location: location
properties: {
sku: { family: 'A', name: 'standard' }
tenantId: subscription().tenantId
enableRbacAuthorization: true
}
}
resource secret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = {
parent: kv
name: 'SqlConnectionString'
properties: { value: sqlConnString }
}[!NOTE] App Configuration supports dynamic refresh via a sentinel key. When the sentinel value changes, the SDK reloads all settings without restarting the application. This is critical for toggling feature flags in production — you change one key and every running instance picks it up within 30 seconds.
See the LO-level lesson for more on labelling strategies, configuration snapshots, and private endpoints for App Configuration.
LO39 — Designing Automated Deployment
Infrastructure-as-code (IaC) plus CI/CD pipelines turn manual, error-prone releases into repeatable, auditable deployments.
Bicep for IaC
Bicep is Azure's declarative IaC language. A typical pattern:
main.bicepdefines the deployment (parameters, modules).- Modules encapsulate resource groups (e.g.,
networking.bicep,compute.bicep,data.bicep). - Parameters file (
main.parameters.json) provides environment-specific values (dev, staging, prod). az deployment group createor a CI/CD pipeline deploys the template.
GitHub Actions Workflow
# .github/workflows/deploy.yml
name: Deploy Infrastructure
on:
push:
branches: [main]
paths: ['infra/**']
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write # OIDC for Azure login
contents: read
steps:
- uses: actions/checkout@v4
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- uses: azure/arm-deploy@v2
with:
resourceGroupName: rg-app-prod
template: infra/main.bicep
parameters: infra/main.parameters.prod.jsonDeployment Strategies
| Strategy | How it works | Rollback | Risk |
|---|---|---|---|
| Blue-green | Two identical environments; swap traffic | Instant (swap back) | Low |
| Canary | Route a small percentage of traffic to new version | Scale down canary | Low |
| Rolling | Update instances one at a time | Redeploy previous version | Medium |
| Big-bang | Replace all at once | Redeploy (slow) | High |
[!WARNING] Never deploy Bicep templates directly from a developer laptop to production. Always route through a CI/CD pipeline with code review, automated validation (
az bicep build --stdout | jq .), and environment-gated approvals. A single typo in a production deployment can delete resources.
See the LO-level lesson for more on Bicep modules, what-if analysis, and rollback patterns.
Worked Examples
Easy: Decouple an Order-Processing Pipeline
Problem: Contoso's monolithic web app calls an inventory API synchronously. During flash sales, the inventory API times out and the entire checkout fails. Design a decoupled architecture.
Solution:
- The web app publishes an
OrderPlacedmessage to anAzure Service Busqueue. - The inventory service consumes from the queue at its own pace.
- Enable
requiresSession: trueso orders for the same customer are processed in sequence. - Set
maxDeliveryCount: 5— after 5 failed attempts, the message moves to the dead-letter queue for manual review. - The web app returns a
202 Acceptedto the user immediately — no more synchronous timeouts.
[!NOTE] Key insight: Service Bus absorbs the traffic spike. The inventory API processes at a steady rate; the queue grows temporarily but drains within minutes. This pattern turns a synchronous bottleneck into an asynchronous buffer.
Medium: Design an Event-Driven Image Processing Pipeline
Problem: A media company uploads thousands of images per hour to Blob Storage. Each upload must trigger thumbnail generation, metadata extraction, and content moderation — three independent processes.
Solution:
- Configure an
Event Gridsystem topic on the storage account. - Create three Event Grid subscriptions, each with a filter for
Microsoft.Storage.BlobCreatedevents on theimages/container. - Subscription 1 → Azure Function (thumbnail generation).
- Subscription 2 → Azure Function (metadata extraction to Cosmos DB).
- Subscription 3 → Azure Function (calls Azure AI Content Safety API; if flagged, moves blob to quarantine container).
- Each subscriber is independent — failure in moderation doesn't block thumbnails.
- Dead-letter container catches events for any subscriber that fails after retries.
[!NOTE] Key insight: Event Grid's fan-out model means one blob upload triggers three independent workflows. If you used a Service Bus queue, you'd need a topic with three subscriptions — possible, but Event Grid is purpose-built for this reactive, push-based pattern and costs less ( per million events).
Hard: Design a Multi-Region API Platform with Caching and Configuration
Problem: Tailwind Traders operates in US East and West Europe. They need a globally distributed API gateway with sub-100 ms response times, centralised configuration, secret rotation, and zero-downtime deployments.
Solution:
- API Management Premium with two gateway units (East US + West Europe). Traffic Manager or Front Door routes users to the nearest gateway.
- Azure Managed Redis with active-active geo-replication across both regions. API backends check Redis first (cache-aside); cache hit returns in under 5 ms.
- App Configuration stores feature flags and non-secret settings. Both regions read from a single App Configuration instance (geo-replicated read replicas if needed). Dynamic refresh via sentinel key.
- Key Vault per region (secrets are region-local for compliance). APIM and backend services use managed identities — no secrets in config files.
- GitHub Actions pipeline: PR triggers
what-ifon staging; merge tomaindeploys to East US first (canary); after 30 minutes of healthy metrics, deploys to West Europe. - Rollback: revert the Git commit and re-run the pipeline — Bicep is declarative, so it converges to the previous state.
[!NOTE] Key insight: This example spans all six LOs — messaging (decoupled order flow behind the API), events (Event Grid for cache-invalidation), APIM (gateway), Redis (caching), App Configuration + Key Vault (config/secrets), and GitHub Actions (deployment). The AZ-305 exam rewards architectures that integrate multiple services coherently.
Visual Explanations
Application Architecture Overview
Messaging Decision Tree
Deployment Pipeline Flow
Cache-Aside Pattern Flow
TikZ: Multi-Region Application Topology
Service Comparison: Messaging and Eventing
| Feature | Service Bus | Storage Queue | Event Grid | Event Hubs |
|---|---|---|---|---|
| Pattern | Command / message | Simple queue | Reactive event | Streaming |
| Max message size | 256 KB–100 MB | 64 KB | 1 MB | 1 MB (Standard) |
| Ordering | FIFO (sessions) | None | Per-topic (no) | Per-partition |
| Delivery | At-least-once / at-most-once | At-least-once | At-least-once | At-least-once |
| Dead-letter | Yes | No | Yes | No (consumer manages) |
| Throughput | Thousands/sec | Thousands/sec | Millions/sec | Millions/sec |
| Cost model | Per-message + base | Per-operation | Per-event | Per-throughput unit |
APIM Policy Pipeline
| Pipeline Stage | Example Policy | Purpose |
|---|---|---|
| Inbound | validate-jwt | Authenticate caller |
| Inbound | rate-limit-by-key | Protect backend from overload |
| Inbound | rewrite-uri | Map external path to internal |
| Backend | set-backend-service | Route to blue or green backend |
| Outbound | cache-store | Cache successful responses |
| On-error | return-response | Return friendly error JSON |
Common Mistakes
❌ Myth: "Event Grid and Event Hubs are interchangeable — pick whichever is cheaper." ✅ Reality: Event Grid is a push-based reactive routing service for discrete events (blob created, resource changed). Event Hubs is a pull-based streaming platform for high-volume telemetry. Using Event Grid for 1M sensor readings/sec will fail — it's not a stream processor. Using Event Hubs for a blob-created trigger adds unnecessary complexity — Event Grid handles it natively. Why it's tricky: Both have "Event" in the name and both handle millions of events per second. The distinction is push-vs-pull delivery model and the nature of the data: discrete notifications (Grid) vs. continuous streams (Hubs).
❌ Myth: "Azure Managed Redis development configuration without high availability is fine for production — it's cheaper." ✅ Reality: Basic tier has no replication and no SLA. A node failure means total cache loss and a cold-start thundering herd against your database. Standard tier adds a replica for 99.9% SLA; Premium adds persistence, VNet isolation, and clustering. Production workloads need at least Standard. Why it's tricky: Basic tier works perfectly in dev/test, so teams promote it to production without realising the SLA gap. The failure mode is silent — everything works until the single node restarts.
❌ Myth: "Store all secrets and settings in Azure Key Vault — it's the most secure option." ✅ Reality: Key Vault has throttling limits ($4,000 transactions per 10 seconds per vault in Standard tier). If your application reads 50 feature flags on every HTTP request across 100 instances, you'll hit throttling instantly. Use App Configuration for high-read settings and feature flags; use Key Vault references for actual secrets. Why it's tricky: Key Vault is indeed the correct place for secrets, but it's not a general-purpose configuration store. The throttling error (
429 Too Many Requests) only appears under production load, never in dev testing.
❌ Myth: "We can deploy Bicep templates manually from our laptops — CI/CD is overkill for infrastructure." ✅ Reality: Manual deployments bypass code review, have no audit trail, and risk deploying to the wrong subscription. A mistyped parameter can delete a production database. CI/CD with
what-ifpreview, approval gates, and automatic rollback is the minimum standard for production infrastructure. Why it's tricky: Manual deployments feel faster during initial development. The risk only materialises months later when someone runsaz deployment group createagainst prod instead of dev.
Practice Exercises
Exercise 1: Choose the Right Queue 🟢 Easy
A startup processes user-uploaded videos. Each upload triggers a transcode job. Jobs are independent and order doesn't matter. The team expects $50,000 uploads/day and wants the cheapest solution. Which queue service should they use?
▶💡 Hint
Consider message size (just a reference to the blob, not the video itself), ordering requirements, and cost.
▶✅ Solution
Use Azure Storage Queue. The message payload is a blob URI (well under 64 KB). No ordering or transactions are needed. Storage Queues cost a fraction of Service Bus. At $50,000 messages/day, the monthly cost is under .
Exercise 2: Event Grid vs. Event Hubs 🟢 Easy
A logistics company wants to trigger an Azure Function every time a GPS device uploads a new location to Blob Storage. Which eventing service fits?
▶💡 Hint
Is this a discrete event (something happened) or a continuous stream (data flowing constantly)?
▶✅ Solution
Use Azure Event Grid with a BlobCreated system topic. Each blob upload is a discrete event that triggers the function. Event Hubs would work but adds unnecessary partition management for what is a simple reactive trigger.
Exercise 3: APIM Tier Selection 🟡 Medium
Contoso's API must be accessible only from within their corporate VNet. They need 99.99% SLA and expect $10,000 requests/sec. Which APIM tier and why?
▶💡 Hint
Which tier supports internal VNet integration? What SLA does it offer?
▶✅ Solution
Premium tier. It's the only tier that supports internal VNet integration (the gateway gets a private IP inside the VNet). It offers a 99.99% SLA with multi-region deployment. Standard supports external VNet only (public IP with VNet access restrictions), which doesn't meet the "only from within the VNet" requirement. Scale to 2+ units for $10,000 req/sec headroom.
Exercise 4: Cache Thundering Herd 🟡 Medium
After a Redis node restart, your e-commerce site experiences a spike in database queries. Response times jump from 50 ms to 3 seconds. What cache pattern prevents this?
▶💡 Hint
What happens when thousands of concurrent requests all miss the cache at the same time?
▶✅ Solution
Implement cache warming (pre-populate Redis with hot keys on startup) and staggered TTLs (add random jitter to expiry times so keys don't all expire simultaneously). Additionally, use Premium tier with persistence (AOF or RDB snapshots) so that on restart, Redis reloads from disk instead of starting empty. For critical keys, implement a lock-based cache-aside where only one thread queries the database on a miss while others wait for the cache to be populated.
Exercise 5: Feature Flag Rollout 🟡 Medium
You want to roll out a new checkout flow to 5% of users, then gradually increase to 100%. How do you implement this without redeploying code?
▶💡 Hint
Which service supports targeting filters with rollout percentages?
▶✅ Solution
Use Azure App Configuration feature flags with a targeting filter. Set DefaultRolloutPercentage to 5. Your application checks the flag on each request — the SDK handles consistent user bucketing (same user always sees the same experience). To increase rollout, update the percentage in App Configuration and change the sentinel key. All running instances pick up the change within 30 seconds via dynamic refresh. No code deployment needed.
Exercise 6: Multi-Service Architecture Design 🔴 Hard
A financial services firm needs an architecture where: (a) trading orders are processed exactly once in FIFO order, (b) market-data events stream at $500,000/sec, (c) a public API serves portfolio data with sub-100 ms latency, (d) configuration changes propagate without redeployment, and (e) all infrastructure is deployed via IaC. Design the architecture.
▶💡 Hint
Map each requirement to a specific service from this topic's six LOs.
▶✅ Solution
(a) Azure Service Bus Premium with sessions enabled for FIFO ordering and duplicate detection for exactly-once processing.
(b) Azure Event Hubs with 16+ partitions and 2+ throughput units for 500K events/sec market-data streaming.
(c) Azure API Management Standard/Premium fronting an App Service backend, with Azure Managed Redis serving portfolio data (cache-aside, sub-10 ms reads).
(d) Azure App Configuration for feature flags and non-secret settings with dynamic refresh via sentinel key; Azure Key Vault for connection strings and API keys, referenced from App Configuration.
(e) GitHub Actions with Bicep modules: networking.bicep, messaging.bicep, compute.bicep, data.bicep. PR triggers what-if; merge deploys to staging; manual approval gates production.
Exercise 7: Deployment Rollback Scenario 🔴 Hard
Your team deployed a Bicep update that accidentally changed the Redis SKU from Premium to Basic, dropping persistence and VNet integration. Production cache is now unprotected. What is the fastest rollback path?
▶💡 Hint
Bicep is declarative. What happens if you redeploy the previous version of the template?
▶✅ Solution
- Revert the Git commit (or cherry-pick the previous known-good Bicep).
- Re-run the CI/CD pipeline — Bicep is declarative, so deploying the old template with
sku: Premiumwill attempt to upgrade the Redis instance back. - Critical caveat: downgrading from Basic back to Premium may not be supported in-place for Redis. If the deployment fails, you must create a new Premium Redis cache and restore from the last RDB backup (if one existed before the SKU change).
- Prevention: add a CI step that runs
az deployment group what-ifand flags any SKU downgrade as a blocking change. Require manual approval for any change that modifies theskuproperty of a cache or database resource.
Summary & Concept Map
- Messaging decouples components: use
Service Busfor ordered, transactional messages andStorage Queuesfor cheap, simple decoupling. - Eventing enables reactive architectures:
Event Gridfor discrete notifications,Event Hubsfor high-volume streaming. - API Management is the governance layer: authentication, throttling, versioning, and caching at the gateway — backends stay focused on business logic.
- Caching with Redis absorbs repetitive reads and session state, cutting latency by orders of magnitude — but choose at least Standard tier for production SLA.
- App Configuration + Key Vault separate settings from secrets, enabling feature flags with dynamic refresh and zero-credential code via managed identities.
- Automated deployment via Bicep + CI/CD pipelines makes infrastructure repeatable, auditable, and rollback-safe — never deploy from a laptop.
Connections & Next Steps
Reading order for the six LO-level lessons under this topic:
- LO34 — Designing a Messaging Architecture — Deep dive into Service Bus queues, topics, sessions, dead-lettering, and Storage Queue patterns.
- LO35 — Designing an Event-Driven Architecture — Event Grid custom topics, Event Hubs partitioning, Capture, and consumer group design.
- LO36 — Designing an API Integration Strategy — APIM policies in depth, API versioning, self-hosted gateways, and synthetic GraphQL.
- LO37 — Designing a Caching Solution — Redis data structures, eviction policies, geo-replication, and cache-aside implementation.
- LO38 — Designing Application Configuration Management — App Configuration labelling, snapshots, Key Vault references, and private endpoints.
- LO39 — Designing Automated Deployment — Bicep modules, what-if analysis, environment promotion, blue-green with App Service slots.
Related Topics and Units:
- Unit 1, Topic 2 — Authentication and Authorization: APIM
validate-jwtpolicies rely on Entra ID tokens — review identity foundations. - Unit 3, Topic 1 — High Availability: Redis geo-replication and Service Bus geo-disaster-recovery tie directly into HA design.
- Unit 4, Topic 1 — Compute Solutions: App Service, Functions, and AKS are the backends that messaging, caching, and configuration plug into.
- Unit 1, Topic 1 — Logging and Monitoring: Monitor APIM latency, Redis hit rates, and Service Bus dead-letter depth with
Azure MonitorandApplication Insights.
Next: Start with LO34 (Messaging) to build the foundational decoupling pattern, then progress through the list. Each LO lesson pairs with its question bank for exam-style practice.