0%
Deploying .NET Applications to Azure: A Complete Guide

Deploying .NET Applications to Azure: A Complete Guide

Learn how to deploy your .NET applications to the Azure cloud platform efficiently with this step-by-step guide covering App Service, Functions, Containers, and DevOps.

I

InSkillCoach

· min

Deploying .NET Applications to Azure: A Complete Guide

Introduction

Microsoft Azure offers a rich, high-performance ecosystem for hosting your .NET applications. Thanks to the native integration between .NET and Azure, you can deploy your applications easily and benefit from automatic scalability, high availability, and enhanced security. This guide walks you through the different deployment options and best practices for optimizing your .NET applications in the cloud.

Prerequisites

Before you begin, make sure you have:

  • An Azure account (you can create a free account at azure.microsoft.com)
  • The .NET SDK installed on your development machine
  • Azure CLI or Azure PowerShell installed (optional but recommended)
  • Visual Studio 2022 or Visual Studio Code with the Azure extension
  • Git for version control

Azure App Service for .NET Web Applications

Azure App Service is the ideal PaaS (Platform as a Service) solution for hosting your ASP.NET and ASP.NET Core web applications.

Creating an App Service from the Azure Portal

  1. Sign in to the Azure Portal
  2. Click “Create a resource” > “Web” > “App Service”
  3. Fill in the basic information:
    • Resource group: create a new one or use an existing one
    • App name: must be globally unique across Azure
    • Publish: select “Code”
    • Runtime stack: choose ”.NET 6” (or the version you are using)
    • Operating system: Windows or Linux
    • Region: choose the one closest to your users
    • App Service plan: select an existing plan or create a new one
  4. Click “Review + create,” then “Create”

Deploying from Visual Studio

  1. Open your solution in Visual Studio
  2. Right-click the web project and select “Publish”
  3. Choose “Azure” as the target
  4. Select “Azure App Service,” then the instance you just created
  5. Configure the deployment settings and click “Publish”

Deploying with Azure DevOps

# azure-pipelines.yml
trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

variables:
  buildConfiguration: 'Release'
  webAppName: 'votre-app-service'

steps:
- task: UseDotNet@2
  inputs:
    packageType: 'sdk'
    version: '6.x'

- script: dotnet build --configuration $(buildConfiguration)
  displayName: 'dotnet build $(buildConfiguration)'

- task: DotNetCoreCLI@2
  inputs:
    command: 'publish'
    publishWebProjects: true
    arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'
    zipAfterPublish: true

- task: AzureWebApp@1
  inputs:
    azureSubscription: 'votre-connexion-azure'
    appName: '$(webAppName)'
    package: '$(Build.ArtifactStagingDirectory)/*.zip'

Environment Configuration

Use application settings to configure your application without recompiling:

  1. In the Azure portal, go to your App Service
  2. Under “Configuration” > “Application settings,” add your environment variables
  3. For example, for a database connection string:
    • Name: ConnectionStrings__DefaultConnection
    • Value: your connection string

Azure Functions for Serverless Microservices

Azure Functions lets you run small pieces of code without managing the underlying infrastructure.

Creating a Function App

// Simple Function App that responds to HTTP requests
public static class HttpExample
{
    [FunctionName("HttpExample")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        string name = req.Query["name"];
        
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        name = name ?? data?.name;
        
        string responseMessage = string.IsNullOrEmpty(name)
            ? "Cette fonction HTTP a été exécutée avec succès. Passez un nom dans la requête pour obtenir un message personnalisé."
            : $"Bonjour, {name}. Cette fonction HTTP a été exécutée avec succès.";
            
        return new OkObjectResult(responseMessage);
    }
}

Deploying Azure Functions

From Visual Studio

  1. Create an Azure Functions project
  2. Develop your functions
  3. Right-click the project > “Publish”
  4. Choose Azure as the target
  5. Select or create a Function App

Using Azure CLI

# Sign in to Azure
az login

# Create a resource group (if needed)
az group create --name MonGroupeDeRessources --location francecentral

# Create a Function App
az functionapp create --resource-group MonGroupeDeRessources --consumption-plan-location francecentral --runtime dotnet --functions-version 4 --name MonAppDeFonctions --storage-account monstockage

# Deploy the code
func azure functionapp publish MonAppDeFonctions

