Azure Services Overview for .NET Developers
Introduction
Microsoft Azure provides a comprehensive cloud platform with 200+ services. This guide focuses on the core services most relevant to .NET developers building modern applications.
Table of Contents
- Compute Services
- Data Services
- Integration Services
- Security & Identity
- Monitoring & DevOps
- Networking
- Service Selection Guide
- Interview Questions
Compute Services
Azure App Service
Platform-as-a-Service (PaaS) for hosting web applications, APIs, and mobile backends.
// Program.cs - Azure-ready ASP.NET Core app
var builder = WebApplication.CreateBuilder(args);
// Azure App Configuration integration
builder.Configuration.AddAzureAppConfiguration(options =>
{
options.Connect(builder.Configuration["ConnectionStrings:AppConfig"])
.UseFeatureFlags();
});
// Application Insights
builder.Services.AddApplicationInsightsTelemetry();
// Health checks for Azure
builder.Services.AddHealthChecks()
.AddAzureBlobStorage(builder.Configuration["ConnectionStrings:Storage"])
.AddSqlServer(builder.Configuration["ConnectionStrings:Database"]);
var app = builder.Build();
app.MapHealthChecks("/health");
app.Run();
Key Features:
- Auto-scaling based on metrics
- Deployment slots for zero-downtime deployments
- Built-in CI/CD integration
- Custom domains and SSL certificates
- VNet integration for private connectivity
Pricing Tiers:
| Tier | Use Case | Features |
|---|---|---|
| Free/Shared | Development | Limited, shared infrastructure |
| Basic | Low traffic | Dedicated compute, custom domains |
| Standard | Production | Auto-scale, staging slots, backups |
| Premium | High performance | Enhanced scaling, VNet, more slots |
| Isolated | Enterprise | Dedicated environment, compliance |
Azure Functions
Serverless compute for event-driven workloads.
// HTTP-triggered function
public class OrderFunctions
{
private readonly IOrderService _orderService;
public OrderFunctions(IOrderService orderService)
{
_orderService = orderService;
}
[Function("ProcessOrder")]
public async Task<IActionResult> ProcessOrder(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
{
var order = await req.ReadFromJsonAsync<Order>();
await _orderService.ProcessAsync(order);
return new OkResult();
}
// Timer-triggered function (runs every hour)
[Function("CleanupExpiredOrders")]
public async Task CleanupExpiredOrders(
[TimerTrigger("0 0 * * * *")] TimerInfo timer)
{
await _orderService.CleanupExpiredAsync();
}
// Queue-triggered function
[Function("SendOrderNotification")]
public async Task SendNotification(
[QueueTrigger("order-notifications")] OrderNotification notification)
{
await _notificationService.SendAsync(notification);
}
}
Trigger Types:
| Trigger | Use Case |
|---|---|
| HTTP | REST APIs, webhooks |
| Timer | Scheduled jobs, cleanup tasks |
| Queue | Async processing, decoupling |
| Blob | File processing, image resizing |
| Cosmos DB | Change feed processing |
| Event Hub | Stream processing, IoT |
| Service Bus | Enterprise messaging |
Hosting Plans:
| Plan | Scaling | Cold Start | Use Case |
|---|---|---|---|
| Consumption | Auto (0-200) | Yes | Sporadic workloads |
| Premium | Auto (1-100) | No | Low latency, VNet |
| Dedicated | Manual | No | Predictable workloads |
Azure Container Apps
Serverless containers without managing Kubernetes.
// Containerized .NET app
// Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyApp.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]
# Deploy to Container Apps
az containerapp create \
--name myapp \
--resource-group mygroup \
--environment myenvironment \
--image myregistry.azurecr.io/myapp:latest \
--target-port 8080 \
--ingress external \
--min-replicas 1 \
--max-replicas 10
Azure Kubernetes Service (AKS)
Managed Kubernetes for complex container orchestration.
# Kubernetes deployment for .NET app
apiVersion: apps/v1
kind: Deployment
metadata:
name: dotnet-api
spec:
replicas: 3
selector:
matchLabels:
app: dotnet-api
template:
metadata:
labels:
app: dotnet-api
spec:
containers:
- name: api
image: myregistry.azurecr.io/api:latest
ports:
- containerPort: 8080
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: ConnectionStrings__Database
valueFrom:
secretKeyRef:
name: db-secrets
key: connection-string
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
Data Services
Azure SQL Database
Managed SQL Server with built-in intelligence.
// Entity Framework Core with Azure SQL
public class ApplicationDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(
Configuration.GetConnectionString("Database"),
sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(
maxRetryCount: 5,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null);
sqlOptions.CommandTimeout(30);
});
}
}
// Connection string with managed identity (recommended)
// Server=tcp:myserver.database.windows.net;Database=mydb;Authentication=Active Directory Managed Identity;
Service Tiers:
| Tier | vCores | Max Size | Use Case |
|---|---|---|---|
| Basic | - | 2 GB | Dev/test |
| Standard | - | 250 GB | Light workloads |
| Premium | - | 4 TB | High performance |
| General Purpose | 2-80 | 4 TB | Most production |
| Business Critical | 2-128 | 4 TB | Low latency, HA |
| Hyperscale | 2-128 | 100 TB | Very large DBs |
Azure Cosmos DB
Globally distributed NoSQL database.
// Cosmos DB SDK usage
public class CosmosOrderRepository : IOrderRepository
{
private readonly Container _container;
public CosmosOrderRepository(CosmosClient cosmosClient)
{
_container = cosmosClient.GetContainer("OrdersDb", "Orders");
}
public async Task<Order> GetByIdAsync(string id, string partitionKey)
{
var response = await _container.ReadItemAsync<Order>(
id,
new PartitionKey(partitionKey));
return response.Resource;
}
public async Task<IEnumerable<Order>> GetByCustomerAsync(string customerId)
{
var query = new QueryDefinition(
"SELECT * FROM c WHERE c.customerId = @customerId")
.WithParameter("@customerId", customerId);
var iterator = _container.GetItemQueryIterator<Order>(query);
var results = new List<Order>();
while (iterator.HasMoreResults)
{
var response = await iterator.ReadNextAsync();
results.AddRange(response);
}
return results;
}
public async Task UpsertAsync(Order order)
{
await _container.UpsertItemAsync(order, new PartitionKey(order.CustomerId));
}
}
// Registration in DI
services.AddSingleton(sp =>
{
return new CosmosClient(
configuration["CosmosDb:Endpoint"],
new DefaultAzureCredential(), // Managed identity
new CosmosClientOptions
{
ApplicationName = "MyApp",
ConnectionMode = ConnectionMode.Direct
});
});
Consistency Levels:
| Level | Guarantee | Performance | Use Case |
|---|---|---|---|
| Strong | Linearizable | Lowest | Financial transactions |
| Bounded Staleness | Consistent within bounds | Medium | Inventory systems |
| Session | Read your writes | Good | Most applications |
| Consistent Prefix | No out-of-order reads | Better | Activity feeds |
| Eventual | May be out of order | Best | Analytics, logs |
Azure Blob Storage
Object storage for unstructured data.
public class AzureBlobStorageService : IFileStorageService
{
private readonly BlobContainerClient _containerClient;
public AzureBlobStorageService(BlobServiceClient blobServiceClient)
{
_containerClient = blobServiceClient.GetBlobContainerClient("documents");
}
public async Task<string> UploadAsync(Stream content, string fileName)
{
var blobClient = _containerClient.GetBlobClient(fileName);
await blobClient.UploadAsync(content, new BlobUploadOptions
{
HttpHeaders = new BlobHttpHeaders
{
ContentType = GetContentType(fileName)
}
});
return blobClient.Uri.ToString();
}
public async Task<Stream> DownloadAsync(string fileName)
{
var blobClient = _containerClient.GetBlobClient(fileName);
var response = await blobClient.DownloadAsync();
return response.Value.Content;
}
public async Task<string> GenerateSasUrlAsync(string fileName, TimeSpan expiry)
{
var blobClient = _containerClient.GetBlobClient(fileName);
var sasUri = blobClient.GenerateSasUri(
BlobSasPermissions.Read,
DateTimeOffset.UtcNow.Add(expiry));
return sasUri.ToString();
}
}
// Registration with managed identity
services.AddSingleton(_ =>
new BlobServiceClient(
new Uri("https://mystorageaccount.blob.core.windows.net"),
new DefaultAzureCredential()));
Storage Tiers:
| Tier | Access | Cost | Use Case |
|---|---|---|---|
| Hot | Frequent | Higher storage, lower access | Active data |
| Cool | Infrequent (30+ days) | Lower storage, higher access | Backups |
| Cold | Rare (90+ days) | Even lower storage | Compliance data |
| Archive | Rare (180+ days) | Lowest | Long-term retention |
Integration Services
Azure Service Bus
Enterprise message broker for reliable async communication.
// Publisher
public class OrderPublisher
{
private readonly ServiceBusSender _sender;
public OrderPublisher(ServiceBusClient client)
{
_sender = client.CreateSender("orders");
}
public async Task PublishOrderCreatedAsync(Order order)
{
var message = new ServiceBusMessage(JsonSerializer.SerializeToUtf8Bytes(order))
{
ContentType = "application/json",
Subject = "OrderCreated",
MessageId = order.Id.ToString(),
SessionId = order.CustomerId // For ordered processing
};
await _sender.SendMessageAsync(message);
}
}
// Consumer
public class OrderProcessor : BackgroundService
{
private readonly ServiceBusProcessor _processor;
private readonly IOrderService _orderService;
public OrderProcessor(ServiceBusClient client, IOrderService orderService)
{
_orderService = orderService;
_processor = client.CreateProcessor("orders", new ServiceBusProcessorOptions
{
MaxConcurrentCalls = 10,
AutoCompleteMessages = false
});
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_processor.ProcessMessageAsync += ProcessMessageAsync;
_processor.ProcessErrorAsync += ProcessErrorAsync;
await _processor.StartProcessingAsync(stoppingToken);
}
private async Task ProcessMessageAsync(ProcessMessageEventArgs args)
{
var order = JsonSerializer.Deserialize<Order>(args.Message.Body.Span);
await _orderService.ProcessAsync(order);
await args.CompleteMessageAsync(args.Message);
}
private Task ProcessErrorAsync(ProcessErrorEventArgs args)
{
_logger.LogError(args.Exception, "Error processing message");
return Task.CompletedTask;
}
}
Azure Event Grid
Event-based reactive programming.
// Event Grid trigger in Azure Functions
[Function("HandleBlobCreated")]
public async Task HandleBlobCreated(
[EventGridTrigger] EventGridEvent eventGridEvent)
{
var blobData = eventGridEvent.Data.ToObjectFromJson<StorageBlobCreatedEventData>();
_logger.LogInformation("Blob created: {Url}", blobData.Url);
await ProcessBlobAsync(blobData.Url);
}
// Publishing custom events
public class EventGridPublisher
{
private readonly EventGridPublisherClient _client;
public async Task PublishOrderCompletedAsync(Order order)
{
var cloudEvent = new CloudEvent(
source: "/orders",
type: "Order.Completed",
data: order);
await _client.SendEventAsync(cloudEvent);
}
}
Security & Identity
Azure Key Vault
Secure storage for secrets, keys, and certificates.
// Configuration with Key Vault
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddAzureKeyVault(
new Uri("https://mykeyvault.vault.azure.net/"),
new DefaultAzureCredential());
// Direct Key Vault access
public class SecretService
{
private readonly SecretClient _secretClient;
public SecretService(SecretClient secretClient)
{
_secretClient = secretClient;
}
public async Task<string> GetSecretAsync(string name)
{
var secret = await _secretClient.GetSecretAsync(name);
return secret.Value.Value;
}
}
// Certificate retrieval
public async Task<X509Certificate2> GetCertificateAsync(string name)
{
var certificate = await _certificateClient.GetCertificateAsync(name);
var secret = await _secretClient.GetSecretAsync(name);
return new X509Certificate2(Convert.FromBase64String(secret.Value.Value));
}
Managed Identity
Passwordless authentication between Azure services.
// DefaultAzureCredential handles all environments
// - Local: Visual Studio, Azure CLI, Environment variables
// - Azure: Managed Identity
var credential = new DefaultAzureCredential();
// Use with any Azure SDK
var blobClient = new BlobServiceClient(
new Uri("https://storage.blob.core.windows.net"),
credential);
var cosmosClient = new CosmosClient(
"https://mydb.documents.azure.com",
credential);
var secretClient = new SecretClient(
new Uri("https://myvault.vault.azure.net"),
credential);
Monitoring & DevOps
Application Insights
Full-stack monitoring for .NET applications.
// Automatic instrumentation
builder.Services.AddApplicationInsightsTelemetry(options =>
{
options.ConnectionString = builder.Configuration["ApplicationInsights:ConnectionString"];
options.EnableAdaptiveSampling = true;
});
// Custom telemetry
public class OrderService
{
private readonly TelemetryClient _telemetry;
public async Task ProcessOrderAsync(Order order)
{
using var operation = _telemetry.StartOperation<RequestTelemetry>("ProcessOrder");
try
{
// Track custom event
_telemetry.TrackEvent("OrderProcessed", new Dictionary<string, string>
{
["OrderId"] = order.Id.ToString(),
["CustomerId"] = order.CustomerId
});
// Track custom metric
_telemetry.TrackMetric("OrderTotal", order.Total);
await DoProcessingAsync(order);
operation.Telemetry.Success = true;
}
catch (Exception ex)
{
_telemetry.TrackException(ex);
operation.Telemetry.Success = false;
throw;
}
}
}
// Structured logging with Serilog
builder.Host.UseSerilog((context, config) =>
{
config
.ReadFrom.Configuration(context.Configuration)
.WriteTo.ApplicationInsights(
TelemetryConfiguration.Active,
TelemetryConverter.Traces);
});
Azure Monitor
Unified monitoring platform.
// Log Analytics queries (KQL)
// Query in Azure Portal or programmatically
// Find errors in last 24 hours
// traces
// | where timestamp > ago(24h)
// | where severityLevel >= 3
// | summarize count() by operation_Name, bin(timestamp, 1h)
// Request performance percentiles
// requests
// | where timestamp > ago(1h)
// | summarize percentiles(duration, 50, 90, 99) by name
Service Selection Guide
Compute Decision Tree
Need to host a web application?
├── Simple web app/API
│ └── Azure App Service
├── Event-driven/scheduled workloads
│ └── Azure Functions
├── Containers without Kubernetes complexity
│ └── Azure Container Apps
└── Full container orchestration needed
└── Azure Kubernetes Service (AKS)
Database Decision Tree
What type of data?
├── Relational (SQL)
│ ├── Need SQL Server compatibility
│ │ └── Azure SQL Database
│ └── Need PostgreSQL/MySQL
│ └── Azure Database for PostgreSQL/MySQL
├── Document/NoSQL
│ └── Azure Cosmos DB
├── Key-value cache
│ └── Azure Cache for Redis
└── Large files/blobs
└── Azure Blob Storage
Interview Questions
1. What is the difference between Azure App Service and Azure Functions?
Answer:
- App Service: Always-on PaaS for web apps and APIs. You pay for allocated resources regardless of usage. Best for traditional web applications with consistent traffic.
- Azure Functions: Serverless, event-driven compute. You pay only for execution time. Best for sporadic workloads, background jobs, and event processing. Has cold start latency on consumption plan.
2. When would you choose Cosmos DB over Azure SQL?
Answer: Choose Cosmos DB when you need:
- Global distribution with multi-region writes
- Flexible schema (document, graph, key-value)
- Horizontal scaling (millions of operations/sec)
- Low latency guarantees (< 10ms)
- Multi-model API support
Choose Azure SQL when you need:
- Complex relational queries and joins
- ACID transactions across tables
- Existing SQL Server compatibility
- Mature tooling (SSMS, EF Core)
3. How does Managed Identity improve security?
Answer: Managed Identity eliminates the need to store credentials in code or configuration. Azure automatically handles:
- Identity creation and lifecycle
- Token acquisition and renewal
- Credential rotation
Benefits:
- No secrets in Key Vault to manage
- No connection strings with passwords
- Automatic credential rotation
- Audit trail in Azure AD
4. Explain Azure Service Bus vs Event Grid vs Event Hub.
Answer:
- Service Bus: Enterprise message broker for reliable message delivery. Supports queues (point-to-point) and topics (pub-sub). Best for business transactions needing guaranteed delivery.
- Event Grid: Event routing service for reactive programming. Best for event-driven architectures responding to Azure resource events or custom events.
- Event Hub: High-throughput event streaming (millions/sec). Best for telemetry, IoT data, and log aggregation.