Where are you deploying your .NET applications?
One of the popular choices is Azure.
However, deploying your .NET application to Azure can be a bit challenging.
That's exactly why .NET Aspire was created - to simplify both local development and deployment to Azure.
Today I will show you how to deploy your .NET Web API application to Azure using .NET Aspire.
For the database, we will be using a Neon Serverless Postgres, which you can set up in less than a minute for free.
Let's dive in!
On my website: antondevtips.com I share .NET and Architecture best practices.
Subscribe to advance your career in .NET.
Download the source code for this blog post for free.
Prerequisites
Before we start, ensure you have the following:
- Azure Subscription: An active Azure account to create and manage your resources.
- Neon Postgres Account: Sign up and set up your Neon Postgres instance, you can start for free.
Note: if you don't have an Azure account and don't plan to create one - you can still run all the code locally on your machine and deploy it using Docker Compose or another instrument of your choice.
Step 1: Setting Up the .NET Application
I have built a Products API web application that has the following entities:
- User
- Product
- ProductCart
- ProductCartItem
This application lets you manage products and create a shopping cart with multiple items.
Let's explore our API endpoints to create, update and delete a product cart for the online store:
app.MapPost("/product-carts", async (ProductCartRequest request, IProductCartService productCartService) =>
{
var response = await productCartService.AddAsync(request);
return Results.Created($"/product-carts/{response.Id}", response);
});
app.MapPut("/product-carts/{cartId:guid}", async (Guid cartId, ProductCartRequest request, IProductCartService productCartService) =>
{
var existingProductCart = await productCartService.GetByIdAsync(cartId);
if (existingProductCart is null)
{
return Results.NotFound($"ProductCart with ID {cartId} not found.");
}
if (existingProductCart.UserId != request.UserId)
{
return Results.BadRequest("Cannot update a ProductCart with a different UserId.");
}
await productCartService.UpdateAsync(cartId, request);
return Results.NoContent();
});
app.MapDelete("/product-carts/{cartId:guid}", async (Guid cartId, IProductCartService productCartService) =>
{
await productCartService.DeleteByIdAsync(cartId);
return Results.NoContent();
});
For database access, I use EF Core, and here is how I register the DbContext:
var connectionString = configuration.GetConnectionString("Postgres");
builder.Services.AddDbContext<ApplicationDbContext>((_, options) =>
{
options
.UseNpgsql(connectionString, npgsqlOptions =>
{
npgsqlOptions.MigrationsHistoryTable(DatabaseConsts.MigrationHistoryTable, DatabaseConsts.Schema);
});
options.UseSnakeCaseNamingConvention();
});
Step 2: Adding .NET Aspire Support
.NET Aspire makes it super easy to run your application locally and further deploy it to Azure.
Depending on your IDE, there are a couple of options:
Visual Studio:
- Right-click on your Web Application project and select "Add .NET Aspire Orchestrator Support".
- This creates two new projects: Aspire App Host and ServiceDefaults.
JetBrains Rider:
- Manually create two projects: Aspire App Host and ServiceDefaults
Here is how our solution looks like (I am using Rider):
If you're using Rider or prefer manual setup, follow these steps:
- Add references:
- In
ProductService.Host
(our WebApplication) project add reference toServiceDefaults
project. - In
AspireHost
project add reference toProductService.Host
project.
- Register Aspire Services in
ProductService.Host
project:
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
// Register other dependencies ...
- Map Default Endpoints in
ProductService.Host
project:
var app = builder.Build();
app.MapDefaultEndpoints();
// Map other endpoints ...
- Modify
AspireHost
Program.cs:
using Projects;
var builder = DistributedApplication.CreateBuilder(args);
var connectionString = builder.AddConnectionString("Postgres");
builder.AddProject<ProductService_Host>("product-service")
.WithExternalHttpEndpoints()
.WithReference(connectionString);
builder.Build().Run();
Here we register our WebApplication project called "product-service" and a connection string to it.
You need to add this connection string to the Aspire Host Project in the appsettings.json
file:
{
"ConnectionStrings": {
"Postgres": "*****"
}
}
Step 3: Connecting Application to Neon Serverless Postgres
Neon is a serverless Postgres database designed to help you build reliable and scalable applications faster.
When I observed Neon postgres for the first time, I was really impressed how easy it is to set up a database there, and it's free.
It offers the following features:
- Scalability: instant provisioning, autoscaling and scale to zero.
- Instant Provisioning: no waiting, no config.
- Branching: you can create a full database copy in seconds, like you can create a branch in GIT.
The most exciting part for .NET developers - Neon integrates into the .NET ecosystem within seconds.
All you need is to setup a Neon database and get a connection string.
Step 1: Create your free account in Neon.
Step 2: Create your first database
Step 3: Here is how you can manage your database schema and tables
Step 4: Get the connection string to Neon
For testing purposes, I run EF migrations on application startup (you may consider another option for Production):
using (var scope = app.Services.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
await dbContext.Database.MigrateAsync();
await DatabaseSeedService.SeedAsync(dbContext);
}
await app.RunAsync();
That's all we need to do. Let's run our application.
Step 4: Running .NET Aspire Application Locally
- In your IDE, launch the Aspire Host Project. You will see a dashboard:
- Verify Your Database: Log in to the Neon console to confirm your database is migrated and seeded with data.
- Test your API. You can use Swagger locally (I have added it manually to my .NET 9 project) or send requests from HTTP Request files (you can find them in the source code).
Once everything works locally, you're ready for deployment to Azure.
Step 5: Deploying .NET Aspire Application to Azure
With Aspire, it has never been easier to deploy our application to Azure.
Follow these steps:
1. Create an Azure Profile: Sign up at Azure.
2. Install Azure Developer CLI (azd):
On Windows execute the following command:
winget install microsoft.azd
For other OS, check the documentation.
3. Authenticate with Azure:
azd auth login
4. Init Azure configuration for the project:
Navigate to the solution folder and execute the command:
azd init
4. Provision and Deploy:
Navigate to the solution folder and execute the command to begin provisioning and deployment:
azd up
This command provisions and deploys your application. Follow the prompts (select “use code in the current directory” and provide a resource group name), then wait for the deployment to finish.
5. Verify on Azure: Once deployed, check the Azure Portal to see your containers running.
6. Test the API: Use Postman or your preferred tool to send a request (e.g., get a product cart) and confirm everything works.
Our mission is accomplished, as we have deployed an application to Azure, that connects to Neon Postgres database.
Bonus: Deploying Neon Natively to Azure
You can also deploy Neon Serverless Postgres as a native Azure container.
Simply find "Neon Serverless Postgres" in the Azure Marketplace, select the free subscription option, set up your database, and update your connection string.
You can even connect to your Neon Azure database via the Neon Cloud!
Summary
In this post, we covered everything from setting up your .NET Web API application, integrating .NET Aspire for easy deployments, and connecting to a Neon Serverless Postgres database.
We walked through:
- Setting up the Products API application.
- Adding and configuring .NET Aspire support.
- Setting up a Neon Postgres database and connecting it to your application.
- Running your application locally and deploying it to Azure using the Azure CLI.
With .NET Aspire and Neon, you can focus more on building great features and less on deployment hassles.
On my website: antondevtips.com I share .NET and Architecture best practices.
Subscribe to advance your career in .NET.
Download the source code for this blog post for free.
Top comments (0)