There are roughly fifteen ways to deploy an ASP.NET Core app to Azure, and the official docs cover every variant. That's overwhelming when you just want a public URL. This tutorial picks one good path — App Service via the az CLI — and walks through it end to end, including configuration and a basic GitHub Actions pipeline.

Prerequisites

Sign in: az login. Confirm your subscription: az account show.

1. The app

dotnet new webapi -n HelloAzure -o HelloAzure
cd HelloAzure
dotnet run

Hit the URL printed in the console; you should get the WeatherForecast endpoint. That's our shippable artifact.

2. Create the Azure resources

Three things to create: a resource group (a named bucket for everything related to this app), an App Service plan (the compute), and a web app (the deployment slot).

$rg = "helloazure-rg"
$plan = "helloazure-plan"
$app = "helloazure-$(Get-Random -Maximum 99999)"  # must be globally unique

az group create -n $rg -l westeurope
az appservice plan create -g $rg -n $plan --sku B1 --is-linux
az webapp create -g $rg -p $plan -n $app --runtime "DOTNETCORE:9.0"

Three commands; one minute. Your app is live at https://<app>.azurewebsites.net, currently serving the default "your app is running" page.

3. First deploy

For a one-shot push from your laptop, ZIP-deploy is the fastest path:

dotnet publish -c Release -o publish
Compress-Archive -Path publish\* -DestinationPath app.zip -Force
az webapp deploy -g $rg -n $app --src-path app.zip --type zip

Browse to https://<app>.azurewebsites.net/weatherforecast — you'll see your real API responding. From dotnet new to public URL in under five minutes.

4. Configuration the right way

Don't put secrets in appsettings.json. App Service exposes environment variables that override config sections automatically. Set them with:

az webapp config appsettings set -g $rg -n $app --settings `
    ConnectionStrings__Default="Server=tcp:..." `
    Auth__JwtKey="$(New-Guid)"

The double-underscore is the .NET configuration provider's separator: it maps to ConnectionStrings:Default in your code. For real secrets, store them in Azure Key Vault and reference them from app settings as @Microsoft.KeyVault(SecretUri=...).

5. A sane CI pipeline

Manual deploys are fine for the first day. After that, wire up GitHub Actions. Generate a publish profile:

az webapp deployment list-publishing-profiles `
    -g $rg -n $app --xml > profile.xml

Add the contents as a repository secret named AZURE_WEBAPP_PUBLISH_PROFILE, then commit this workflow:

# .github/workflows/deploy.yml
name: Deploy to Azure
on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '9.0.x'

      - run: dotnet publish -c Release -o publish

      - uses: azure/webapps-deploy@v3
        with:
          app-name: helloazure-12345
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
          package: publish

Push to main and your app deploys. Add a test step before the deploy step and you've got a real pipeline.

6. Things you'll want to know within a week

Cost note. A B1 plan costs roughly $13/month if left running 24/7. Stop the App Service when you're not using it (az webapp stop) for personal projects, or use the F1 (Free) SKU — limited but real.

Closing

That's a complete, real deployment story: provision, deploy, configure, automate. It's deliberately not the fanciest path — no Bicep, no Container Apps, no Application Gateway — because for 90% of first deployments, you don't need them. Get something live, add complexity when it earns its keep.

We help teams take the next step: infrastructure as code, environments, secret rotation, and observability. Reach out if you'd like a structured walkthrough.