diff --git a/docs/database/oracle-entity-framework-integration.md b/docs/database/oracle-entity-framework-integration.md index ba1f15e319..5f4a211fb5 100644 --- a/docs/database/oracle-entity-framework-integration.md +++ b/docs/database/oracle-entity-framework-integration.md @@ -1,27 +1,30 @@ --- -title: Oracle Entity Framework Component -description: Oracle Entity Framework Component -ms.date: 08/12/2024 +title: .NET Aspire Oracle Entity Framework Core integration +description: Learn how to use the .NET Aspire Oracle Entity Framework Core integration, which includes both hosting and client integrations. +ms.date: 01/21/2025 +uid: database/oracle-entity-framework-integration --- -# .NET Aspire Oracle Entity Framework Component +# .NET Aspire Oracle Entity Framework Core integration -In this article, you learn how to use the .NET Aspire Oracle Entity Framework Core integration. The `Aspire.Oracle.EntityFrameworkCore` library is used to register a as a singleton in the DI container for connecting to Oracle databases. It also enables connection pooling, retries, health checks, logging and telemetry. +[!INCLUDE [includes-hosting-and-client](../includes/includes-hosting-and-client.md)] -## Get started +[Oracle Database](https://www.oracle.com/database/technologies/) is a widely-used relational database management system owned and developed by Oracle. The .NET Aspire Oracle Entity Framework Core integration enables you to connect to existing Oracle servers or create new servers from .NET with the [container-registry.orcale.com/databse/free](https://container-registry.oracle.com/ords/f?p=113:4:5999388133692:::RP,4:P4_REPOSITORY,AI_REPOSITORY,P4_REPOSITORY_NAME,AI_REPOSITORY_NAME:1863,1863,Oracle%20Database%20Free,Oracle%20Database%20Free&cs=3L7x5hgm9Co0WJN-3xZTrFJkDyCZKiS8wlK1jg7nU2yE65gVGYh4WbMLzmX59tAHoLwbwWeAz-kjraRQzB1V5TA) container image. -You need an Oracle database and connection string for accessing the database. To get started with the .NET Aspire Oracle Entity Framework Core integration, install the [📦 Aspire.Oracle.EntityFrameworkCore](https://www.nuget.org/packages/Aspire.Oracle.EntityFrameworkCore) NuGet package in the consuming client project. +## Hosting integration + +The .NET Aspire Oracle hosting integration models the server as the type and the database as the type. To access these types and APIs, add the [📦 Aspire.Hosting.Oracle](https://www.nuget.org/packages/Aspire.Hosting.Oracle) NuGet package in the [app host](xref:dotnet/aspire/app-host) project. ### [.NET CLI](#tab/dotnet-cli) ```dotnetcli -dotnet add package Aspire.Oracle.EntityFrameworkCore +dotnet add package Aspire.Hosting.Oracle ``` ### [PackageReference](#tab/package-reference) ```xml - ``` @@ -29,97 +32,193 @@ dotnet add package Aspire.Oracle.EntityFrameworkCore For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies). -## Example usage +### Add Oracle server and database resources -In the _:::no-loc text="Program.cs":::_ file of your client-consuming project, call the extension to register a for use via the dependency injection container. +In your app host project, call to add and return an Oracle server resource builder. Chain a call to the returned resource builder to , to add an Oracle database to the server resource: ```csharp -builder.AddOracleDatabaseDbContext("oracledb"); +var builder = DistributedApplication.CreateBuilder(args); + +var oracle = builder.AddOracle("oracle") + .WithLifetime(ContainerLifetime.Persistent); + +var oracledb = oracle.AddDatabase("oracledb"); + +builder.AddProject() + .WithReference(oracledb); + .WaitFor(oracledb); + +// After adding all resources, run the app... ``` -You can then retrieve the instance using dependency injection. For example, to retrieve the client from a service: +> [!NOTE] +> The Oracle database container can be slow to start, so it's best to use a _persistent_ lifetime to avoid unnecessary restarts. For more information, see [Container resource lifetime](../fundamentals/app-host-overview.md#container-resource-lifetime). + +When .NET Aspire adds a container image to the app host, as shown in the preceding example with the `container-registry.oracle.com/database/free` image, it creates a new Oracle server on your local machine. A reference to your Oracle resource builder (the `oracle` variable) is used to add a database. The database is named `oracledb` and then added to the `ExampleProject`. The Oracle resource includes a random `password` generated using the method. + +The method configures a connection in the `ExampleProject` named `"oracledb"`. For more information, see [Container resource lifecycle](../fundamentals/app-host-overview.md#container-resource-lifecycle). + +> [!TIP] +> If you'd rather connect to an existing Oracle server, call instead. For more information, see [Reference existing resources](../fundamentals/app-host-overview.md#reference-existing-resources). + +### Add Oracle resource with password parameter + +The Oracle resource includes default credentials with a random password. Oracle supports configuration-based default passwords by using the environment variable `ORACLE_PWD`. When you want to provide a password explicitly, you can provide it as a parameter: ```csharp -public class ExampleService(MyDbContext context) +var password = builder.AddParameter("password", secret: true); + +var oracle = builder.AddOracle("oracle", password) + .WithLifetime(ContainerLifetime.Persistent); + +var oracledb = oracle.AddDatabase("oracledb"); + +var myService = builder.AddProject() + .WithReference(oracledb) + .WaitFor(oracledb); +``` + +The preceding code gets a parameter to pass to the `AddOracle` API, and internally assigns the parameter to the `ORACLE_PWD` environment variable of the Oracle container. The `password` parameter is usually specified as a _user secret_: + +```json { - // Use context... + "Parameters": { + "password": "Non-default-P@ssw0rd" + } } ``` -You might also need to configure specific options of Oracle database, or register a `DbContext` in other ways. In this case call the `EnrichOracleDatabaseDbContext` extension method, for example: +For more information, see [External parameters](../fundamentals/external-parameters.md). + +### Add Oracle resource with data volume + +To add a data volume to the Oracle resource, call the method: ```csharp -var connectionString = builder.Configuration.GetConnectionString("oracledb"); +var builder = DistributedApplication.CreateBuilder(args); + +var oracle = builder.AddOracle("oracle") + .WithDataVolume() + .WithLifetime(ContainerLifetime.Persistent); + +var oracledb = oracle.AddDatabase("oracle"); -builder.Services.AddDbContextPool( - dbContextOptionsBuilder => dbContextOptionsBuilder.UseOracle(connectionString)); +builder.AddProject() + .WithReference(oracledb) + .WaitFor(oracledb); -builder.EnrichOracleDatabaseDbContext(); +// After adding all resources, run the app... ``` -## App host usage +The data volume is used to persist the Oracle data outside the lifecycle of its container. The data volume is mounted at the `/opt/oracle/oradata` path in the Oracle container and when a `name` parameter isn't provided, the name is generated at random. For more information on data volumes and details on why they're preferred over [bind mounts](#add-oracle-resource-with-data-bind-mount), see [Docker docs: Volumes](https://docs.docker.com/engine/storage/volumes). -To model the Oracle server resource in the app host, install the [📦 Aspire.Hosting.Oracle](https://www.nuget.org/packages/Aspire.Hosting.Oracle) NuGet package in the [app host](xref:dotnet/aspire/app-host) project. +> [!WARNING] +> The password is stored in the data volume. When using a data volume and if the password changes, it will not work until you delete the volume. + +### Add Oracle resource with data bind mount + +To add a data bind mount to the Oracle resource, call the method: + +```csharp +var builder = DistributedApplication.CreateBuilder(args); + +var oracle = builder.AddOracle("oracle") + .WithDataBindMount(source: @"C:\Oracle\Data"); + +var oracledb = oracle.AddDatabase("oracledb"); + +builder.AddProject() + .WithReference(oracledb) + .WaitFor(oracledb); + +// After adding all resources, run the app... +``` + +[!INCLUDE [data-bind-mount-vs-volumes](../includes/data-bind-mount-vs-volumes.md)] + +Data bind mounts rely on the host machine's filesystem to persist the Oracle data across container restarts. The data bind mount is mounted at the `C:\Oracle\Data` on Windows (or `/Oracle/Data` on Unix) path on the host machine in the Oracle container. For more information on data bind mounts, see [Docker docs: Bind mounts](https://docs.docker.com/engine/storage/bind-mounts). + +### Hosting integration health checks + +The Oracle hosting integration automatically adds a health check for the Oracle resource. The health check verifies that the Oracle server is running and that a connection can be established to it. + +The hosting integration relies on the [📦 AspNetCore.HealthChecks.Oracle](https://www.nuget.org/packages/AspNetCore.HealthChecks.Oracle) NuGet package. + +## Client integration + +You need an Oracle database and connection string for accessing the database. To get started with the .NET Aspire Oracle client integration, install the [📦 Aspire.Oracle.EntityFrameworkCore](https://www.nuget.org/packages/Aspire.Microsoft.Data.SqlClient) NuGet package in the client-consuming project, that is, the project for the application that uses the Oracle client. The Oracle client integration registers a instance that you can use to interact with Oracle. ### [.NET CLI](#tab/dotnet-cli) ```dotnetcli -dotnet add package Aspire.Hosting.Oracle +dotnet add package Aspire.Oracle.EntityFrameworkCore ``` ### [PackageReference](#tab/package-reference) ```xml - ``` --- -In your app host project, register an Oracle container and consume the connection using the following methods: +### Add Oracle client + +In the _:::no-loc text="Program.cs":::_ file of your client-consuming project, call the extension method on any to register a `DbContext` for use via the dependency injection container. The method takes a connection name parameter. ```csharp -var builder = DistributedApplication.CreateBuilder(args); +builder.AddOracleDatabaseDbContext(connectionName: "oracledb"); +``` -var oracle = builder.AddOracle("oracle"); -var oracledb = oracle.AddDatabase("oracledb"); +> [!TIP] +> The `connectionName` parameter must match the name used when adding the Oracle database resource in the app host project. In other words, when you call `AddDatabase` and provide a name of `oracledb` that same name should be used when calling `AddOracleDatabaseDbContext`. For more information, see [Add Oracle server and database resources](#add-oracle-server-and-database-resources). -var myService = builder.AddProject() - .WithReference(oracledb); +You can then retrieve the instance using dependency injection. For example, to retrieve the connection from an example service: + +```csharp +public class ExampleService(ExampleDbContext context) +{ + // Use database context... +} ``` -When you want to explicitly provide a password, you can provide it as a parameter. Consider the following alternative example: +For more information on dependency injection, see [.NET dependency injection](/dotnet/core/extensions/dependency-injection). -```csharp -var password = builder.AddParameter("password", secret: true); +### Add Oracle database context with enrichment -var oracle = builder.AddOracle("oracle", password); -var oracledb = oracle.AddDatabase("oracledb"); +To enrich the `DbContext` with additional services, such as automatic retries, health checks, logging and telemetry, call the method: -var myService = builder.AddProject() - .WithReference(oracledb); +```csharp +builder.EnrichOracleDatabaseDbContext( + connectionName: "oracledb", + configureSettings: settings => + { + settings.DisableRetry = false; + settings.CommandTimeout = 30 // seconds + }); ``` -For more information, see [External parameters](../fundamentals/external-parameters.md). +The `settings` parameter is an instance of the class. -## Configuration +### Configuration -The .NET Aspire Oracle Entity Framework Core integration provides multiple options to configure the database connection based on the requirements and conventions of your project. +The .NET Aspire Oracle Entity Framework Core integration provides multiple configuration approaches and options to meet the requirements and conventions of your project. -### Use a connection string +#### Use a connection string -When using a connection string from the `ConnectionStrings` configuration section, you can provide the name of the connection string when calling `builder.AddOracleDatabaseDbContext()`: +When using a connection string from the `ConnectionStrings` configuration section, you provide the name of the connection string when calling `builder.AddOracleDatabaseDbContext()`: ```csharp -builder.AddOracleDatabaseDbContext("myConnection"); +builder.AddOracleDatabaseDbContext("oracleConnection"); ``` -And then the connection string will be retrieved from the `ConnectionStrings` configuration section: +The connection string is retrieved from the `ConnectionStrings` configuration section: ```json { "ConnectionStrings": { - "myConnection": "Data Source=TORCL;User Id=myUsername;Password=myPassword;" + "oracleConnection": "Data Source=TORCL;User Id=OracleUser;Password=Non-default-P@ssw0rd;" } } ``` @@ -128,11 +227,11 @@ The `EnrichOracleDatabaseDbContext` won't make use of the `ConnectionStrings` co For more information, see the [ODP.NET documentation](https://www.oracle.com/database/technologies/appdev/dotnet/odp.html). -### Use configuration providers +#### Use configuration providers -The .NET Aspire Oracle Entity Framework Core integration supports [Microsoft.Extensions.Configuration](/dotnet/api/microsoft.extensions.configuration). It loads the `OracleEntityFrameworkCoreSettings` from configuration by using the `Aspire:Oracle:EntityFrameworkCore` key. +The .NET Aspire Oracle Entity Framework Core integration supports from configuration files such as _:::no-loc text="appsettings.json":::_ by using the `Aspire:Oracle:EntityFrameworkCore` key. If you have set up your configurations in the `Aspire:Oracle:EntityFrameworkCore` section you can just call the method without passing any parameter. -The following example shows an _:::no-loc text="appsettings.json":::_ that configures some of the available options: +The following is an example of an _:::no-loc text="appsettings.json":::_ that configures some of the available options: ```json { @@ -141,9 +240,8 @@ The following example shows an _:::no-loc text="appsettings.json":::_ that confi "EntityFrameworkCore": { "DisableHealthChecks": true, "DisableTracing": true, - "DisableMetrics": false, "DisableRetry": false, - "Timeout": 30 + "CommandTimeout": 30 } } } @@ -151,14 +249,14 @@ The following example shows an _:::no-loc text="appsettings.json":::_ that confi ``` > [!TIP] -> The `Timeout` property is in seconds. When set as shown in the preceding example, the timeout is 30 seconds. +> The `CommandTimeout` property is in seconds. When set as shown in the preceding example, the timeout is 30 seconds. -### Use inline delegates +#### Use inline delegates -You can also pass the `Action configureSettings` delegate to set up some or all the options inline, for example to disable health checks from code: +You can also pass the `Action` delegate to set up some or all the options inline, for example to disable health checks from code: ```csharp -builder.AddOracleDatabaseDbContext( +builder.AddOracleDatabaseDbContext( "oracle", static settings => settings.DisableHealthChecks = true); ``` @@ -166,32 +264,53 @@ builder.AddOracleDatabaseDbContext( or ```csharp -builder.EnrichOracleDatabaseDbContext( +builder.EnrichOracleDatabaseDbContext( static settings => settings.DisableHealthChecks = true); ``` +#### Configuration options + +Here are the configurable options with corresponding default values: + +| Name | Description | +|-----------------------|--------------------------------------------------------------------------------------| +| `ConnectionString` | The connection string of the Oracle database to connect to. | +| `DisableHealthChecks` | A boolean value that indicates whether the database health check is disabled or not. | +| `DisableTracing` | A boolean value that indicates whether the OpenTelemetry tracing is disabled or not. | +| `DisableRetry` | A boolean value that indicates whether command retries should be disabled or not. | +| `CommandTimeout` | The time in seconds to wait for the command to execute. | + [!INCLUDE [integration-health-checks](../includes/integration-health-checks.md)] -The .NET Aspire Oracle Entity Framework Core integration registers a basic health check that checks the database connection given a `TContext`. The health check is enabled by default and can be disabled using the `DisableHealthChecks` property in the configuration. +By default, the .NET Aspire Oracle Entity Framework Core integration handles the following: + +- Checks if the is `true`. +- If so, adds the [`DbContextHealthCheck`](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/blob/master/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs), which calls EF Core's method. The name of the health check is the name of the `TContext` type. [!INCLUDE [integration-observability-and-telemetry](../includes/integration-observability-and-telemetry.md)] -### Logging +#### Logging The .NET Aspire Oracle Entity Framework Core integration uses the following log categories: -- `Microsoft.EntityFrameworkCore.Database.Command.CommandCreated` -- `Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting` -- `Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted` -- `Microsoft.EntityFrameworkCore.Database.Command.CommandError` +- `Microsoft.EntityFrameworkCore.ChangeTracking` +- `Microsoft.EntityFrameworkCore.Database.Command` +- `Microsoft.EntityFrameworkCore.Database.Connection` +- `Microsoft.EntityFrameworkCore.Database.Transaction` +- `Microsoft.EntityFrameworkCore.Infrastructure` +- `Microsoft.EntityFrameworkCore.Migrations` +- `Microsoft.EntityFrameworkCore.Model` +- `Microsoft.EntityFrameworkCore.Model.Validation` +- `Microsoft.EntityFrameworkCore.Query` +- `Microsoft.EntityFrameworkCore.Update` -### Tracing +#### Tracing The .NET Aspire Oracle Entity Framework Core integration will emit the following tracing activities using OpenTelemetry: - OpenTelemetry.Instrumentation.EntityFrameworkCore -### Metrics +#### Metrics The .NET Aspire Oracle Entity Framework Core integration currently supports the following metrics: @@ -199,6 +318,8 @@ The .NET Aspire Oracle Entity Framework Core integration currently supports the ## See also +- [Oracle Database](https://www.oracle.com/database/) +- [Oracle Database Documentation](https://docs.oracle.com/en/database/oracle/oracle-database/index.html) - [Entity Framework Core docs](/ef/core) - [.NET Aspire integrations](../fundamentals/integrations-overview.md) - [.NET Aspire GitHub repo](https://github.com/dotnet/aspire) diff --git a/docs/deployment/azure/aca-deployment-github-actions.md b/docs/deployment/azure/aca-deployment-github-actions.md index 0081395ceb..abb81e0252 100644 --- a/docs/deployment/azure/aca-deployment-github-actions.md +++ b/docs/deployment/azure/aca-deployment-github-actions.md @@ -1,21 +1,20 @@ --- -title: Deploy a .NET Aspire project using the Azure Developer CLI and GitHub Actions -description: Learn how to use `azd` and GitHub Actions to deploy .NET Aspire projects. +title: Deploy a .NET Aspire project using the Azure Developer CLI +description: Learn how to use `azd` to deploy .NET Aspire projects. ms.date: 01/08/2025 zone_pivot_groups: deployment-platform ms.custom: devx-track-extended-azdevcli --- -# Tutorial: Deploy a .NET Aspire project using the Azure Developer CLI and GitHub Actions +# Tutorial: Deploy a .NET Aspire project using the Azure Developer CLI -The Azure Developer CLI (`azd`) enables you to deploy .NET Aspire projects using GitHub Actions by automatically configuring the required authentication and environment settings. This article walks you through the process of creating and deploying a .NET Aspire project on Azure Container Apps using `azd` and GitHub Actions. You learn the following concepts: +The Azure Developer CLI (`azd`) enables you to deploy .NET Aspire projects using GitHub Actions or Azure Devops pipelines by automatically configuring the required authentication and environment settings. This article walks you through the process of creating and deploying a .NET Aspire project on Azure Container Apps using `azd`. You learn the following concepts: > [!div class="checklist"] > -> - Explore how `azd` integration works with .NET Aspire projects and GitHub Actions -> - Create and configure a GitHub repository for a .NET Aspire project using `azd` -> - Add a GitHub Actions workflow file to your .NET Aspire solution -> - Monitor and explore GitHub Actions workflow executions and Azure deployments +> - Explore how `azd` integration works with .NET Aspire projects +> - Create and configure a GitHub or Azure DevOps repository for a .NET Aspire project using `azd` +> - Monitor and explore GitHub Actions workflow or Azure DevOps pipeline executions and Azure deployments [!INCLUDE [aspire-prereqs](../../includes/aspire-prereqs.md)] @@ -62,97 +61,6 @@ As a starting point, this article assumes that you've created a .NET Aspire solu :::zone pivot="github-actions" -## Add the GitHub Actions workflow file - -Although `azd` generated some essential template files for you, the project still needs a GitHub Actions workflow file to support provisioning and deployments using CI/CD. - -1. Create an empty _.github_ folder at the root of your project. `azd` uses this directory by default to discover GitHub Actions workflow files. - - > [!TIP] - > If you're on macOS user and you're struggling to create a folder with a leading `.`, you can use the terminal to create the folder. Open the terminal and navigate to the root of your project. Run the following command to create the folder: - > - > ```bash - > mkdir .github - > ``` - -1. Inside the new _.github_ folder, create another folder called _workflows_ (you'll end up with _.github/workflows_). - -1. Add a new GitHub Actions workflow file into the new folder named _azure-dev.yml_. The `azd` starter template provides a [Sample GitHub Actions workflow file](https://github.com/Azure-Samples/azd-starter-bicep/blob/main/.github/workflows/azure-dev.yml) that you can copy into your project. - -1. Update the sample GitHub Actions workflow to include a step to install the .NET Aspire workload. This ensures the .NET Aspire tooling and commands are available to the job running your GitHub Actions. The completed workflow file should match the following: - - ```yml - 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_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} - AZURE_ENV_NAME: ${{ vars.AZURE_ENV_NAME }} - AZURE_LOCATION: ${{ vars.AZURE_LOCATION }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install azd - uses: Azure/setup-azd@v2 - - - name: Install .NET Aspire workload - run: dotnet workload install aspire - - - name: Log in with Azure (Federated Credentials) - if: ${{ env.AZURE_CLIENT_ID != '' }} - run: | - azd auth login ` - --client-id "$Env:AZURE_CLIENT_ID" ` - --federated-credential-provider "github" ` - --tenant-id "$Env:AZURE_TENANT_ID" - shell: pwsh - - - name: Log in with Azure (Client Credentials) - if: ${{ env.AZURE_CREDENTIALS != '' }} - run: | - $info = $Env:AZURE_CREDENTIALS | ConvertFrom-Json -AsHashtable; - Write-Host "::add-mask::$($info.clientSecret)" - - azd auth login ` - --client-id "$($info.clientId)" ` - --client-secret "$($info.clientSecret)" ` - --tenant-id "$($info.tenantId)" - shell: pwsh - - - name: Provision Infrastructure - run: azd provision --no-prompt - # Required when - # env: - # AZD_INITIAL_ENVIRONMENT_CONFIG: ${{ secrets.AZD_INITIAL_ENVIRONMENT_CONFIG }} - - # Required when provisioning and deploying are defined in separate jobs. - # - name: Refresh azd env (pulls latest infrastructure provision) - # run: azd env refresh - # env: - # AZURE_LOCATION: ${{ env.AZURE_LOCATION }} - - - name: Deploy Application - run: azd deploy --no-prompt - ``` - -Additionally, you may notice that the provisioning and deployment steps are combined into a single job. If you prefer to separate these steps into different jobs, you can do so by creating two separate jobs in the workflow file. The provisioning job should run first, followed by the deployment job. The deployment job should include the `AZD_INITIAL_ENVIRONMENT_CONFIG` secret to ensure the deployment job has access to the environment configuration. You'd also need to uncomment the `azd env refresh` step in the deployment job to ensure the deployment job has access to the latest infrastructure provision. - ## Create the GitHub repository and pipeline The Azure Developer CLI enables you to automatically create CI/CD pipelines with the correct configurations and permissions to provision and deploy resources to Azure. `azd` can also create a GitHub repository for your app if it doesn't exist already. @@ -198,74 +106,6 @@ Congratulations! You successfully deployed a .NET Aspire project using the Azure :::zone pivot="azure-pipelines" -## Configure the workflow file - -Although `azd` generated some essential template files for you, the project still needs an Azure Pipelines workflow file to support provisioning and deployments using CI/CD. - -1. Create an empty _.azdo_ folder at the root of your project. `azd` uses this directory by default to discover Azure Pipelines workflow files. - -1. Inside the new _.azdo_ folder, create another folder called _pipelines_ (you'll end up with _.azdo/pipelines_). - -1. Add a new Azure Pipelines workflow file into the new folder named _azure-dev.yml_. The `azd` starter template provides a [Sample Azure Pipelines workflow file](https://github.com/Azure-Samples/azd-starter-bicep/blob/main/.azdo/pipelines/azure-dev.yml) that you can copy into your project. - -1. Update the sample Azure Pipelines workflow to include a step to install the .NET Aspire workload. The completed workflow file should match the following: - -```yml -trigger: - - main - - master - -pool: - vmImage: ubuntu-latest - -steps: - - - task: Bash@3 - displayName: Install azd - inputs: - targetType: 'inline' - script: | - curl -fsSL https://aka.ms/install-azd.sh | bash - - # azd delegate auth to az to use service connection with AzureCLI@2 - - pwsh: | - azd config set auth.useAzCliAuth "true" - displayName: Configure `azd` to Use AZ CLI Authentication. - - - task: Bash@3 - displayName: Install .NET Aspire workload - inputs: - targetType: 'inline' - script: | - dotnet workload install aspire - - - task: AzureCLI@2 - displayName: Provision Infrastructure - inputs: - azureSubscription: azconnection - scriptType: bash - scriptLocation: inlineScript - inlineScript: | - azd provision --no-prompt - env: - AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID) - AZURE_ENV_NAME: $(AZURE_ENV_NAME) - AZURE_LOCATION: $(AZURE_LOCATION) - - - task: AzureCLI@2 - displayName: Deploy Application - inputs: - azureSubscription: azconnection - scriptType: bash - scriptLocation: inlineScript - inlineScript: | - azd deploy --no-prompt - env: - AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID) - AZURE_ENV_NAME: $(AZURE_ENV_NAME) - AZURE_LOCATION: $(AZURE_LOCATION) -``` - ## Create the Azure DevOps repository and pipeline > [!IMPORTANT] diff --git a/docs/get-started/aspire-overview.md b/docs/get-started/aspire-overview.md index 75a4984d8b..fd8d97732e 100644 --- a/docs/get-started/aspire-overview.md +++ b/docs/get-started/aspire-overview.md @@ -1,6 +1,6 @@ --- title: .NET Aspire overview -description: Learn about .NET Aspire, an application stack designed to improve the experience of building cloud-native applications. +description: Learn about .NET Aspire, an application stack designed to improve the experience of building distributed applications. ms.date: 11/12/2024 --- @@ -14,29 +14,27 @@ ms.date: 11/12/2024 :::column-end::: :::column span="3"::: -.NET Aspire is a set of powerful tools, templates, and packages for building observable, production ready apps.​​ .NET Aspire is delivered through a collection of NuGet packages that handle specific cloud-native concerns. Cloud-native apps often consist of small, interconnected pieces or microservices rather than a single, monolithic code base. Cloud-native apps generally consume a large number of services, such as databases, messaging, and caching. For information on support, see the [.NET Aspire Support Policy](https://dotnet.microsoft.com/platform/support/policy/aspire). +.NET Aspire is a set of tools, templates, and packages for building observable, production ready apps.​​ .NET Aspire is delivered through a collection of NuGet packages that bootstrap or improve specific challenges with modern app development. Today's apps generally consume a large number of services, such as databases, messaging, and caching, many of which are supported via [.NET Aspire Integrations](../fundamentals/integrations-overview.md). For information on support, see the [.NET Aspire Support Policy](https://dotnet.microsoft.com/platform/support/policy/aspire). :::column-end::: :::row-end::: -A _distributed application_ is one that uses computational _resources_ across multiple nodes, such as containers running on different hosts. Such nodes must communicate over network boundaries to deliver responses to users. A cloud-native app is a specific type of distributed app that takes full advantage of the scalability, resilience, and manageability of cloud infrastructures. - ## Why .NET Aspire? -.NET Aspire is designed to improve the experience of building .NET cloud-native apps. It provides a consistent, opinionated set of tools and patterns that help you build and run distributed apps. .NET Aspire is designed to help you with: +.NET Aspire improves the experience of building apps that have a variety of projects and resources. With dev-time productivity enhancements that emulate deployed scenarios, you can quickly develop interconnected apps. Designed for flexibility, .NET Aspire allows you to replace or extend parts with your preferred tools and workflows. Key features include: -- [**Orchestration**](#orchestration): .NET Aspire provides features for running and connecting multi-project applications and their dependencies for [local development environments](../fundamentals/networking-overview.md). +- [**Dev-Time Orchestration**](#dev-time-orchestration): .NET Aspire provides features for running and connecting multi-project applications, container resources, and other dependencies for [local development environments](../fundamentals/networking-overview.md). - [**Integrations**](#net-aspire-integrations): .NET Aspire integrations are NuGet packages for commonly used services, such as Redis or Postgres, with standardized interfaces ensuring they connect consistently and seamlessly with your app. - [**Tooling**](#project-templates-and-tooling): .NET Aspire comes with project templates and tooling experiences for Visual Studio, Visual Studio Code, and the [.NET CLI](/dotnet/core/tools/) to help you create and interact with .NET Aspire projects. -## Orchestration +## Dev-time orchestration -In .NET Aspire, orchestration primarily focuses on enhancing the _local development_ experience by simplifying the management of your cloud-native app's configuration and interconnections. It's important to note that .NET Aspire's orchestration isn't intended to replace the robust systems used in production environments, such as [Kubernetes](../deployment/overview.md#deploy-to-kubernetes). Instead, it provides a set of abstractions that streamline the setup of service discovery, environment variables, and container configurations, eliminating the need to deal with low-level implementation details. These abstractions ensure a consistent setup pattern across apps with numerous integrations and services, making it easier to manage complex applications during the development phase. +In .NET Aspire, "orchestration" primarily focuses on enhancing the _local development_ experience by simplifying the management of your app's configuration and interconnections. It's important to note that .NET Aspire's orchestration isn't intended to replace the robust systems used in production environments, such as [Kubernetes](../deployment/overview.md#deploy-to-kubernetes). Instead, it's a set of abstractions that streamline the setup of service discovery, environment variables, and container configurations, eliminating the need to deal with low-level implementation details. With .NET Aspire, your code has a consistent bootstrapping experience on any dev machine without the need for complex manual steps, making it easier to manage during the development phase. .NET Aspire orchestration assists with the following concerns: - **App composition**: Specify the .NET projects, containers, executables, and cloud resources that make up the application. -- **Service discovery and connection string management**: The app host manages to inject the right connection strings or network configurations and service discovery information to simplify the developer experience. +- **Service discovery and connection string management**: The app host injects the right connection strings, network configurations, and service discovery information to simplify the developer experience. For example, using .NET Aspire, the following code creates a local Redis container resource, waits for it to become available, and then configures the appropriate connection string in the `"frontend"` project with a few helper method calls: @@ -61,9 +59,9 @@ For more information, see [.NET Aspire orchestration overview](../fundamentals/a ## .NET Aspire integrations -[.NET Aspire integrations](../fundamentals/integrations-overview.md) are NuGet packages designed to simplify connections to popular services and platforms, such as Redis or PostgreSQL. .NET Aspire integrations handle many cloud-native concerns for you through standardized configuration patterns, such as adding health checks and telemetry. Integrations are two-fold, in that one side represents the service you're connecting to, and the other side represents the client or consumer of that service. In other words, for each hosting package there's a corresponding client package that handles the service connection. +[.NET Aspire integrations](../fundamentals/integrations-overview.md) are NuGet packages designed to simplify connections to popular services and platforms, such as Redis or PostgreSQL. .NET Aspire integrations handle cloud resource setup and interaction for you through standardized patterns, such as adding health checks and telemetry. Integrations are two-fold - ["hosting" integrations](../fundamentals/integrations-overview.md#hosting-integrations) represents the service you're connecting to, and ["client" integrations](../fundamentals/integrations-overview.md#client-integrations) represents the client or consumer of that service. In other words, for many hosting packages there's a corresponding client package that handles the service connection within your code. -Each integration is designed to work with .NET Aspire orchestration, and their configurations are injected automatically by [referencing named resources](../fundamentals/app-host-overview.md#reference-resources). In other words, if _Example.ServiceFoo_ references _Example.ServiceBar_, _Example.ServiceFoo_ inherits the integration's required configurations to allow them to communicate with each other automatically. +Each integration is designed to work with the .NET Aspire app host, and their configurations are injected automatically by [referencing named resources](../fundamentals/app-host-overview.md#reference-resources). In other words, if _Example.ServiceFoo_ references _Example.ServiceBar_, _Example.ServiceFoo_ inherits the integration's required configurations to allow them to communicate with each other automatically. For example, consider the following code using the .NET Aspire Service Bus integration: @@ -81,7 +79,7 @@ A full list of available integrations is detailed on the [.NET Aspire integratio ## Project templates and tooling -.NET Aspire provides a set of project templates and tooling experiences for Visual Studio, Visual Studio Code, and the [.NET CLI](/dotnet/core/tools/). These templates are designed to help you create and interact with .NET Aspire projects. The templates are opinionated and come with a set of defaults that help you get started quickly. They include boilerplate code and configurations that are common to cloud-native apps, such as telemetry, health checks, and service discovery. For more information, see [.NET Aspire templates](../fundamentals/setup-tooling.md#net-aspire-templates). +.NET Aspire provides a set of project templates and tooling experiences for Visual Studio, Visual Studio Code, and the [.NET CLI](/dotnet/core/tools/). These templates are designed to help you create and interact with .NET Aspire projects, or add .NET Aspire into your existing codebase. The templates include a set of opinionated defaults to help you get started quickly - for example, it has boilerplate code for turning on health checks and logging in .NET apps. These defaults are fully customizable, so you can edit and adapt them to suit your needs. .NET Aspire templates also include boilerplate extension methods that handle common service configurations for you: