A deployment pipeline automates the path from a code change to a deployed Aspire application. It can start on a commit or pull request, check dependencies and code quality, build the solution, run tests, and deploy to a chosen environment. Automating these steps avoids relying on someone to run deployment scripts by hand. section 9.6 section 9.5.2
For an Azure Container Apps deployment, start with a generated pipeline and then tighten it:
- Run `azd init` in the Aspire host project directory and `azd login`. An optional `azd up` checks that deployment to Azure works before CI/CD is involved. section 9.6
- Generate a GitHub Actions workflow with `azd pipeline config --provider github`, or an Azure DevOps pipeline with `azd pipeline config --provider azdo`. Both produce YAML that can be edited. section 9.6.1 section 9.6.2
- Add automated tests before deployment. The default generated GitHub Actions pipeline builds and deploys but does not run them; a failed test should stop the build until the change is fixed. section 9.6.1
- Keep environment-specific values in environment variables, but pass values needed by the deployed application explicitly through `azd env set`. Pipeline variables are not passed into Bicep templates or the application automatically. section 9.6.1
A generated workflow is a starting point, not a restriction. GitHub Actions can use separate YAML files for development, test, staging, or production. Azure DevOps can also run a pipeline for a repository hosted elsewhere, although connecting that repository requires additional manual configuration. If provisioning fails, adding `--debug` to `azd provision` helps investigate it. section 9.6.1 section 9.6.2
Listing 9.2 GitHub Actions pipeline with tests
on:
workflow_dispatch:
push:
# Run when commits are pushed to mainline branch (main or master)
# Set this to the mainline branch you are using
branches:
- main
permissions:
id-token: write
contents: read
jobs:
build:
runs-on: ubuntu-latest
env:
AZURE_CLIENT_ID: ${{ vars.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ vars.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ vars.AZURE_SUBSCRIPTION_ID }}
AZURE_ENV_NAME: ${{ vars.AZURE_ENV_NAME }}
AZURE_LOCATION: ${{ vars.AZURE_LOCATION }}
steps:
- name: Checkout
uses: actions/checkout@v4
# Make sure the right .NET SDK is available
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x' #1
- name: Install azd
uses: Azure/setup-azd@v1.0.0
- name: Install .NET Aspire workload
run: dotnet workload install aspire
# ---------- CI: build & test ----------
- name: Restore
run: dotnet restore ./AspireApp.sln #2
- name: Build
run: dotnet build ./AspireApp.sln --configuration Release --no-restore #3
- name: Test
run: dotnet test ./AspireApp.sln --configuration Release --no-build #4
# If tests fail here, the job stops and nothing below runs
# --------------------------------------
- name: Log in with Azure (Federated Credentials)
run: |
azd auth login `
--client-id "$Env:AZURE_CLIENT_ID" `
--federated-credential-provider "github" `
--tenant-id "$Env:AZURE_TENANT_ID"
shell: pwsh
- name: Provision Infrastructure
run: azd provision --no-prompt
env:
AZD_INITIAL_ENVIRONMENT_CONFIG: ${{ secrets.AZD_INITIAL_ENVIRONMENT_CONFIG }}
- name: Deploy Application
run: azd deploy --no-prompt
Compare the GitHub Actions workflow with tests against the generated build-and-deploy pipeline: tests become a gate before a change is deployed. section 9.6.1
For Kubernetes, retain the scaffolded pipeline structure and replace the deployment steps manually. The GitHub Actions and Azure DevOps examples install the .NET SDK, Aspire workload, and Aspirate CLI before restoring and building. The resulting deployment workflow can automate applying the generated Kubernetes configuration instead of running `kubectl apply -k .` by hand. section 9.6.3 section 9.5.2





























