MFormations
Modern DevOps Engineering

Chapitre 8

08 — Microsoft Azure

08 — Microsoft Azure

Course: Microsoft Azure

1. Azure Kubernetes Service (AKS)

1.1 AKS Architecture

AKS provides managed Kubernetes with integrated Azure services:

  • Control plane: Microsoft-managed (free)
  • Node pools: Linux and Windows, system and user pools
  • Managed Identity: Integrated with Azure AD
  • Virtual nodes: Serverless pods via ACI
  • Cluster autoscaler: Automatically scales node pools
  • Azure CNI: Native VPC networking or Kubenet
  • Azure AD Integration: RBAC with Azure AD

1.2 Cluster Creation

# Create AKS cluster
az aks create \
  --resource-group rg-aks \
  --name aks-production \
  --node-count 3 \
  --node-vm-size Standard_D4s_v3 \
  --enable-managed-identity \
  --enable-cluster-autoscaler \
  --min-count 3 \
  --max-count 10 \
  --network-plugin azure \
  --network-policy calico \
  --enable-addons monitoring \
  --vnet-subnet-id /subscriptions/.../subnets/aks-subnet \
  --zones 1 2 3

# Add user node pool
az aks nodepool add \
  --resource-group rg-aks \
  --cluster-name aks-production \
  --name userpool \
  --node-count 3 \
  --mode User \
  --node-vm-size Standard_D8s_v3 \
  --enable-cluster-autoscaler \
  --min-count 3 \
  --max-count 20 \
  --zones 1 2 3

1.3 AKS Security

# Enable Azure AD integration
az aks update \
  --resource-group rg-aks \
  --name aks-production \
  --enable-aad \
  --aad-admin-group-object-ids <group-id>

# Enable pod identity
az aks update \
  --resource-group rg-aks \
  --name aks-production \
  --enable-pod-identity

# Enable Azure Policy for AKS
az aks enable-addons \
  --resource-group rg-aks \
  --name aks-production \
  --addons azure-policy

2. Azure Functions

2.1 Function App

Azure Functions is a serverless compute service for event-driven applications.

// HTTP Trigger
[FunctionName("GetUsers")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", Route = "users/{id}")] HttpRequest req,
    string id,
    [CosmosDB(
        databaseName: "MyDB",
        containerName: "Users",
        Connection = "CosmosDBConnection")]
    IAsyncCollector<User> users,
    ILogger log)
{
    log.LogInformation($"Getting user {id}");
    // ...
    return new OkObjectResult(user);
}

2.2 Triggers and Bindings

{
  "bindings": [
    {
      "name": "queueItem",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "orders",
      "connection": "StorageConnection"
    },
    {
      "name": "document",
      "type": "cosmosDB",
      "direction": "out",
      "databaseName": "MyDB",
      "collectionName": "Orders",
      "connectionStringSetting": "CosmosDBConnection"
    }
  ]
}

2.3 Durable Functions

Durable Functions manage stateful workflows:

[FunctionName("OrderWorkflow")]
public static async Task<List<string>> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var order = context.GetInput<Order>();
    var payment = await context.CallActivityAsync<bool>("ProcessPayment", order);
    if (!payment) return new List<string> { "Payment failed" };

    await context.CallActivityAsync("UpdateInventory", order);
    var shipping = await context.CallActivityAsync<string>("CreateShipment", order);
    await context.CallActivityAsync("SendConfirmation", new { order, shipping });

    return new List<string> { "Completed", shipping };
}

3. Azure DevOps

3.1 Pipelines

# azure-pipelines.yml
trigger:
  - main
  - develop

pool:
  vmImage: ubuntu-latest

variables:
  dockerRegistryServiceConnection: 'acr-connection'
  imageRepository: 'myapp'
  tag: '$(Build.BuildId)'
  dockerfilePath: 'Dockerfile'

stages:
- stage: Build
  jobs:
  - job: BuildAndPush
    steps:
    - task: Docker@2
      displayName: Build and push image
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)
          latest

    - task: PublishPipelineArtifact@1
      inputs:
        targetPath: '$(System.DefaultWorkingDirectory)/k8s'
        artifact: 'manifests'

- stage: DeployDev
  dependsOn: Build
  condition: succeeded()
  jobs:
  - deployment: Deploy
    environment: dev
    strategy:
      runOnce:
        deploy:
          steps:
          - task: KubernetesManifest@0
            inputs:
              action: deploy
              manifests: '$(Pipeline.Workspace)/manifests/deployment.yaml'
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository):$(tag)

3.2 Multi-Stage YAML

# Deploy to multiple environments
stages:
- stage: Build
  jobs:
  - job: Build
    steps:
    - script: echo Building...

- stage: DeployDev
  dependsOn: Build
  environment: dev
  jobs:
  - deployment: Deploy
    steps:
    - script: echo Deploying to dev...

- stage: DeployStaging
  dependsOn: DeployDev
  environment: staging
  jobs:
  - deployment: Deploy
    steps:
    - script: echo Deploying to staging...

- stage: DeployProd
  dependsOn: DeployStaging
  environment: prod
  jobs:
  - deployment: Deploy
    steps:
    - script: echo Deploying to prod...

