EN · · 4 min read
Operating a .NET Service on Azure
A production-minded checklist for identity, configuration, observability, resilience, deployment, and cost.
Technical GuideIntermediateTime Bound
Revised
A service is not production-ready when it compiles, passes tests, or responds correctly on a laptop. It becomes production-ready when a team can deploy it safely, understand its behavior, recover from failure, and control its cost.
Azure offers a large catalogue of services, but choosing more services is not the same as designing a better system. I prefer to begin with operational questions and select the smallest platform surface that answers them.
Establish the runtime boundary
For a typical ASP.NET Core service, the first choice is not between every Azure product. It is whether the workload needs a managed web runtime, container orchestration, event-driven execution, or static delivery.
| Workload | Starting point | Escalate when |
|---|---|---|
| HTTP API or web application | Azure App Service | Container/runtime constraints demand more control |
| Containerized service | Azure Container Apps | You need Kubernetes-level control |
| Event-triggered short work | Azure Functions | Execution or networking constraints do not fit |
| Static Astro site | Cloudflare Pages or Static Web Apps | Server behavior becomes a real requirement |
The starting point should minimize operational ownership. Complexity can be added after evidence appears.
Identity before secrets
Connection strings and API keys are easy locally and expensive operationally. On Azure, managed identity should be the default question for service-to-service access.
This removes long-lived credentials from deployment settings, but it does not remove authorization work. The identity still needs the minimum role, environment boundaries, rotation behavior, and an auditable owner.
Configuration has a lifecycle
Configuration is more than key-value storage. Each value has scope, sensitivity, owner, default, and failure behavior. A service should validate required settings at startup so a bad deployment fails clearly rather than producing delayed runtime errors.
builder.Services
.AddOptions<AuthorizationOptions>()
.BindConfiguration("Authorization")
.ValidateDataAnnotations()
.ValidateOnStart();
Secrets belong in Key Vault or an equivalent secret store. Non-secret configuration can live in environment settings or App Configuration. Feature flags need expiration and ownership; otherwise temporary decisions become permanent branches.
Observability begins with questions
Logs, metrics, and traces are three views of behavior:
- Metrics reveal trends and thresholds.
- Traces reveal the path and latency of one operation.
- Logs preserve contextual events that require explanation.
Instrument the boundaries first: incoming request, authorization decision, database call, external dependency, queue message, and background job. Use correlation identifiers consistently. Avoid logging payloads by default, especially tokens, personal data, and authorization tuples.
Resilience needs a failure model
Retries are not a universal reliability feature. They are appropriate only for transient failures and idempotent or protected operations. Unbounded retries multiply load during an outage.
timeout → bounded retry with jitter → circuit/open state → degraded response
Every dependency should have a time budget. Cancellation should flow from the HTTP request through application and data access layers. A queue consumer needs explicit poison-message and duplicate-delivery behavior.
Deployment is a reversible experiment
A safe deployment answers:
- What changed?
- How do we know it is healthy?
- What stops rollout?
- How do we return to a known state?
- Are database changes backward-compatible?
Blue/green slots or gradual revisions help, but the essential property is reversibility. Database migrations often define the real rollback boundary, so additive changes should precede destructive cleanup.
Cost is an architectural signal
Cost exposes architecture in aggregate: unnecessary data movement, idle capacity, noisy telemetry, and accidental fan-out eventually become visible on the bill.
Write the service contract before the deployment checklist
Operational readiness begins with explicit assumptions. What traffic shape is expected? Which operations may be retried? What data loss is acceptable? Which dependency failures should degrade the response and which should stop it? A list of Azure resources cannot answer these questions.
A compact service contract should record:
| Concern | Question |
|---|---|
| Availability | Which user journey must remain available? |
| Data | What consistency and recovery point are required? |
| Identity | Which workload may access each dependency? |
| Scale | What input or concurrency bound is expected? |
| Recovery | How is a failed deployment reversed? |
| Evidence | Which signals prove the service is healthy? |
The cloud topology should follow these answers rather than lead them.
Rehearse one failure at a time
Dashboards are not evidence that recovery works. A small failure rehearsal can disable one dependency, expire one credential in a safe environment, saturate a bounded queue, or deploy a deliberately unhealthy revision. The objective is to observe detection, diagnosis, containment, and recovery.
Each rehearsal should produce a concrete improvement: a clearer alert, a safer timeout, a missing correlation field, or a runbook step that did not work as written. This is where resilience stops being configuration and becomes a team capability.
Warning
Azure product behavior and recommendations evolve. This article describes an operational method, not a permanent service-by-service configuration. Pin the environment and verify current platform guidance before applying it.
Operating a .NET service well means connecting code decisions to runtime evidence. Identity, telemetry, deployment, recovery, and cost are not the final chapter after development; they are constraints that shape the service from its first boundary.
Cost anomalies can expose inefficient query shapes, noisy telemetry, runaway retries, oversized compute, or poor cache behavior. Set budgets and alerts before the invoice becomes the monitoring system.
Production engineering is the practice of making behavior visible and change recoverable. Azure supplies mechanisms; the architecture must turn them into a coherent operating model.