This repository contains an azd template that uses Aspire as the application orchestrator. The template includes:
- Azure Key Vault for app secrets
- Azure App Configuration for app settings
- Azure Service Bus or RabbitMQ for messaging
- two sample ASP.NET applications that use the above services
The architecture of the template is depicted below:
The template supports both local and hybrid development mode (see below for details).
To enable this, messaging between apps is abstracted using Rebus 🚌.
The bicep template used to provision the Azure resources takes the following parameters:
environmentName: corresponds toAZURE_ENV_NAMEand is set byazdduring environment creationlocation: corresponds toAZURE_LOCATIONand is set byazdinteractively during provisioninghybridEnvironment: corresponds toHYBRID_ENVIRONMENTand must be set manually (can be eithertrueorfalse, the default)principalId: corresponds toAZURE_PRINCIPAL_IDand is set byazdautomatically during provisioning
The principal specified above will be given appropriate permissions to access the provisioned resources, e.g. create secrets in the key vault.
In this mode no resources are provisioned and all apps and services run locally:
- app secrets are stored in the project's user secrets
- app settings are stored in the project's
appsettings.Development.json - a RabbitMQ container, which includes the management portal, is used for messaging between the apps
Create the secrets using the following dotnet commands:
dotnet user-secrets -p .\src\AzdAspire.WebApplication1\AzdAspire.WebApplication1.csproj set "WebApp1:AppKey" "MyAppKey1"
dotnet user-secrets -p .\src\AzdAspire.WebApplication2\AzdAspire.WebApplication2.csproj set "WebApp2:AppKey" "MyAppKey2"
Since no resources need to be provisioned, there are no other pre-requisites to use local development:
- to run the application in Visual Studio, select the Development profile and hit F5
- in VS Code, use:
dotnet run --project .\src\AzdAspire.AppHost\AzdAspire.AppHost.csproj --launch-profile Development
In this mode only a few service resources are provisioned and all apps run locally:
- app secrets are stored in Azure Key Vault
- app settings are stored in Azure App Configuration
- Azure Service Bus is used for messaging between the apps
Hybrid development is enabled as follows:
- create a new
azdenvironment using the commandazd env new <environment>, where<environment>is your chosen environment name - locate the newly created file
.azure\<environment>\.envand append the lineHYBRID_ENVIRONMENT="true" - create the service resources by running
azd provision(you can use the--previewflag to preview the changes without creating any resources) - locate the
Productionprofile in thelaunchSettings.jsonof the Aspire host project - in the above profile, set the
DOTNET_ENVIRONMENTvariable to<environment> - to run the application in Visual Studio, select the Production profile and hit F5
- in VS Code, use:
dotnet run --project .\src\AzdAspire.AppHost\AzdAspire.AppHost.csproj --launch-profile Production
To prove connectivity to Azure Key Vault, the WebApp1:AppKey and WebApp2:AppKey secrets are used.
Similarly, for Azure App Configuration, the WebApp1:AppName and WebApp2:AppName settings are used.
You can create these using the portal or the following az commands:
az keyvault secret set `
--vault-name <keyvault> `
--name WebApp1--AppKey `
--value MyAppKey1 `
--output none
az keyvault secret set `
--vault-name <keyvault> `
--name WebApp2--AppKey `
--value MyAppKey2 `
--output none
az appconfig kv set `
--name <appconfig> `
--key WebApp1:AppName `
--value MyWebApp1 `
--yes `
--output none
az appconfig kv set `
--name <appconfig> `
--key WebApp2:AppName `
--value MyWebApp2 `
--yes `
--output none
In this mode all the required resources are provisioned and all apps and services run in the cloud.
To create a fully provisioned runtime environment, follow these steps:
- download the template with
azd init -t fabio-marini/azd-aspire-basic -b master - login to Azure with
azd auth login - create the service resources by running
azd provision - deploy the applications by running
azd deploy - create the necessary secrets and settings as described in the previous section
Two workflows are provided in .github/workflows/:
Triggered on push or pull request to main or develop.
Steps:
- Restore dependencies
- Build in
Releaseconfiguration - Run tests with XPlat Code Coverage
- Upload test results as a GitHub artifact (retained 7 days)
- Generate an HTML + Cobertura coverage report via ReportGenerator
- Upload the coverage report as a GitHub artifact (retained 7 days)
Triggered manually via workflow_dispatch. Requires an azure-env-name input at run time.
Steps:
- Install
azd - Authenticate to Azure using OIDC federated credentials (no stored client secret)
azd provision— create/update all Azure resourcesazd deploy— build and deploy the application containers
The following repository variables must be configured before running the CD pipeline:
| Variable | Description |
|---|---|
AZURE_CLIENT_ID |
Client ID of the app registration used for OIDC login |
AZURE_TENANT_ID |
Azure AD tenant ID |
AZURE_SUBSCRIPTION_ID |
Target subscription ID |
AZURE_LOCATION |
Azure region (e.g. eastus) |
Run
azd pipeline config -e <environment>to create the app registration and configure federated credentials automatically.
To test that everything is wired up correctly, use the POST /echo endpoint of WebApp1, e.g.
Invoke-WebRequest -Uri https://localhost:7099/echo `
-Method POST `
-Headers @{ "Content-Type" = "application/json" } `
-Body '{ "message": "Hello World! :)" }'
Take a look at the logs for WebApp2 to confirm connectivity to the message bus. They should show that an EchoRequest was received:
Received AzdAspire.ServiceDefaults.EchoRequest with message: Hello World! :) and headers [x-appkey, LocalKey1], [x-appname, LocalApp1]
And the logs for WebApp1 should show that an EchoResponse was received:
Received AzdAspire.ServiceDefaults.EchoResponse with message: Hello World! :) and headers [x-appkey, LocalKey2], [x-appname, LocalApp2]
The messages headers will contain the values of the AppName and AppKey settings and will confirm the connectivity to Key Vault and App config (for hybrid environments).
A Copilot prompt is provided at .github/prompts/rename-projects.prompt.md to help rename all projects in the solution from the default AzdAspire prefix to a custom one.
To use it, open the prompt in VS Code (with the GitHub Copilot extension) and supply the {new-prefix} value. The prompt instructs Copilot to:
- Rename all project files and folders under
src/usinggit mv - Replace all occurrences of
AzdAspirein:.github/copilot-instructions.md.github/workflows/aspire-shell-cd.yml.github/workflows/aspire-shell-ci.ymlazure.yamlREADME.mdAGENTS.md
- Run
dotnet buildto verify the solution still compiles
