Azure Deployment
Azure App Service runs ASP.NET Core APIs without managing servers: you push code, it handles scaling, TLS certificates and patching. This lesson deploys the ShopSmart API with secure, password-free access to Azure SQL and Key Vault, and zero-downtime releases with slots.
On this page · 6 min · Advanced
On this page
- In simple words
- Learning objectives
- Explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 6 min
- Difficulty
- Advanced
- Updated
- Oct 29, 2026
Related tutorials
In simple words#
Deploying to Azure App Service is renting a fully managed shop: Azure handles the building, power and security guard; you bring the goods (your API).
- App Service
- Managed hosting for web apps and APIs.
- App settings
- Configuration that overrides appsettings.json.
- Managed identity
- Access Azure SQL without passwords.
Learning objectives#
- Create an App Service plan and web app with the Azure CLI
- Configure app settings and secrets safely
- Use managed identity for Azure SQL and Key Vault
- Release with deployment slots and GitHub Actions
Explanation#
Create a resource group, an App Service plan (Linux, e.g. P0v3 or B1) and a web app with the DOTNETCORE:9.0 runtime. Deploy a published zip, a container image, or from GitHub Actions.
App settings become environment variables: ASPNETCORE_ENVIRONMENT=Production, ConnectionStrings__Shop=…, Cors__Origins__0=https://shop.example.com. Use Key Vault references (@Microsoft.KeyVault(SecretUri=…)) for secrets.
Enable a system-assigned managed identity. Grant it access to Key Vault and create a contained database user for it in Azure SQL; the connection string then uses Authentication=Active Directory Default — no password anywhere.
Deployment slots (Standard tier and up): deploy to “staging”, warm it up and run smoke tests, then swap with production — zero downtime and instant rollback by swapping back.
Turn on HTTPS only, minimum TLS 1.2, health checks (/health), and Application Insights for logs and metrics.
Syntax#
az webapp create -g shopsmart-rg -p shopsmart-plan -n shopsmart-api --runtime "DOTNETCORE:9.0"
az webapp config appsettings set -g shopsmart-rg -n shopsmart-api --settings ASPNETCORE_ENVIRONMENT=Production
az webapp identity assign -g shopsmart-rg -n shopsmart-api
az webapp deployment slot swap -g shopsmart-rg -n shopsmart-api --slot staging
Code example: From zero to a deployed API with the Azure CLI#
# 1. Resource group, plan (Linux) and web app
az group create --name shopsmart-rg --location centralindia
az appservice plan create --name shopsmart-plan --resource-group shopsmart-rg --sku P0v3 --is-linux
az webapp create --name shopsmart-api --resource-group shopsmart-rg --plan shopsmart-plan --runtime "DOTNETCORE:9.0"
# 2. Security basics
az webapp update --name shopsmart-api --resource-group shopsmart-rg --https-only true
az webapp config set --name shopsmart-api --resource-group shopsmart-rg --min-tls-version 1.2 --generic-configurations '{"healthCheckPath": "/health"}'
# 3. Managed identity, then settings without passwords
PRINCIPAL_ID=$(az webapp identity assign --name shopsmart-api --resource-group shopsmart-rg --query principalId -o tsv)
az keyvault set-policy --name shopsmart-kv --object-id "$PRINCIPAL_ID" --secret-permissions get list
az webapp config appsettings set --name shopsmart-api --resource-group shopsmart-rg --settings \
ASPNETCORE_ENVIRONMENT=Production \
"ConnectionStrings__Shop=Server=tcp:shopsmart-sql.database.windows.net;Database=ShopSmart;Authentication=Active Directory Default" \
"Jwt__Key=@Microsoft.KeyVault(SecretUri=https://shopsmart-kv.vault.azure.net/secrets/JwtKey/)"
# In Azure SQL (as the Entra admin): CREATE USER [shopsmart-api] FROM EXTERNAL PROVIDER;
# ALTER ROLE db_datareader ADD MEMBER [shopsmart-api]; ALTER ROLE db_datawriter ADD MEMBER [shopsmart-api];
# 4. Publish and deploy to a staging slot, test it, then swap
dotnet publish ShopSmart.Api -c Release -o publish && (cd publish && zip -r ../api.zip .)
az webapp deployment slot create --name shopsmart-api --resource-group shopsmart-rg --slot staging
az webapp deploy --name shopsmart-api --resource-group shopsmart-rg --slot staging --src-path api.zip --type zip
curl --fail https://shopsmart-api-staging.azurewebsites.net/health
az webapp deployment slot swap --name shopsmart-api --resource-group shopsmart-rg --slot staging --target-slot production
After the swap, https://shopsmart-api.azurewebsites.net/health returns “Healthy”. The app reads its database through the managed identity and its JWT key from Key Vault; no secret appears in app settings or source control. Swapping back to the previous slot rolls back instantly.
This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- The CLI creates a Linux App Service plan and a web app with the .NET 9 runtime.
- HTTPS-only, TLS 1.2 and the /health path are configured for every instance.
- A managed identity gets Key Vault access; the JWT key is a Key Vault reference and the database connection string has no password.
- The API is deployed to a staging slot and checked with curl before anything reaches users.
- Swapping slots makes the tested build live with no downtime.
Real-world use case#
ShopSmart’s GitHub Actions workflow runs exactly these deploy, smoke-test and swap steps on every merge to main; a failed smoke test stops the workflow before the swap.
Common mistakes#
Anyone with portal read access sees them. Use managed identity or Key Vault references.
A bad deploy hits users immediately. Deploy to a slot, test, swap.
The default is Production — fine — but staging slots should use slot-specific settings so they do not hit production resources.
Best practices#
- Managed identity everywhere
- Key Vault references for secrets
- Staging slot + smoke test + swap
- HTTPS only, TLS 1.2+, health checks, Application Insights
Remember this#
App settings = environment variables (use __ for nesting).
Managed identity → Azure SQL and Key Vault without passwords.
Deploy to staging, test, swap.
Practice exercise#
Your task: Write a GitHub Actions workflow that builds the API on push to main and deploys it to the staging slot with azure/webapps-deploy.
Need a hint?
Show solution
name: Deploy API
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x
- run: dotnet publish ShopSmart.Api -c Release -o publish
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- uses: azure/webapps-deploy@v3
with:
app-name: shopsmart-api
slot-name: staging
package: publish
Mini quiz#
How does a deployment slot swap help?
Want more? Practise all ASP.NET Core Web API MCQs · ASP.NET Core Web API interview questions
My notes#
Saved in this browser.