The Azure Developer Associate exam (AZ-204) validates the ability to design, build, test, and maintain cloud applications on Microsoft Azure. It is code-heavy and expects real development experience — these five concepts recur in scenarios.
1. Azure Compute Solutions#
Compute solutions make up 25-30% of the exam — you need to know when to use each service and how to implement them.
Tip
Think of Azure compute as a spectrum: VMs give you full control, App Service handles the platform, Functions go serverless, and containers offer portability. Choose based on your control vs. management trade-off.
Azure App Service#
App Service is your go-to for hosting web applications, REST APIs, and mobile backends:
// Configure App Service settings programmatically
var webApp = azure.WebApps.Define("myapp")
.WithRegion(Region.USEast)
.WithExistingResourceGroup("myResourceGroup")
.WithNewAppServicePlan(PricingTier.StandardS1)
.WithRuntimeStack(WebAppRuntimeStack.NETCore("6.0"))
.WithAppSetting("ConnectionString", "@Microsoft.KeyVault(SecretUri=...)")
.Create();
Key concepts to know:
- Deployment slots — Deploy to staging, test, then swap to production with zero downtime
- Autoscale rules — Scale based on metrics like CPU, memory, or HTTP queue length
- App Settings & Connection Strings — Configure without code changes, use Key Vault references
Azure Functions#
Serverless compute for event-driven scenarios:
// Blob-triggered function example
[FunctionName("ProcessImage")]
public static async Task Run(
[BlobTrigger("images/{name}", Connection = "StorageConnection")] Stream imageBlob,
string name,
[Blob("thumbnails/{name}", FileAccess.Write)] Stream thumbnailBlob,
ILogger log)
{
log.LogInformation($"Processing blob: {name}");
// Generate thumbnail and write to output blob
await GenerateThumbnailAsync(imageBlob, thumbnailBlob);
}
| Trigger Type | Use Case |
|---|---|
| HTTP | REST APIs, webhooks |
| Timer | Scheduled tasks, cleanup jobs |
| Blob | Process uploaded files |
| Queue | Background processing, decoupling |
| Event Grid | React to Azure events |
| Service Bus | Enterprise messaging scenarios |
Azure Container Solutions#
| Service | Description | Use When |
|---|---|---|
| Container Instances (ACI) | Simple, fast container hosting | Quick deployments, burst workloads |
| Container Apps | Serverless containers with autoscale | Microservices, event-driven apps |
| Kubernetes Service (AKS) | Full Kubernetes orchestration | Complex multi-container workloads |
You need to run a containerized app that scales to zero when idle and scales up based on HTTP traffic. Which service is best?
2. Azure Storage Solutions#
Understanding storage options and access patterns is critical for the exam.
Blob Storage Operations#
// Upload a blob with metadata
BlobClient blobClient = containerClient.GetBlobClient("document.pdf");
var options = new BlobUploadOptions
{
HttpHeaders = new BlobHttpHeaders { ContentType = "application/pdf" },
Metadata = new Dictionary<string, string>
{
{ "uploadedBy", "user123" },
{ "department", "engineering" }
}
};
await blobClient.UploadAsync(fileStream, options);
Blob Access Tiers#
| Tier | Access Frequency | Min Storage Duration | Cost |
|---|---|---|---|
| Hot | Frequently accessed | None | Higher storage, lower access |
| Cool | Infrequently accessed | 30 days | Lower storage, higher access |
| Cold | Rarely accessed | 90 days | Even lower storage |
| Archive | Rarely accessed, offline | 180 days | Lowest storage, highest access |
Warning
Archive tier blobs must be rehydrated before access — this can take hours! Use blob lifecycle management policies to automatically transition blobs between tiers.
Shared Access Signatures (SAS)#
SAS tokens provide secure, delegated access to your storage resources:
// Generate a SAS token for blob read access
BlobSasBuilder sasBuilder = new BlobSasBuilder
{
BlobContainerName = containerName,
BlobName = blobName,
Resource = "b", // b for blob
ExpiresOn = DateTimeOffset.UtcNow.AddHours(1)
};
sasBuilder.SetPermissions(BlobSasPermissions.Read);
Uri sasUri = blobClient.GenerateSasUri(sasBuilder);
SAS Types:
- User Delegation SAS — Secured with Entra ID credentials (most secure)
- Service SAS — Scoped to a single storage service
- Account SAS — Access to multiple services in a storage account
Azure Cosmos DB#
Know the consistency levels — this is heavily tested:
| Level | Guarantee | Latency | Use Case |
|---|---|---|---|
| Strong | Linearizability | Highest | Financial transactions |
| Bounded Staleness | Consistent prefix, bounded lag | High | Leaderboards, inventory |
| Session | Read your writes within session | Medium | Shopping carts, user profiles |
| Consistent Prefix | Ordered reads | Low | Social feeds |
| Eventual | No ordering guarantee | Lowest | Analytics, non-critical reads |
// Query with the SDK
var container = cosmosClient.GetContainer("database", "products");
var query = new QueryDefinition(
"SELECT * FROM c WHERE c.category = @category")
.WithParameter("@category", "electronics");
using FeedIterator<Product> iterator = container.GetItemQueryIterator<Product>(query);
while (iterator.HasMoreResults)
{
FeedResponse<Product> response = await iterator.ReadNextAsync();
foreach (Product product in response)
{
Console.WriteLine(product.Name);
}
}
You need to give a partner temporary read access to a specific blob without sharing your account key. What should you use?
3. Implementing Azure Security#
Security is 20-25% of the exam. Focus on managed identities, Key Vault, and authentication patterns.
Note
The exam loves questions about managed identities — they eliminate the need to manage credentials in code. System-assigned identities are tied to a resource's lifecycle; user-assigned identities can be shared across resources.
Managed Identity with Key Vault#
// Access Key Vault using managed identity (no credentials in code!)
var credential = new DefaultAzureCredential();
var client = new SecretClient(
new Uri("https://myvault.vault.azure.net/"),
credential);
KeyVaultSecret secret = await client.GetSecretAsync("DatabasePassword");
string connectionString = secret.Value;
App Service Authentication (Easy Auth)#
Configure identity providers without writing authentication code:
// authentication settings in Azure portal or ARM template
{
"platform": {
"enabled": true
},
"identityProviders": {
"azureActiveDirectory": {
"enabled": true,
"registration": {
"clientId": "<app-registration-client-id>",
"openIdIssuer": "https://login.microsoftonline.com/<tenant-id>/v2.0"
}
}
},
"login": {
"tokenStore": {
"enabled": true
}
}
}
Microsoft Identity Platform#
For custom authentication, use MSAL (Microsoft Authentication Library):
// Acquire token for calling an API
var app = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{tenantId}"))
.Build();
var result = await app
.AcquireTokenForClient(new[] { "api://target-api/.default" })
.ExecuteAsync();
string accessToken = result.AccessToken;
Security Best Practices#
| Practice | Implementation |
|---|---|
| Never store secrets in code | Use Key Vault with managed identity |
| Use managed identities | Enable system or user-assigned identity |
| Apply least privilege | Grant minimum required permissions |
| Rotate secrets | Use Key Vault secret rotation |
| Validate tokens | Verify issuer, audience, and signature |
Your Azure Function needs to read secrets from Key Vault. What's the most secure approach?
4. Monitoring and Optimization#
Understand how to instrument applications and optimize performance.
Application Insights#
// Custom telemetry tracking
private readonly TelemetryClient _telemetryClient;
public async Task ProcessOrderAsync(Order order)
{
var stopwatch = Stopwatch.StartNew();
try
{
// Track custom event
_telemetryClient.TrackEvent("OrderProcessed", new Dictionary<string, string>
{
{ "OrderId", order.Id },
{ "CustomerId", order.CustomerId }
});
await ProcessAsync(order);
// Track custom metric
_telemetryClient.TrackMetric("OrderProcessingTime", stopwatch.ElapsedMilliseconds);
}
catch (Exception ex)
{
// Track exception with context
_telemetryClient.TrackException(ex, new Dictionary<string, string>
{
{ "OrderId", order.Id }
});
throw;
}
}
Key Application Insights Features#
| Feature | Purpose |
|---|---|
| Distributed Tracing | Correlate requests across services |
| Live Metrics | Real-time performance monitoring |
| Application Map | Visualize service dependencies |
| Smart Detection | Automatic anomaly detection |
| Availability Tests | Monitor endpoint health globally |
Caching with Azure Cache for Redis#
// Connection with proper configuration
var connection = ConnectionMultiplexer.Connect(new ConfigurationOptions
{
EndPoints = { "mycache.redis.cache.windows.net:6380" },
Password = "<access-key>",
Ssl = true,
AbortOnConnectFail = false
});
IDatabase cache = connection.GetDatabase();
// Cache-aside pattern
public async Task<Product> GetProductAsync(string productId)
{
string cacheKey = $"product:{productId}";
// Try cache first
string cached = await cache.StringGetAsync(cacheKey);
if (!string.IsNullOrEmpty(cached))
return JsonSerializer.Deserialize<Product>(cached);
// Load from database
Product product = await _database.GetProductAsync(productId);
// Cache for 1 hour
await cache.StringSetAsync(
cacheKey,
JsonSerializer.Serialize(product),
TimeSpan.FromHours(1));
return product;
}
Tip
Use the cache-aside pattern: check the cache first, load from the source on cache miss, then populate the cache. This works well for read-heavy workloads with data that changes infrequently.
Azure CDN#
CDN improves performance by caching static content at edge locations:
- Cache rules — Control what gets cached and for how long
- Query string caching — Ignore, cache unique, or bypass cache
- Compression — Automatic gzip/brotli compression
- Custom domains — Use your own domain with HTTPS
You need to track how long specific operations take in your application. What Application Insights method should you use?
5. Connect to Azure Services#
The final domain covers API Management, messaging, and event-driven patterns.
Azure API Management#
API Management provides a facade for your backend services:
<!-- Inbound policy example: validate JWT and rate limit -->
<inbound>
<validate-jwt header-name="Authorization"
failed-validation-httpcode="401"
require-signed-tokens="true">
<openid-config url="https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration"/>
<required-claims>
<claim name="aud" match="any">
<value>{client-id}</value>
</claim>
</required-claims>
</validate-jwt>
<rate-limit calls="100" renewal-period="60"/>
</inbound>
Event Grid vs Service Bus vs Queue Storage#
| Service | Pattern | Message Size | Use Case |
|---|---|---|---|
| Event Grid | Pub/Sub events | 1 MB | React to Azure/custom events |
| Service Bus | Enterprise messaging | 256 KB – 100 MB | Ordered, transactional messaging |
| Queue Storage | Simple queue | 64 KB | Lightweight async processing |
Event Grid Integration#
// Publish custom events
var client = new EventGridPublisherClient(
new Uri("https://mytopic.eastus-1.eventgrid.azure.net/api/events"),
new AzureKeyCredential("<topic-key>"));
var events = new List<EventGridEvent>
{
new EventGridEvent(
subject: "orders/new",
eventType: "Order.Created",
dataVersion: "1.0",
data: new { OrderId = "12345", CustomerId = "C001" })
};
await client.SendEventsAsync(events);
Service Bus Patterns#
// Send message with session for ordered processing
var client = new ServiceBusClient(connectionString);
var sender = client.CreateSender("orders-queue");
var message = new ServiceBusMessage(JsonSerializer.SerializeToUtf8Bytes(order))
{
SessionId = order.CustomerId, // Group by customer
MessageId = Guid.NewGuid().ToString(),
ContentType = "application/json"
};
await sender.SendMessageAsync(message);
Note
Sessions in Service Bus enable FIFO (first-in, first-out) processing. All messages with the same SessionId are processed in order by a single consumer. This is essential for scenarios like order processing where sequence matters.
Multiple services need to react when a new customer signs up. Which service best supports this pub/sub pattern?
Know your range before test day#
AZ-204 is code-and-scenario heavy. A short diagnostic shows which compute, security, or messaging topics still break under pressure.
- Timed diagnostic with domain-level breakdown
- Clear signal on what to drill next
- Practice free; timed sittings and readiness range on Pro
Take the free AZ-204 assessment →
Next step: Start practicing free on the AZ-204 hub, or sit a short diagnostic first.