Dopo aver visto come sviluppare, osservare e rendere sicura un’applicazione con .NET Aspire, arriviamo all’ultimo passo del ciclo di vita: il deployment.
Distribuire un’applicazione moderna significa molto più che “pubblicare del codice”: bisogna gestire ambienti diversi (sviluppo, test, produzione), garantire configurazioni coerenti e assicurarsi che le risorse esterne siano correttamente collegate.
Aspire nasce per ridurre la distanza tra sviluppo e produzione, permettendo di definire l’intera applicazione in modo dichiarativo e coerente.
Di solito un’applicazione attraversa diversi ambienti:
Il problema comune è che spesso le configurazioni cambiano da un ambiente all’altro, causando errori. Aspire aiuta a mantenere consistenza in tutti gli step.
In fase di sviluppo, il deployment locale avviene tramite l’AppHost, che avvia automaticamente progetti e risorse.
Esempio:
AppHost/Program.cs
var builder = DistributedApplication.CreateBuilder(args);
var db = builder.AddPostgres("postgres")
.AddDatabase("appdb");
builder.AddProject<Projects.MyApi>("api")
.WithReference(db);
builder.AddProject<Projects.MyFrontend>("frontend")
.WithReference("api");
builder.Build().Run();
Con questo approccio:
Il tutto senza configurazioni manuali.
Il vero vantaggio di Aspire emerge quando si passa dal locale al cloud. La stessa definizione usata in sviluppo può essere mappata verso servizi gestiti.
Esempio – passaggio da PostgreSQL locale ad Azure Database for PostgreSQL:
var db = builder.AddPostgres("postgres")
.AddDatabase("appdb")
.WithAzureDatabase("my-azure-db");
In questo caso, Aspire instrada automaticamente la connection string verso l’istanza gestita su Azure, senza modifiche al codice dell’API.
Allo stesso modo, un’API esterna definita in locale può essere sostituita con un endpoint di produzione semplicemente cambiando la configurazione.
Aspire non è un orchestratore, ma produce configurazioni compatibili con container orchestrati come:
La forza di Aspire è che il modello dichiarativo rimane lo stesso: sei libero di scegliere dove distribuire.
Aspire utilizza il modello di configurazione di .NET (appsettings + environment variables), ma estende il concetto aggiungendo deployment profiles.
Esempio – profiles.json
{
"profiles": {
"development": {
"resources": {
"postgres": { "connectionString": "Host=localhost;Port=5432;..." }
}
},
"production": {
"resources": {
"postgres": { "connectionString": "Host=myazuresql.postgres.database.azure.com;..." }
}
}
}
}
In questo modo, puoi passare da locale a cloud con un semplice switch di profilo, mantenendo coerenza tra ambienti.
Un altro vantaggio è che le definizioni Aspire possono essere integrate in pipeline CI/CD (GitHub Actions, Azure DevOps, GitLab).
Esempio – GitHub Actions per deployment:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 9.0.x
- name: Publish Aspire AppHost
run: dotnet publish src/AppHost -c Release
- name: Deploy to Azure
run: az containerapp up --name myapp --resource-group my-rg --image myapp:latest
Così, la pipeline prende il modello Aspire e lo distribuisce direttamente in ambiente cloud.
Quando parliamo di deployment e ambienti, Aspire fornisce vantaggi significativi:
In pratica, Aspire riduce la distanza tra “funziona sul mio PC” e “funziona in produzione”.
Con .NET Aspire, il deployment e la gestione degli ambienti diventano un processo coerente e semplificato. Lo stesso modello dichiarativo che utilizzi in locale si adatta senza modifiche a staging e produzione, garantendo consistenza e riducendo gli errori di configurazione.
Questa filosofia “define once, run anywhere” è ciò che rende Aspire un alleato ideale per lo sviluppo cloud native, portando le applicazioni dal laptop dello sviluppatore al cloud in modo rapido e sicuro.