Containerization with Docker and Azure Container Registry

Containerizing your .NET applications provides portability and consistency across environments.

Creating a Dockerfile for ASP.NET Core

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["MonApp.csproj", "./"]
RUN dotnet restore "MonApp.csproj"
COPY . .
RUN dotnet build "MonApp.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MonApp.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MonApp.dll"]

Creating and Using Azure Container Registry (ACR)

# Create a container registry
az acr create --resource-group MonGroupeDeRessources --name monregistre --sku Basic

# Sign in to the registry
az acr login --name monregistre

# Build the Docker image
docker build -t monapp:v1 .

# Tag the image for ACR
docker tag monapp:v1 monregistre.azurecr.io/monapp:v1

# Push the image to ACR
docker push monregistre.azurecr.io/monapp:v1

Deploying to Azure App Service with Containers

# Enable admin access for the registry
az acr update -n monregistre --admin-enabled true

# Get the registry credentials
az acr credential show -n monregistre

# Create an App Service plan that supports containers
az appservice plan create --resource-group MonGroupeDeRessources --name MonPlanAppService --is-linux --sku B1

# Create an App Service that uses the container
az webapp create --resource-group MonGroupeDeRessources --plan MonPlanAppService --name MonAppWeb --deployment-container-image-name monregistre.azurecr.io/monapp:v1

# Configure the registry credentials
az webapp config container set --name MonAppWeb --resource-group MonGroupeDeRessources --docker-custom-image-name monregistre.azurecr.io/monapp:v1 --docker-registry-server-url https://monregistre.azurecr.io --docker-registry-server-user monregistre --docker-registry-server-password <mot-de-passe>

Azure Kubernetes Service (AKS) for .NET Applications

AKS is ideal for complex applications that require advanced container orchestration.

Deploying a .NET Application to AKS

  1. Create an AKS cluster:
az aks create --resource-group MonGroupeDeRessources --name MonClusterAKS --node-count 2 --enable-addons monitoring --generate-ssh-keys
  1. Connect to the cluster:
az aks get-credentials --resource-group MonGroupeDeRessources --name MonClusterAKS
  1. Create a Kubernetes deployment file (deployment.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
  name: monapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: monapp
  template:
    metadata:
      labels:
        app: monapp
    spec:
      containers:
      - name: monapp
        image: monregistre.azurecr.io/monapp:v1
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: monapp
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: monapp
  1. Deploy the application to AKS:
kubectl apply -f deployment.yaml
  1. Verify that the service is accessible:
kubectl get services monapp

Azure Databases for .NET Applications

Azure SQL Database with Entity Framework Core

  1. Create an Azure SQL database from the Azure portal

  2. Configure the connection string in your application:

// appsettings.json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=tcp:monserveur.database.windows.net,1433;Database=maBaseDeDonnees;User ID=monutilisateur;Password=monMotDePasse;Encrypt=true;Connection Timeout=30;"
  }
}
  1. Use Entity Framework Core to connect:
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    
    // ...
}

Azure Cosmos DB for NoSQL

// Cosmos DB client configuration
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<CosmosClient>(serviceProvider => {
        var configuration = serviceProvider.GetRequiredService<IConfiguration>();
        var cosmosDbSection = configuration.GetSection("CosmosDb");
        var endpoint = cosmosDbSection["Endpoint"];
        var key = cosmosDbSection["Key"];
        
        return new CosmosClient(endpoint, key);
    });
    
    services.AddSingleton<IDocumentRepository, CosmosDbRepository>();
}

CI/CD for .NET Applications with GitHub Actions

GitHub Actions Workflow for App Service

# .github/workflows/azure-webapps-dotnet.yml
name: .NET Core CI/CD pour Azure Web App

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

env:
  AZURE_WEBAPP_NAME: votre-app-service
  AZURE_WEBAPP_PACKAGE_PATH: '.'
  DOTNET_VERSION: '6.0.x'

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    
    - name: Configurer .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: ${{ env.DOTNET_VERSION }}
    
    - name: Restaurer les dépendances
      run: dotnet restore
    
    - name: Build
      run: dotnet build --configuration Release --no-restore
    
    - name: Test
      run: dotnet test --no-restore --verbosity normal
    
    - name: Publish
      run: dotnet publish -c Release -o ${{env.AZURE_WEBAPP_PACKAGE_PATH}}/myapp
    
    - name: Déployer sur Azure Web App
      uses: azure/webapps-deploy@v2
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: ${{env.AZURE_WEBAPP_PACKAGE_PATH}}/myapp

