diff --git a/.gitignore b/.gitignore index 35c050d2e..2474b601b 100644 --- a/.gitignore +++ b/.gitignore @@ -450,4 +450,5 @@ FodyWeavers.xsd bin/ -obj/ \ No newline at end of file +obj/ +tmp-ts-validation/ diff --git a/src/frontend/config/redirects.mjs b/src/frontend/config/redirects.mjs index e49b51812..bc03b3d8f 100644 --- a/src/frontend/config/redirects.mjs +++ b/src/frontend/config/redirects.mjs @@ -72,4 +72,8 @@ export const redirects = { '/reference/cli/commands/aspire-mcp-start/': '/reference/cli/commands/aspire-agent-mcp/', '/reference/cli/commands/aspire-exec/': '/reference/cli/commands/aspire-resource/', '/get-started/configure-mcp/': '/get-started/ai-coding-agents/', + '/get-started/pipelines/': '/deployment/pipelines/', + '/ja/get-started/pipelines/': '/ja/deployment/pipelines/', + '/deployment/manifest-format/': '/deployment/azure/manifest-format/', + '/fundamentals/app-lifecycle/': '/deployment/app-lifecycle/', }; diff --git a/src/frontend/config/sidebar/deployment.topics.ts b/src/frontend/config/sidebar/deployment.topics.ts index 7e3a39df7..420957320 100644 --- a/src/frontend/config/sidebar/deployment.topics.ts +++ b/src/frontend/config/sidebar/deployment.topics.ts @@ -64,71 +64,16 @@ export const deploymentTopics: StarlightSidebarTopicsUserConfig = { slug: 'deployment/overview', }, { - label: 'Deploy JavaScript apps', - slug: 'deployment/javascript-apps', + label: 'Pipelines (aspire do)', + slug: 'deployment/pipelines', }, { - label: 'Deployment manifest format', - translations: { - da: 'Udrulningsmanifestformat', - de: 'Bereitstellungsmanifestformat', - en: 'Deployment manifest format', - es: 'Formato de manifiesto de despliegue', - fr: 'Format de manifeste de déploiement', - hi: 'तैनाती मैनिफ़ेस्ट प्रारूप', - id: 'Format manifes penyebaran', - it: 'Formato del manifesto di distribuzione', - ja: 'デプロイマニフェスト形式', - ko: '배포 매니페스트 형식', - 'pt-BR': 'Formato de manifesto de implantação', - ru: 'Формат манифеста развертывания', - tr: 'Dağıtım bildirimi biçimi', - uk: 'Формат маніфесту розгортання', - 'zh-CN': '部署清单格式', - }, - slug: 'deployment/manifest-format', - }, - { - label: 'Deployment state caching', - translations: { - da: 'Cachelagring af udrulningstilstand', - de: 'Zwischenspeichern des Bereitstellungsstatus', - en: 'Deployment state caching', - es: 'Almacenamiento en caché del estado de despliegue', - fr: "Mise en cache de l'état de déploiement", - hi: 'तैनाती स्थिति कैशिंग', - id: 'Caching status penyebaran', - it: 'Memorizzazione nella cache dello stato di distribuzione', - ja: 'デプロイ状態のキャッシュ', - ko: '배포 상태 캐싱', - 'pt-BR': 'Cache de estado de implantação', - ru: 'Кэширование состояния развертывания', - tr: 'Dağıtım durumu önbelleğe alma', - uk: 'Кешування стану розгортання', - 'zh-CN': '部署状态缓存', - }, - slug: 'deployment/deployment-state-caching', + label: 'Deploy to Docker Compose', + slug: 'deployment/docker-compose', }, { - label: 'Custom deployment pipelines', - translations: { - da: 'Brugerdefinerede implementeringspipelines', - de: 'Benutzerdefinierte Bereitstellungspipelines', - en: 'Custom deployment pipelines', - es: 'Canalizaciones de despliegue personalizadas', - fr: 'Pipelines de déploiement personnalisés', - hi: 'कस्टम तैनाती पाइपलाइन', - id: 'Pipeline penyebaran kustom', - it: 'Pipeline di distribuzione personalizzate', - ja: 'カスタム デプロイ パイプライン', - ko: '사용자 지정 배포 파이프라인', - 'pt-BR': 'Pipelines de implantação personalizados', - ru: 'Пользовательские конвейеры развертывания', - tr: 'Özel dağıtım işlem hatları', - uk: 'Користувацькі конвеєри розгортання', - 'zh-CN': '自定义部署管道', - }, - slug: 'deployment/custom-deployments', + label: 'Deploy to Kubernetes', + slug: 'deployment/kubernetes', }, { label: 'Deploy to Azure', @@ -172,6 +117,10 @@ export const deploymentTopics: StarlightSidebarTopicsUserConfig = { }, slug: 'deployment/azure/aca-deployment-aspire-cli', }, + { + label: 'Customize Azure Container Apps', + slug: 'deployment/azure/customize-container-apps', + }, { label: 'Azure security best practices', translations: { @@ -193,6 +142,42 @@ export const deploymentTopics: StarlightSidebarTopicsUserConfig = { }, slug: 'deployment/azure/azure-security-best-practices', }, + { + label: 'Azure Developer CLI (azd)', + collapsed: true, + items: [ + { + label: 'Overview', + slug: 'deployment/azure/azure-developer-cli', + }, + { + label: 'Deployment manifest format', + slug: 'deployment/azure/manifest-format', + }, + ], + }, + ], + }, + { + label: 'Deploy JavaScript apps', + slug: 'deployment/javascript-apps', + }, + { + label: 'App lifecycle (CI/CD)', + slug: 'deployment/app-lifecycle', + }, + { + label: 'Advanced', + collapsed: true, + items: [ + { + label: 'Deployment state caching', + slug: 'deployment/deployment-state-caching', + }, + { + label: 'Custom deployment pipelines', + slug: 'deployment/custom-deployments', + }, ], }, ], diff --git a/src/frontend/config/sidebar/docs.topics.ts b/src/frontend/config/sidebar/docs.topics.ts index d221912bc..24ae19551 100644 --- a/src/frontend/config/sidebar/docs.topics.ts +++ b/src/frontend/config/sidebar/docs.topics.ts @@ -529,27 +529,6 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = { }, slug: 'get-started/app-host', }, - { - label: 'Pipelines and app topology', - translations: { - da: 'Udrulning og apptopologi', - de: 'Bereitstellung und App-Topologie', - en: 'Pipelines and app topology', - es: 'Despliegue y topología de la aplicación', - fr: 'Déploiement et topologie de l’application', - hi: 'परिनियोजन और ऐप टोपोलॉजी', - id: 'Penyebaran dan topologi aplikasi', - it: 'Distribuzione e topologia dell’applicazione', - ja: 'パイプラインとアプリのトポロジー', - ko: '배포 및 앱 토폴로지', - 'pt-BR': 'Implantação e topologia do aplicativo', - ru: 'Развертывание и топология приложения', - tr: 'Dağıtım ve uygulama topolojisi', - uk: 'Розгортання і топологія застосунку', - 'zh-CN': '部署与应用拓扑', - }, - slug: 'get-started/pipelines', - }, { label: 'Understanding resources', translations: { @@ -571,27 +550,6 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = { }, slug: 'get-started/resources', }, - { - label: 'Aspire app lifecycle guide', - slug: 'fundamentals/app-lifecycle', - translations: { - da: 'Guide til Aspire app-livscyklus', - de: 'Leitfaden zum Aspire-App-Lebenszyklus', - en: 'Aspire app lifecycle guide', - es: 'Guía del ciclo de vida de la aplicación Aspire', - fr: 'Guide du cycle de vie des applications Aspire', - hi: 'Aspire ऐप जीवनचक्र गाइड', - id: 'Panduan siklus hidup aplikasi Aspire', - it: 'Guida al ciclo di vita delle app Aspire', - ja: 'Aspire アプリのライフサイクル ガイド', - ko: 'Aspire 앱 수명 주기 가이드', - 'pt-BR': 'Guia do ciclo de vida do aplicativo Aspire', - ru: 'Руководство по жизненному циклу приложения Aspire', - tr: 'Aspire uygulama yaşam döngüsü kılavuzu', - uk: 'Посібник з життєвого циклу застосунку Aspire', - 'zh-CN': 'Aspire 应用生命周期指南', - }, - }, { label: 'Glossary', slug: 'get-started/glossary', @@ -1340,4 +1298,4 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = { ], }, ], -}; +}; \ No newline at end of file diff --git a/src/frontend/src/content/docs/app-host/container-registry.mdx b/src/frontend/src/content/docs/app-host/container-registry.mdx index a53dacfa5..b3771a6b6 100644 --- a/src/frontend/src/content/docs/app-host/container-registry.mdx +++ b/src/frontend/src/content/docs/app-host/container-registry.mdx @@ -629,4 +629,4 @@ The explicit container registry configuration introduced in Aspire 13.1 provides - [Configure Azure Container Apps environments](/integrations/cloud/azure/configure-container-apps/) - [`aspire do` command](/reference/cli/commands/aspire-do/) - [External parameters](/fundamentals/external-parameters/) -- [Pipelines and app topology](/get-started/pipelines/) +- [Pipelines and app topology](/deployment/pipelines/) diff --git a/src/frontend/src/content/docs/da/index.mdx b/src/frontend/src/content/docs/da/index.mdx index 8b218cad0..f343300e2 100644 --- a/src/frontend/src/content/docs/da/index.mdx +++ b/src/frontend/src/content/docs/da/index.mdx @@ -97,7 +97,7 @@ import LanguagesSupported from '@components/LanguagesSupported.astro'; ## Lokal-først, produktionsklar -**Bygget til lokal udvikling**, Aspire spejler produktionsmiljøer på din maskine, eliminerer "virker på min maskine" problemer for glatte deployments. [Lær om deployment og app-topologi](/da/get-started/pipelines/). +**Bygget til lokal udvikling**, Aspire spejler produktionsmiljøer på din maskine, eliminerer "virker på min maskine" problemer for glatte deployments. [Lær om deployment og app-topologi](/da/deployment/pipelines/). import LocalVsProdEnvironments from '@components/LocalVsProdEnvironments.astro'; diff --git a/src/frontend/src/content/docs/de/index.mdx b/src/frontend/src/content/docs/de/index.mdx index e7f5d2d85..573c0a082 100644 --- a/src/frontend/src/content/docs/de/index.mdx +++ b/src/frontend/src/content/docs/de/index.mdx @@ -99,7 +99,7 @@ Aspire unterstützt viele Sprachen & Frameworks und lässt dich mit deinen Favor ## Lokal zuerst, produktionsbereit -**Für lokale Entwicklung gebaut**, Aspire spiegelt Produktionsumgebungen auf deiner Maschine und eliminiert „Works on my machine“-Probleme für reibungslose Deployments. [Mehr über Deployment & App-Topologie](/de/get-started/pipelines/). +**Für lokale Entwicklung gebaut**, Aspire spiegelt Produktionsumgebungen auf deiner Maschine und eliminiert „Works on my machine“-Probleme für reibungslose Deployments. [Mehr über Deployment & App-Topologie](/de/deployment/pipelines/). import LocalVsProdEnvironments from '@components/LocalVsProdEnvironments.astro'; diff --git a/src/frontend/src/content/docs/fundamentals/app-lifecycle.mdx b/src/frontend/src/content/docs/deployment/app-lifecycle.mdx similarity index 91% rename from src/frontend/src/content/docs/fundamentals/app-lifecycle.mdx rename to src/frontend/src/content/docs/deployment/app-lifecycle.mdx index 3bc396b78..7bce396d3 100644 --- a/src/frontend/src/content/docs/fundamentals/app-lifecycle.mdx +++ b/src/frontend/src/content/docs/deployment/app-lifecycle.mdx @@ -6,7 +6,7 @@ description: Understand the lifecycle of Aspire applications from development to import { Aside, FileTree, Steps } from '@astrojs/starlight/components'; import LearnMore from '@components/LearnMore.astro'; -This guide provides a high-level overview of the lifecycle phases of an Aspire application, from development through local deployment to production release. By using the same `AppHost` configuration across all phases, you ensure consistency and reduce configuration drift between environments. +This guide provides a high-level overview of the lifecycle phases of an Aspire application, from development through local deployment to production release. By using the same AppHost configuration across all phases, you ensure consistency and reduce configuration drift between environments. The example in this guide demonstrates how Aspire orchestrates containerized applications with persistent storage and CI/CD automation using the [Docker Integration](/integrations/compute/docker/) and GitHub. ## App lifecycle @@ -25,6 +25,8 @@ The Aspire application lifecycle consists of three main phases: ### Example +The following example uses a C# AppHost, but the same lifecycle applies to TypeScript AppHosts. + Consider [this example](https://github.com/BethMassi/VolumeMount/). You have a distributed application that consists of a Blazor web project that relies on a SQL Server database with a persistent data volume as well as a persistent writable file volume to capture user file uploads. You want to distribute your Blazor app as a Docker container image via the GitHub Container Registry. You need the [Aspire.Hosting.Docker](/integrations/compute/docker/) and [Aspire.Hosting.SqlServer](/integrations/databases/sql-server/sql-server-get-started/) integrations. @@ -104,7 +106,7 @@ When you run `aspire run`: 1. **Aspire dashboard launches** - A web-based dashboard starts, and its URL (often an HTTPS login URL like `https://localhost:/login?...`) is printed to the console. -2. **Resources start** - All resources defined in your `AppHost.cs` are orchestrated. +2. **Resources start** - All resources defined in your AppHost are orchestrated. 3. **Live debugging** - You can attach debuggers, set breakpoints, and modify code with hot reload. 4. **Telemetry & logs** - Dashboard provides real-time logs, metrics, and distributed traces. @@ -132,7 +134,7 @@ Dashboard: https://localhost:17244/login?t=9db79f2885dae24ee06c6ef10290b8b2 In the example above, when resources start with the run command: - SQL Server container starts in Docker with persistent volume -- Blazor Web project runs as a .NET process (**not containerized**) +- Web project runs as a local process (**not containerized**) - Database is automatically created and migrated (containerized) ## Phase 2: Local Deployment @@ -193,7 +195,7 @@ In [this example](https://github.com/BethMassi/VolumeMount/blob/main/.github/wor -1. **Setup Environment** - Install .NET +1. **Setup Environment** - Install required SDKs 2. **Install Aspire CLI** - Install the Aspire CLI 3. **Build and Push Container Images** - Build app and push image to GitHub Container Registry with `aspire do push` 4. **Publish Docker Compose Artifacts** - Generate deployment files with `aspire publish` @@ -204,6 +206,7 @@ In [this example](https://github.com/BethMassi/VolumeMount/blob/main/.github/wor #### Step 1: Setup Environment ```yaml +# Required for C# AppHost projects - name: Setup .NET uses: actions/setup-dotnet@v4 with: @@ -241,7 +244,7 @@ Replace `your-org/your-repo` with your actual GitHub organization and repository The `aspire do push` command does the following: -- Analyzes your `AppHost.cs` configuration +- Analyzes your AppHost configuration - Restores dependencies and builds the project - Builds Docker container images for project resources - Tags images with configured registry endpoint and repository @@ -264,8 +267,12 @@ The `aspire do push` command does the following: --output-path ./aspire-output ``` + + The `aspire publish` command does the following: -- Analyzes your `AppHost.cs` configuration +- Analyzes your AppHost configuration - Generates `docker-compose.yaml` file with all service definitions - Creates `.env` template file for environment variables - Packages configuration needed for deployment @@ -329,11 +336,15 @@ After the workflow completes, you have everything needed for production deployme | Phase | Command | Purpose | Environment | App | Database | |-------|---------|---------|-------------|------------|------------| -| **Development** | `aspire run` | Inner-loop coding & debugging | Local machine | App process (i.e. .NET) | Container | +| **Development** | `aspire run` | Inner-loop coding & debugging | Local machine | Local process | Container | | **Local Deploy** | `aspire deploy` | Test containerized app locally | Registered compute environment (i.e. Docker Desktop) | Container | Container | | **Release** | CI/CD workflow (i.e. GitHub Actions) | Publish to staging/ production | Cloud/Server | Container | Container | -The `AppHost.cs` file is the **single source of truth** for your application architecture. Each phase above uses the exact same `AppHost` configuration. This eliminates configuration drift between development and deployment. It defines things your distributed application needs like: + + +The AppHost is the **single source of truth** for your application architecture. Each phase above uses the exact same AppHost configuration. This eliminates configuration drift between development and deployment. It defines things your distributed application needs like: - **Services & Dependencies** - Projects, containers, and their relationships - **Configuration** - Connection strings, secrets, and parameters - **Volumes** - Persistent storage for databases and files diff --git a/src/frontend/src/content/docs/deployment/azure/azure-developer-cli.mdx b/src/frontend/src/content/docs/deployment/azure/azure-developer-cli.mdx new file mode 100644 index 000000000..c17d1bb10 --- /dev/null +++ b/src/frontend/src/content/docs/deployment/azure/azure-developer-cli.mdx @@ -0,0 +1,111 @@ +--- +title: Azure Developer CLI (azd) +description: Learn how to use the Azure Developer CLI as an alternative deployment path for Aspire applications. +--- + +import { Aside, Steps, Tabs, TabItem } from '@astrojs/starlight/components'; + +The Azure Developer CLI (`azd`) is a developer-oriented command-line tool that can provision Azure resources and deploy applications from your local environment or CI/CD pipelines. It integrates with Aspire by consuming the deployment manifest format to understand your app model and automatically provision the corresponding Azure resources. + + + +## When to use azd + +While `aspire deploy` is the recommended path, `azd` remains useful in several scenarios: + +- You have **existing `azd` workflows** and infrastructure templates you want to continue using. +- You need **`azd pipeline config`** for automated CI/CD setup with GitHub Actions or Azure DevOps. +- You want to use **`azd` environment management** features to manage multiple deployment environments. +- You're working with **teams already familiar** with `azd` conventions and tooling. + +## Prerequisites + +- [Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd) installed +- An active Azure subscription — [create one for free](https://azure.microsoft.com/free/) +- [Aspire CLI](/get-started/install-cli/) installed + +## Basic workflow + + + +1. **Initialize your project** — run `azd init` from your AppHost directory. When prompted, select **Use code in the current directory** so `azd` detects the Aspire app model. + + ```bash title="Initialize azd in the AppHost directory" + azd init + ``` + +2. **Provision and deploy** — run `azd up` to provision the required Azure resources and deploy your application in a single step. This combines the `azd provision` and `azd deploy` commands. + + ```bash title="Provision infrastructure and deploy" + azd up + ``` + +3. **Redeploy without reprovisioning** — after the initial deployment, use `azd deploy` to push code changes without reprovisioning infrastructure. + + ```bash title="Deploy updated code" + azd deploy + ``` + + + +## `aspire deploy` vs `azd` comparison + +| Feature | `aspire deploy` | `azd` | +| --------------------------- | --------------- | --------------------- | +| Azure Container Apps | ✅ | ✅ | +| Azure App Service | ✅ | ❌ | +| Infrastructure provisioning | Built-in | Built-in | +| CI/CD pipeline setup | Manual | `azd pipeline config` | +| Environment management | State caching | `azd env` | +| Manifest dependency | No | Yes | + +## Resource naming + +The `aspire deploy` path and `azd` use different resource naming schemes by default. If you're upgrading from an existing `azd` deployment to `aspire deploy`, use `WithAzdResourceNaming()` to preserve the original naming convention. This avoids creating duplicate Azure resources: + + + + +```csharp title="AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +builder.AddAzureContainerAppEnvironment("env") + .WithAzdResourceNaming(); +``` + + + + +```typescript title="apphost.ts" +import { createBuilder } from './.modules/aspire.js'; + +const builder = await createBuilder(); + +const env = await builder.addAzureContainerAppEnvironment('env'); +await env.withAzdResourceNaming(); +``` + + + + +## Deployment manifest + +The `azd` tool relies on the [deployment manifest format](/deployment/azure/manifest-format/) to understand your application topology. The manifest is a JSON document generated from the AppHost that describes resources, bindings, and parameters. It's produced automatically when `azd` invokes the AppHost during deployment. + + + +## See also + +- [Deploy using the Aspire CLI](/deployment/azure/aca-deployment-aspire-cli/) — recommended deployment path +- [Deployment manifest format](/deployment/azure/manifest-format/) +- [Azure Developer CLI documentation](https://learn.microsoft.com/azure/developer/azure-developer-cli/) diff --git a/src/frontend/src/content/docs/deployment/azure/customize-container-apps.mdx b/src/frontend/src/content/docs/deployment/azure/customize-container-apps.mdx new file mode 100644 index 000000000..05afc6cdc --- /dev/null +++ b/src/frontend/src/content/docs/deployment/azure/customize-container-apps.mdx @@ -0,0 +1,229 @@ +--- +title: Customize Azure Container Apps +description: Learn how to customize Azure Container Apps deployments for your Aspire applications. +--- + +import { Aside, Tabs, TabItem } from '@astrojs/starlight/components'; +import LearnMore from '@components/LearnMore.astro'; + +When you deploy to [Azure Container Apps](https://learn.microsoft.com/azure/container-apps/overview) using `aspire deploy`, Aspire provisions infrastructure automatically based on the resources defined in your AppHost. While the defaults work for many scenarios, you often need to customize the generated infrastructure—scaling rules, custom domains, resource groups, role assignments, and more. + +This page covers the most common customization options for Azure Container Apps deployments. For hosting-side configuration of the Container Apps _environment_, see [Configure Azure Container Apps](/integrations/cloud/azure/configure-container-apps/). + +## Customize a Container App with `PublishAsAzureContainerApp` + +Use `PublishAsAzureContainerApp` to customize the generated Container App resource for any project, container, or executable in your AppHost. The callback gives you access to the `AzureResourceInfrastructure` and the `ContainerApp` construct, allowing you to modify any property of the generated resource. + + + + +```csharp title="AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +builder.AddAzureContainerAppEnvironment("env"); + +builder.AddProject("api") + .PublishAsAzureContainerApp((infrastructure, app) => + { + // Customize the Container App + app.Template.Scale.MinReplicas = 1; + app.Template.Scale.MaxReplicas = 10; + }); + +builder.Build().Run(); +``` + + + + +```typescript title="apphost.ts" +import { createBuilder } from './.modules/aspire.js'; + +const builder = await createBuilder(); + +await builder.addAzureContainerAppEnvironment("env"); + +const api = await builder.addProject("api", "../Api/Api.csproj", "http"); +await api.publishAsAzureContainerApp(async (infrastructure, app) => { + // Customize the Container App + // Note: Scaling properties (minReplicas, maxReplicas) are + // configured through the ContainerAppHandle API +}); + +await builder.build().run(); +``` + + + + +The `infrastructure` parameter provides access to the overall Azure resource infrastructure, while the `app` parameter represents the `ContainerApp` construct. You can modify scaling, ingress, environment variables, and other settings directly. + + +For more information, see [Publish as Azure Container App](/integrations/cloud/azure/overview/#publish-as-azure-container-app). + + +## Custom domains + +Use `ConfigureCustomDomain` to set up custom domains on Container Apps. This lets you bind a custom DNS name and a managed certificate to your Container App. + + + + +```csharp title="AppHost.cs" +var customDomain = builder.AddParameter("customDomain"); +var certificateName = builder.AddParameter("certificateName"); + +#pragma warning disable ASPIREACADOMAINS001 +builder.AddProject("api") + .PublishAsAzureContainerApp((infrastructure, app) => + { + ContainerAppExtensions.ConfigureCustomDomain( + app, customDomain, certificateName); + }); +#pragma warning restore ASPIREACADOMAINS001 +``` + + + + +:::note +The `ConfigureCustomDomain` API is not yet available in the TypeScript AppHost SDK. +::: + + + + + + +## Existing Azure resources + +When you have Azure resources that already exist—such as a shared Service Bus namespace or a database server—you can reference them instead of having Aspire provision new ones. Aspire provides three APIs for this: + +- `AsExisting` — use the existing resource in both local development and deployment. +- `RunAsExisting` — use the existing resource during local development only. +- `PublishAsExisting` — use the existing resource during deployment only. + + + + +```csharp title="AppHost.cs" +var existingBusName = builder.AddParameter("existingServiceBusName"); +var existingBusRg = builder.AddParameter("existingServiceBusResourceGroup"); + +var serviceBus = builder.AddAzureServiceBus("messaging") + .PublishAsExisting(existingBusName, existingBusRg); +``` + + + + +```typescript title="apphost.ts" +const existingBusName = builder.addParameter("existingServiceBusName"); +const existingBusRg = builder.addParameter("existingServiceBusResourceGroup"); + +const serviceBus = await builder.addAzureServiceBus("messaging"); +await serviceBus.publishAsExistingFromParameters( + existingBusName, + existingBusRg +); +``` + + + + +When you reference an existing resource, Aspire skips provisioning for that resource and instead configures your application to connect to the specified instance. + + + +## Resource groups + +By default, all Azure resources deploy to the same resource group created by the environment. Use `WithResourceGroup` on the `AzureEnvironmentResource` to set the resource group for the deployment: + + + + +```csharp title="AppHost.cs" +builder.AddAzureEnvironment() + .WithResourceGroup(builder.AddParameter("resourceGroup")); +``` + + + + +:::note +The `WithResourceGroup` API is not yet available in the TypeScript AppHost SDK. +::: + + + + + + +## Role assignments + +Aspire automatically assigns Azure RBAC roles for resources based on how they're referenced. For example, a project that references an Azure Service Bus resource is automatically granted the **Azure Service Bus Data Sender** role. + +To remove the default role assignments for a resource, use `ClearDefaultRoleAssignments`: + + + + +```csharp title="AppHost.cs" +builder.AddAzureServiceBus("messaging") + .ClearDefaultRoleAssignments(); +``` + + + + +```typescript title="apphost.ts" +const serviceBus = await builder.addAzureServiceBus("messaging"); +await serviceBus.clearDefaultRoleAssignments(); +``` + + + + +Custom role assignments can be configured via `ConfigureInfrastructure`. + + +For more information, see [Manage Azure role assignments](/integrations/cloud/azure/role-assignments/). + + +## Service discovery on Azure Container Apps + +Services deployed to Azure Container Apps use internal DNS for service discovery. HTTP and HTTPS endpoints are both available by default for internal communication between container apps. + +To expose an endpoint externally (outside the Container Apps environment), use `WithExternalHttpEndpoints()`: + + + + +```csharp title="AppHost.cs" +builder.AddProject("api") + .WithExternalHttpEndpoints(); +``` + + + + +```typescript title="apphost.ts" +const api = await builder.addProject("api", "../Api/Api.csproj", "http"); +await api.withExternalHttpEndpoints(); +``` + + + + +## See also + +- [Configure Azure Container Apps](/integrations/cloud/azure/configure-container-apps/) +- [Deploy using the Aspire CLI](/deployment/azure/aca-deployment-aspire-cli/) +- [Manage Azure role assignments](/integrations/cloud/azure/role-assignments/) +- [Azure security best practices](/deployment/azure/azure-security-best-practices/) diff --git a/src/frontend/src/content/docs/deployment/manifest-format.mdx b/src/frontend/src/content/docs/deployment/azure/manifest-format.mdx similarity index 97% rename from src/frontend/src/content/docs/deployment/manifest-format.mdx rename to src/frontend/src/content/docs/deployment/azure/manifest-format.mdx index 15ef3e3ff..e53bed33b 100644 --- a/src/frontend/src/content/docs/deployment/manifest-format.mdx +++ b/src/frontend/src/content/docs/deployment/azure/manifest-format.mdx @@ -13,6 +13,10 @@ import placeholderMappingsLight from '@assets/deployment/placeholder-mappings-li The deployment manifest is a JSON-formatted document generated by Aspire to describe your app's resources and their relationships. This manifest is consumed by deployment tools to provision and configure infrastructure in target cloud environments. + + ## Generate the manifest Create a new Aspire project using the following command: @@ -209,7 +213,7 @@ The final segment of the placeholder string (`url` in this case) is generated by ## Resource types -Each resource has a `type` field. When a deployment tool reads the manifest, it should read the type to verify whether it can correctly process the manifest. During the Aspire preview period, all resource types have a `v0` suffix to indicate that they're subject to change. As Aspire approaches release a `v1` suffix will be used to signify that the structure of the manifest for that resource type should be considered stable (subsequent updates increment the version number accordingly). +Each resource has a `type` field. When a deployment tool reads the manifest, it should read the type to verify whether it can correctly process the manifest. All resource types currently use a `v0` suffix. This format is no longer being actively evolved — for new deployments, use `aspire publish` and `aspire deploy` with compute environment integrations instead. ### Common resource fields diff --git a/src/frontend/src/content/docs/deployment/custom-deployments.mdx b/src/frontend/src/content/docs/deployment/custom-deployments.mdx index 82cfa8599..2b8b111de 100644 --- a/src/frontend/src/content/docs/deployment/custom-deployments.mdx +++ b/src/frontend/src/content/docs/deployment/custom-deployments.mdx @@ -17,10 +17,9 @@ During publishing and deployment, the container image builder is available to cr These APIs give you fine-grained control over the image building process and provide real-time feedback to users during lengthy build operations. - + + + For hosting integration setup and configuration, see [Kubernetes + integration](/integrations/compute/kubernetes/). + + +To configure your AppHost for Kubernetes, add a Kubernetes environment with `AddKubernetesEnvironment`: + + + + +```csharp title="AppHost.cs" {3} +var builder = DistributedApplication.CreateBuilder(args); + +var k8s = builder.AddKubernetesEnvironment("k8s"); + +var api = builder.AddProject("api"); + +builder.Build().Run(); +``` + + + + +```typescript title="apphost.ts" {5} +import { createBuilder } from './.modules/aspire.js'; + +const builder = await createBuilder(); + +const k8s = await builder.addKubernetesEnvironment('k8s'); + +const api = await builder.addProject('api', '../MyApi/MyApi.csproj', 'http'); + +await builder.build().run(); +``` + + + + +## Generate Kubernetes artifacts + +To generate Kubernetes deployment artifacts from your Aspire application, run the `aspire publish` command: + +```bash title="Generate Kubernetes artifacts" +aspire publish -o k8s-artifacts +``` + +This command analyzes your application model and produces a complete Helm chart in the specified output directory. The generated chart structure looks like this: + + +- k8s-artifacts/ + - Chart.yaml Chart metadata (name, version, etc.) + - values.yaml Configurable values for the chart + - templates/ + - \/ + - deployment.yaml Deployment or StatefulSet + - service.yaml Service for connectivity + - configmap.yaml Configuration data + - secret.yaml Sensitive data + + +The publisher generates the following Kubernetes resources from your application model: + +- **Deployments** or **StatefulSets** for your application services +- **Services** for network connectivity between resources +- **ConfigMaps** for application configuration and connection strings +- **Secrets** for sensitive data such as passwords and connection strings +- **Dockerfiles** copied into the output directory for container build contexts + +## Deploy with Helm + +After generating artifacts, use Helm to deploy your application to a Kubernetes cluster: + + + +1. Install the chart to your cluster: + + ```bash title="Install with Helm" + helm install my-app ./k8s-artifacts + ``` + +2. For subsequent deployments, upgrade the existing release: + + ```bash title="Upgrade with Helm" + helm upgrade my-app ./k8s-artifacts + ``` + +3. Override default values using `--set` flags or a custom values file: + + ```bash title="Override values" + helm upgrade my-app ./k8s-artifacts \ + --set api.image.repository=myregistry.azurecr.io/api \ + --set api.image.tag=v1.2.0 + ``` + + Alternatively, create a custom values file for your environment: + + ```yaml title="values.production.yaml" + api: + image: + repository: myregistry.azurecr.io/api + tag: v1.2.0 + ``` + + ```bash title="Deploy with custom values file" + helm upgrade my-app ./k8s-artifacts -f values.production.yaml + ``` + + + +## Supported resource mappings + +The Kubernetes publisher converts Aspire resources to their Kubernetes equivalents: + +| Aspire resource | Kubernetes resource | +| --------------------- | -------------------------------------------- | +| Project resources | Deployments or StatefulSets | +| Container resources | Deployments or StatefulSets | +| Connection strings | ConfigMaps and Secrets | +| Environment variables | ConfigMaps and Secrets | +| Endpoints | Services | +| Volumes | PersistentVolumes and PersistentVolumeClaims | + +## Deployment considerations + +### Container images + +The publisher generates parameterized Helm values for container image references. If you haven't specified custom container images, the generated `values.yaml` contains placeholders that you override at deployment time using `--set` or a custom values file. + +### Resource names + +Resource names in Kubernetes must follow DNS naming conventions. The integration automatically normalizes Aspire resource names by: + +- Converting to lowercase +- Replacing invalid characters with hyphens +- Ensuring names don't start or end with hyphens + +### Environment-specific configuration + +Use [external parameters](/fundamentals/external-parameters/) to configure values that differ between development and production environments. + +### Helm chart name + +By default, the Helm chart name is derived from your AppHost project. Configure a custom chart name using `WithProperties`: + + + + +```csharp title="AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +builder.AddKubernetesEnvironment("k8s") + .WithProperties(k8s => + { + k8s.HelmChartName = "my-aspire-app"; + }); +``` + + + + +```typescript title="apphost.ts" +import { createBuilder } from './.modules/aspire.js'; + +const builder = await createBuilder(); + +const k8s = await builder.addKubernetesEnvironment('k8s'); +await k8s.withProperties(async (k8s) => { + await k8s.helmChartName.set('my-aspire-app'); +}); +``` + + + + +## Customize Kubernetes services + +Use the `PublishAsKubernetesService` callback to modify the generated Kubernetes resources for individual services. This provides fully typed access to the Kubernetes object model: + + + + +```csharp title="AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +builder.AddContainer("service", "nginx") + .WithEnvironment("ORIGINAL_ENV", "value") + .PublishAsKubernetesService(resource => + { + // Customize the generated Kubernetes resource + }); +``` + + + + +```typescript title="apphost.ts" +import { createBuilder } from './.modules/aspire.js'; + +const builder = await createBuilder(); + +const service = await builder.addContainer('service', 'nginx'); +await service.withEnvironment('ORIGINAL_ENV', 'value'); +await service.publishAsKubernetesService(async (resource) => { + // Customize the generated Kubernetes resource +}); +``` + + + + + + +## Troubleshooting + +### Connection strings empty in Kubernetes + +If your application can't find connection strings at runtime, verify that the generated ConfigMaps and Secrets are correctly mounted as environment variables in your pod specifications. Check that the resource names in your Helm values match the expected connection string names. + +### Password and authentication issues + +Kubernetes Secrets store values as base64-encoded strings. Verify that your Secrets are properly encoded and that the generated templates reference them correctly. Use `kubectl get secret -o yaml` to inspect Secret contents. + +### Service discovery + +In Kubernetes, services discover each other using the cluster's built-in DNS. A service named `api` is reachable at `api..svc.cluster.local`. The generated Helm charts configure service references automatically using Kubernetes-native DNS resolution. + +## See also + +- [Kubernetes integration](/integrations/compute/kubernetes/) +- [Pipelines and app topology](/deployment/pipelines/) +- [Publishing and deployment overview](/deployment/overview/) +- [Kubernetes documentation](https://kubernetes.io/docs/) +- [Helm documentation](https://helm.sh/docs/) diff --git a/src/frontend/src/content/docs/deployment/overview.mdx b/src/frontend/src/content/docs/deployment/overview.mdx index cec47f6a9..2e1c2eed1 100644 --- a/src/frontend/src/content/docs/deployment/overview.mdx +++ b/src/frontend/src/content/docs/deployment/overview.mdx @@ -134,10 +134,10 @@ This example shows how you could explicitly map services to different compute en | Integration | Target | Publish | Deploy | Notes | |---------------------|--------|---------|--------|-------| -| [📦 Aspire.Hosting.Docker](/integrations/compute/docker/) | Docker / Docker Compose | ✅ Yes | 🧪 Preview | Use generated Compose with your own scripts or tooling. | -| [📦 Aspire.Hosting.Kubernetes](/integrations/compute/kubernetes/) | Kubernetes | ✅ Yes | 🧪 Preview | Apply with `kubectl`, GitOps, or other controllers. | -| [📦 Aspire.Hosting.Azure.AppContainers](/integrations/cloud/azure/configure-container-apps/) | Azure Container Apps | ✅ Yes | ✅ Yes (Preview) | Deploy capability is in Preview and may change. | -| [📦 Aspire.Hosting.Azure.AppService](/integrations/cloud/azure/azure-app-service/azure-app-service-get-started/) | Azure App Service | ✅ Yes | ✅ Yes (Preview) | Deploy capability is in Preview and may change. | +| [📦 Aspire.Hosting.Docker](/integrations/compute/docker/) | Docker / Docker Compose | ✅ Yes | ✅ Yes | Use generated Compose with your own scripts or tooling. | +| [📦 Aspire.Hosting.Kubernetes](/integrations/compute/kubernetes/) | Kubernetes | ✅ Yes | ❌ No | Apply with `kubectl`, GitOps, or other controllers. | +| [📦 Aspire.Hosting.Azure.AppContainers](/integrations/cloud/azure/configure-container-apps/) | Azure Container Apps | ✅ Yes | ✅ Yes | Full publish and deploy support via `aspire deploy`. | +| [📦 Aspire.Hosting.Azure.AppService](/integrations/cloud/azure/azure-app-service/azure-app-service-get-started/) | Azure App Service | ✅ Yes | ✅ Yes | Full publish and deploy support via `aspire deploy`. |