☁️

Azure Services Overview

Cloud & Azure Intermediate 5 min read 900 words

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

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.

Sources

📚 Related Articles