Monitoring and Diagnostics

Application Insights for Monitoring

  1. Create an Application Insights resource in the Azure portal

  2. Integrate Application Insights into your application:

// Program.cs (.NET 6)
var builder = WebApplication.CreateBuilder(args);

// Add Application Insights
builder.Services.AddApplicationInsightsTelemetry();

// ...

var app = builder.Build();
  1. Add custom logs:
// In a controller or service
public class MonController : Controller
{
    private readonly ILogger<MonController> _logger;
    
    public MonController(ILogger<MonController> logger)
    {
        _logger = logger;
    }
    
    public IActionResult Index()
    {
        _logger.LogInformation("La page d'accueil a été visitée");
        return View();
    }
}
  1. View the metrics in the Azure Application Insights portal

Securing .NET Applications on Azure

Using Azure Key Vault

  1. Create a key vault in the Azure portal

  2. Grant permissions to your application:

az keyvault set-policy --name MonCoffre --object-id <object-id-de-votre-app> --secret-permissions get list
  1. Integrate Key Vault into your application:
// Program.cs
var builder = WebApplication.CreateBuilder(args);

// Add the Azure Key Vault configuration
builder.Configuration.AddAzureKeyVault(
    new Uri($"https://{builder.Configuration["KeyVault:VaultName"]}.vault.azure.net/"),
    new DefaultAzureCredential());

Setting Up Azure AD B2C for Authentication

// Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C"));

// ...

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

Cost Optimization

Tips for Reducing Costs on Azure

  1. Choose the right pricing tier:

    • Use the Free and Shared tiers for development
    • Consider Basic/Standard for small to medium-sized production workloads
  2. Scale automatically:

    • Configure autoscaling based on your needs
    az monitor autoscale create --resource-group MonGroupeDeRessources --resource monappservice --resource-type "Microsoft.Web/sites" --name autoscale-config --min-count 1 --max-count 5 --count 1
  3. Use reserved instances for long-term savings

  4. Enable Azure Cost Management to monitor and optimize spending

  5. Clean up unused resources regularly

Best Practices for .NET on Azure

  1. Cloud-native architecture:

    • Design for resilience and scalability
    • Use serverless architectures when appropriate
  2. Externalized configuration:

    • Store settings in Azure App Configuration or Key Vault
    • Use environment variables for environment-specific configurations
  3. Comprehensive monitoring:

    • Integrate Application Insights from the start
    • Configure alerts for critical metrics
  4. Automated testing:

    • Include load tests specifically for Azure
    • Use test/staging environments
  5. Infrastructure as Code (IaC):

    • Use Azure Resource Manager (ARM) or Terraform
    // example ARM template
    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "appServiceName": {
          "type": "string",
          "metadata": {
            "description": "Nom de l'App Service"
          }
        }
      },
      "resources": [
        {
          "type": "Microsoft.Web/serverfarms",
          "apiVersion": "2020-06-01",
          "name": "[parameters('appServiceName')]",
          "location": "[resourceGroup().location]",
          "sku": {
            "name": "B1",
            "tier": "Basic"
          }
        }
      ]
    }

Conclusion

Azure offers a rich, integrated ecosystem for your .NET applications, covering the entire development lifecycle. By combining Azure services with .NET development best practices, you can build robust, high-performing, and scalable applications.

The tools and services presented in this guide are only the beginning of what Azure can offer .NET developers. Don’t hesitate to explore further and combine different services to meet your application’s specific needs.

Additional Resources

InSkillCoach

About InSkillCoach

Training and technology expert

Coach specializing in advanced technologies and AI, backed by GNeurone Inc.

Certifications:

  • AWS Certified Solutions Architect – Professional
  • Google Cloud certifications
  • Microsoft Certified: DevOps Engineer Expert
  • Certified Kubernetes Administrator (CKA)
  • CompTIA Security+
1.4k
226

Comments

Comments are powered by GitHub Discussions

Sign in with GitHub to join the discussion

Link copied!