4. Azure Active Directory

4.1 Managed Identity

Managed Identity provides Azure services with an automatically managed identity in Azure AD:

# Enable system-assigned managed identity
az vm identity assign --resource-group rg-app --name vm-app
az aks update --resource-group rg-aks --name aks-prod --enable-managed-identity

# Use in code (Python)
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

credential = DefaultAzureCredential()
client = SecretClient(vault_url="https://myvault.vault.azure.net", credential=credential)
secret = client.get_secret("db-password")

4.2 Azure RBAC

# Create custom role
az role definition create --role-definition '{
  "Name": "Network Observer",
  "Description": "Read-only network access",
  "Actions": [
    "Microsoft.Network/*/read",
    "Microsoft.Network/virtualNetworks/subnets/read"
  ],
  "AssignableScopes": ["/subscriptions/<sub>"]
}'

# Assign role
az role assignment create \
  --assignee "user@example.com" \
  --role "Network Observer" \
  --scope "/subscriptions/<sub>/resourceGroups/rg-networking"

5. Virtual Network

5.1 VNet Design

# Create VNet with subnets
az network vnet create \
  --resource-group rg-networking \
  --name vnet-production \
  --address-prefixes 10.0.0.0/16 \
  --subnet-name aks-subnet \
  --subnet-prefixes 10.0.1.0/24

# Add subnets
az network vnet subnet create \
  --resource-group rg-networking \
  --vnet-name vnet-production \
  --name appgw-subnet \
  --address-prefixes 10.0.2.0/24

# VNet peering
az network vnet peering create \
  --resource-group rg-networking \
  --name vnet-prod-to-hub \
  --vnet-name vnet-production \
  --remote-vnet /subscriptions/.../vnet-hub \
  --allow-vnet-access

5.2 Azure Firewall

# Deploy Azure Firewall
az network firewall create \
  --resource-group rg-networking \
  --name fw-production \
  --sku Premium

# Add NAT rule (inbound)
az network firewall nat-rule create \
  --firewall-name fw-production \
  --collection-name inbound \
  --destination-addresses 1.2.3.4 \
  --destination-ports 443 \
  --protocols TCP \
  --action Dnat \
  --translated-address 10.0.1.10 \
  --translated-port 443

6. Cosmos DB

6.1 Database Configuration

# Create Cosmos DB account
az cosmosdb create \
  --resource-group rg-database \
  --name myapp-cosmos \
  --locations regionName=westeurope failoverPriority=0 \
  --locations regionName=northeurope failoverPriority=1 \
  --enable-multiple-write-locations false \
  --default-consistency-level Session

# Create database and container
az cosmosdb sql database create \
  --resource-group rg-database \
  --account-name myapp-cosmos \
  --name MyDB

az cosmosdb sql container create \
  --resource-group rg-database \
  --account-name myapp-cosmos \
  --database-name MyDB \
  --name Users \
  --partition-key-path "/tenantId" \
  --throughput 400

7. Key Vault

7.1 Secrets Management

# Create Key Vault
az keyvault create \
  --resource-group rg-security \
  --name myapp-keyvault \
  --sku Premium \
  --enable-purge-protection

# Add secrets
az keyvault secret set \
  --vault-name myapp-keyvault \
  --name db-password \
  --value "s3cr3t!"

# Access policy
az keyvault set-policy \
  --name myapp-keyvault \
  --object-id <principal-id> \
  --secret-permissions get list

# AKS integration
az aks enable-addons \
  --resource-group rg-aks \
  --name aks-production \
  --addons azure-keyvault-secrets-provider

8. Azure Monitor & Application Insights

8.1 Application Insights

// Configure telemetry
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Extensibility;

var config = TelemetryConfiguration.CreateDefault();
config.ConnectionString = "InstrumentationKey=...;IngestionEndpoint=https://...";
var client = new TelemetryClient(config);

client.TrackEvent("OrderPlaced", new Dictionary<string, string> {
    { "OrderId", order.Id },
    { "Amount", order.Total.ToString() }
});

client.TrackDependency("CosmosDB", "UpsertItem", "Users", DateTime.UtcNow, 150, true);

client.TrackException(new Exception("Payment failed"), new Dictionary<string, string> {
    { "OrderId", order.Id }
});

8.2 Log Analytics Queries

// Application Insights queries
requests
| where timestamp > ago(1d)
| summarize Count = count(), AvgDuration = avg(duration),
    P95 = percentile(duration, 95) by name
| order by AvgDuration desc

// Find failed requests
requests
| where success == false
| where timestamp > ago(1h)
| project timestamp, name, resultCode, duration, operation_Id
| join (exceptions | project operation_Id, type, message) on operation_Id

// Container logs in AKS
ContainerLog
| where TimeGenerated > ago(1h)
| where LogEntry contains "ERROR"
| project TimeGenerated, ContainerName, LogEntry

Summary

Azure provides deep integration with Microsoft ecosystem (Azure AD, DevOps). AKS offers managed Kubernetes with Azure AD and Managed Identity integration. Azure Functions provides serverless compute, Azure DevOps offers built-in CI/CD, Cosmos DB is a globally distributed NoSQL database, Key Vault handles secrets, and Application Insights provides observability.