From 2a4154d11d54ce6ac27e318cb733a533afcaf9c8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Jun 2025 16:35:17 +0000 Subject: [PATCH 1/2] Initial plan for issue From 84666c294fd32fd67535945fa47a9cfe0c561768 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Jun 2025 16:44:15 +0000 Subject: [PATCH 2/2] Add infrastructure synthesis customization doc and clean up unused include files Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com> --- .../azure/aca-deployment-azd-in-depth.md | 2 + .../azure/aca-deployment-visual-studio.md | 2 +- docs/deployment/azure/aca-deployment.md | 2 +- .../deployment/azure/customize-deployments.md | 262 ++++++++++++++++++ .../includes/aca-bicep-cli-shared-steps.md | 118 -------- .../includes/aca-configure-post-deployment.md | 77 ----- docs/toc.yml | 3 + 7 files changed, 269 insertions(+), 197 deletions(-) create mode 100644 docs/deployment/azure/customize-deployments.md delete mode 100644 docs/deployment/azure/includes/aca-bicep-cli-shared-steps.md delete mode 100644 docs/deployment/azure/includes/aca-configure-post-deployment.md diff --git a/docs/deployment/azure/aca-deployment-azd-in-depth.md b/docs/deployment/azure/aca-deployment-azd-in-depth.md index 464e1aa272..18be913f99 100644 --- a/docs/deployment/azure/aca-deployment-azd-in-depth.md +++ b/docs/deployment/azure/aca-deployment-azd-in-depth.md @@ -202,6 +202,8 @@ The previous command may take some time to execute, but when completed the resou Although development teams are free to use `azd up` (or `azd provision` and `azd deploy`) commands for their deployments both for development and production purposes, some teams may choose to generate Bicep files that they can review and manage as part of version control (this also allows these Bicep files to be referenced as part of a larger more complex Azure deployment). +For comprehensive guidance on customizing generated infrastructure for production scenarios, see [Customize deployments with infrastructure synthesis](customize-deployments.md). + `azd` includes the ability to output the Bicep it uses for provisioning via following command: ```azdeveloper diff --git a/docs/deployment/azure/aca-deployment-visual-studio.md b/docs/deployment/azure/aca-deployment-visual-studio.md index 1507c6c7f8..3a401ff194 100644 --- a/docs/deployment/azure/aca-deployment-visual-studio.md +++ b/docs/deployment/azure/aca-deployment-visual-studio.md @@ -1,6 +1,6 @@ --- title: Deploy .NET Aspire projects to Azure Container Apps using Visual Studio -description: Learn how to use Bicep, the Azure CLI, and Azure Developer CLI to deploy .NET Aspire projects to Azure using Visual Studio. +description: Learn how to deploy .NET Aspire projects to Azure Container Apps using Visual Studio. ms.date: 06/14/2024 --- diff --git a/docs/deployment/azure/aca-deployment.md b/docs/deployment/azure/aca-deployment.md index 0751eeb4c0..261ac536d6 100644 --- a/docs/deployment/azure/aca-deployment.md +++ b/docs/deployment/azure/aca-deployment.md @@ -23,7 +23,7 @@ As an alternative to this tutorial and for a more in-depth guide, see [Deploy a ## Deploy .NET Aspire projects with `azd` -With .NET Aspire and Azure Container Apps (ACA), you have a great hosting scenario for building out your cloud-native apps with .NET. We built some great new features into the Azure Developer CLI (`azd`) specific for making .NET Aspire development and deployment to Azure a friction-free experience. You can still use the Azure CLI and/or Bicep options when you need a granular level of control over your deployments. But for new projects, you won't find an easier path to success for getting a new microservice topology deployed into the cloud. +With .NET Aspire and Azure Container Apps (ACA), you have a great hosting scenario for building out your cloud-native apps with .NET. We built some great new features into the Azure Developer CLI (`azd`) specific for making .NET Aspire development and deployment to Azure a friction-free experience. For production scenarios that require granular control over infrastructure, see [Customize deployments with infrastructure synthesis](customize-deployments.md). But for new projects, you won't find an easier path to success for getting a new microservice topology deployed into the cloud. ## Create a .NET Aspire project diff --git a/docs/deployment/azure/customize-deployments.md b/docs/deployment/azure/customize-deployments.md new file mode 100644 index 0000000000..fa843252c1 --- /dev/null +++ b/docs/deployment/azure/customize-deployments.md @@ -0,0 +1,262 @@ +--- +title: Customize .NET Aspire deployments with infrastructure synthesis +description: Learn how to customize Azure deployments using azd infra synth for production scenarios. +ms.date: 01/08/2025 +ms.custom: devx-track-extended-azdevcli +--- + +# Customize .NET Aspire deployments with infrastructure synthesis + +The Azure Developer CLI (`azd`) provides a powerful feature called infrastructure synthesis that allows you to generate and customize the underlying infrastructure code for your .NET Aspire applications. This capability is essential for production scenarios where you need fine-grained control over Azure resources, security configurations, and deployment patterns. + +This article covers how to use `azd infra synth` to: + +> [!div class="checklist"] +> +> - Generate Bicep infrastructure files from your .NET Aspire app model +> - Customize generated infrastructure for production requirements +> - Apply security best practices to generated resources +> - Manage infrastructure as code with proper version control + +[!INCLUDE [aspire-prereqs](../../includes/aspire-prereqs.md)] + +You will also need to have the Azure Developer CLI [installed locally](/azure/developer/azure-developer-cli/install-azd). + +## How infrastructure synthesis works + +Infrastructure synthesis in `azd` transforms your .NET Aspire app model into concrete Azure infrastructure definitions using Bicep templates. This process bridges the gap between the development-time orchestration in .NET Aspire and the production infrastructure required in Azure. + +When you run `azd infra synth`, the CLI: + +1. Analyzes your .NET Aspire app host project +2. Identifies all resources and their dependencies +3. Generates corresponding Azure resource definitions in Bicep +4. Creates supporting configuration files for deployment + +## Enable and use infrastructure synthesis + +Infrastructure synthesis is currently an alpha feature that must be explicitly enabled: + +```azdeveloper +azd config set alpha.infraSynth on +``` + +Once enabled, generate infrastructure files for your .NET Aspire project: + +```azdeveloper +azd infra synth +``` + +This command creates an `infra` folder in your app host project directory with the following structure: + +``` +infra/ +├── main.bicep # Main infrastructure entry point +├── main.parameters.json # Parameter values for deployment +├── resources.bicep # Resource definitions +└── abbreviations.json # Azure resource naming conventions +``` + +## Production considerations + +### Security configurations + +When preparing for production deployments, review and enhance the generated infrastructure with appropriate security controls: + +**Network isolation:** + +```bicep +// Example: Configure Container Apps Environment with network restrictions +resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = { + name: environmentName + location: location + properties: { + vnetConfiguration: { + infrastructureSubnetId: subnetId + internal: true + } + workloadProfiles: [ + { + name: 'Consumption' + workloadProfileType: 'Consumption' + } + ] + } +} +``` + +**Identity and access management:** + +```bicep +// Example: Configure managed identity with least privilege access +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: identityName + location: location +} + +// Assign specific roles rather than broad permissions +resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + scope: containerRegistry + name: guid(containerRegistry.id, managedIdentity.id, 'AcrPull') + properties: { + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') // AcrPull + principalId: managedIdentity.properties.principalId + principalType: 'ServicePrincipal' + } +} +``` + +### Resource sizing and scaling + +Review generated resource configurations for production requirements: + +```bicep +// Example: Configure appropriate resource limits +resource containerApp 'Microsoft.App/containerApps@2023-05-01' = { + name: appName + location: location + properties: { + configuration: { + ingress: { + external: true + targetPort: 8080 + allowInsecure: false // Ensure HTTPS only + } + } + template: { + containers: [ + { + name: containerName + image: image + resources: { + cpu: json('1.0') // Adjust based on load requirements + memory: '2.0Gi' // Adjust based on memory needs + } + } + ] + scale: { + minReplicas: 2 // Ensure availability + maxReplicas: 10 // Control costs + rules: [ + { + name: 'http-requests' + http: { + metadata: { + concurrentRequests: '100' + } + } + } + ] + } + } + } +} +``` + +### Environment-specific configurations + +Use parameters to manage environment-specific settings: + +```bicep +@description('Environment name (dev, staging, prod)') +param environmentType string = 'dev' + +@description('Application tier configuration') +var tierConfigurations = { + dev: { + skuName: 'Consumption' + replicas: 1 + } + staging: { + skuName: 'Dedicated' + replicas: 2 + } + prod: { + skuName: 'Dedicated' + replicas: 3 + } +} + +var currentTier = tierConfigurations[environmentType] +``` + +## Iterative customization workflow + +After generating initial infrastructure, establish a workflow for ongoing customization: + +1. **Make infrastructure changes** to the generated Bicep files +2. **Test deployments** in development environments +3. **Version control** your infrastructure changes +4. **Document customizations** for team collaboration + +> [!IMPORTANT] +> Running `azd infra synth` again will regenerate files and may overwrite your customizations. Always version control your changes and be prepared to re-apply customizations after regeneration. + +## Advanced customization patterns + +### Custom resource definitions + +Extend generated infrastructure with additional Azure resources: + +```bicep +// Add Application Insights for monitoring +resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { + name: '${resourceBaseName}-ai' + location: location + kind: 'web' + properties: { + Application_Type: 'web' + Flow_Type: 'Redfield' + Request_Source: 'IbizaWebAppExtensionCreate' + WorkspaceResourceId: logAnalyticsWorkspace.id + } +} + +// Configure container apps to use Application Insights +resource containerApp 'Microsoft.App/containerApps@2023-05-01' = { + // ... other properties + properties: { + template: { + containers: [ + { + // ... other container properties + env: [ + { + name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' + value: applicationInsights.properties.ConnectionString + } + ] + } + ] + } + } +} +``` + +### Infrastructure validation + +Add validation rules to ensure proper resource configuration: + +```bicep +@description('Validates that environment type is supported') +@allowed(['dev', 'staging', 'prod']) +param environmentType string + +@description('Validates location is in allowed regions') +@allowed(['eastus', 'westus2', 'northeurope']) +param location string +``` + +## Best practices + +- **Version control**: Always commit generated infrastructure files to source control +- **Environment separation**: Use separate resource groups and naming conventions for different environments +- **Security scanning**: Implement automated security scanning of Bicep templates +- **Cost monitoring**: Set up budget alerts and resource tags for cost tracking +- **Documentation**: Maintain documentation of customizations and their rationale + +## Next steps + +- [Deploy a .NET Aspire project to Azure Container Apps using azd](aca-deployment.md) +- [Azure Container Apps with azd (In-depth)](aca-deployment-azd-in-depth.md) +- [Deploy using azd and CI/CD](aca-deployment-github-actions.md) diff --git a/docs/deployment/azure/includes/aca-bicep-cli-shared-steps.md b/docs/deployment/azure/includes/aca-bicep-cli-shared-steps.md deleted file mode 100644 index a6b82dd662..0000000000 --- a/docs/deployment/azure/includes/aca-bicep-cli-shared-steps.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -ms.topic: include ---- - -1. Install the latest [Azure CLI](/cli/azure/install-azure-cli) & [sign in](/cli/azure/authenticate-azure-cli) - - # [Windows](#tab/install-az-windows) - - ```powershell - winget install -e --id Microsoft.AzureCLI - # Restart the terminal session after installing the az CLI before running the next command - az login - ``` - - # [macOS](#tab/install-macos-windows) - - ```bash - brew update && brew install azure-cli - # Restart the terminal session after installing the az CLI before running the next command - az login - ``` - - # [Linux](#tab/linux) - - ```bash - curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash - # Restart the terminal session after installing the az CLI before running the next command - az login - ``` - - --- - -1. Login using the `az login` command, which will prompt you to open a browser. - -1. If you have access to more than one Azure subscription, get your subscription list as a table so you can find the right subscription and matching subscription id in which you want to experiment. - - ```azurecli - az account list --output table - ``` - -1. Copy the string from the "SubscriptionId" column for the Azure subscription you wish to use, then paste that string to your command prompt as the parameter to the `az account set` command: - - ```azurecli - az account set --subscription your-subscription-id-pasted-here - ``` - -1. Add the Azure CLI `az containerapp` extension, which provides capabilities specific to Azure Container Apps. For more information, see the [az containerapp docs](/cli/azure/containerapp?view=azure-cli-latest). - - ```azurecli - az extension add --name containerapp --upgrade - ``` - -1. Register required `az` namespaces. For more information, see the [az provider register docs](/cli/azure/provider?view=azure-cli-latest#az-provider-register): - - ```azurecli - az provider register --namespace Microsoft.App - az provider register --namespace Microsoft.OperationalInsights - az provider register --namespace Microsoft.ContainerRegistry - ``` - -## Set the environment variables - -Declare a set of environment variables to store commonly used values for the app deployment process. Setting these variables simplifies working with command-line parameters: - -> [!NOTE] -> You will need to customize the `SOLUTION` and `LOCATION` variables per your own needs. To get a list of the available Azure regions to which you can deploy, use the command `az account list-locations --output table`. - -# [PowerShell](#tab/powershell) - -```powershell -$env:SOLUTION="YOUR_APP_NAME" # Your app's name (e.g., "aspiresample42") -$env:LOCATION="YOUR_REGION" # Your desired Azure region (e.g., "westus") -$env:RESOURCE_GROUP="$($env:SOLUTION.ToLower())rg" # Resource Group name, e.g. eshopliterg -$env:CONTAINER_REGISTRY="$($env:SOLUTION.ToLower())cr" # Azure Container Registry name, e.g. eshoplitecr -$env:IMAGE_PREFIX="$($env:SOLUTION.ToLower())" # Container image name prefix, e.g. eshoplite -$env:IDENTITY="$($env:SOLUTION.ToLower())id" # Azure Managed Identity, e.g. eshopliteid -$env:ENVIRONMENT="$($env:SOLUTION.ToLower())cae" # Azure Container Apps Environment name, e.g. eshoplitecae -``` - -# [Bash](#tab/bash) - -```bash -SOLUTION="YOUR_APP_NAME" # Your app's name (e.g., "aspiresample42") -LOCATION="YOUR_REGION" # Your desired Azure region (e.g., "westus") -RESOURCE_GROUP="${SOLUTION,,}rg" # Resource Group name, e.g. eshopliterg -CONTAINER_REGISTRY="${SOLUTION,,}cr" # Azure Container Registry name, e.g. eshoplitecr -IMAGE_PREFIX="${SOLUTION,,}" # Container image name prefix, e.g. eshoplite -IDENTITY="${SOLUTION,,}id" # Azure Managed Identity, e.g. eshopliteid -ENVIRONMENT="${SOLUTION,,}cae" # Azure Container Apps Environment name, e.g. eshoplitecae -``` - ---- - -## Provision the Azure resources - -Azure Container Apps (ACA) is an ideal hosting platform for .NET Aspire projects. You can use Bicep or the Azure CLI to create resources in Azure to host the .NET Aspire project code along with supporting services: - -- An Azure Container Apps Environment to host your code and tertiary containers -- A pair of Azure Container Apps, hosting your code -- A Redis container inside the ACA Environment used by the output caching subsystem -- An Azure Log Analytics instance to host the log output from your apps -- An Azure Container Registry (ACR) instance for publishing your containers into the cloud - -1. Create the Azure resource group that will hold the provision resources: - - # [PowerShell](#tab/powershell) - - ```powershell - az group create --location $env:LOCATION --name $env:RESOURCE_GROUP - ``` - - # [Bash](#tab/bash) - - ```bash - az group create --location $LOCATION --name $RESOURCE_GROUP - ``` - - --- diff --git a/docs/deployment/azure/includes/aca-configure-post-deployment.md b/docs/deployment/azure/includes/aca-configure-post-deployment.md deleted file mode 100644 index 07219cf00a..0000000000 --- a/docs/deployment/azure/includes/aca-configure-post-deployment.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -ms.topic: include ---- - -## Configure the app for the deployed environment - -Now that the infrastructure has been provisioned, you need to set a few configuration settings in the Azure Container Apps before your code can be published into them from their new ACR repositories. - -> [!NOTE] -> These last few steps will be mitigated in a future release of Bicep and ACA. - -Configure the front end with the correct Redis connection configuration: - -1. First, use the `az containerapp exec` command to log into the Container App: - - # [PowerShell](#tab/powershell) - - ```powershell - az containerapp exec --resource-group $env:RESOURCE_GROUP --name web - ``` - - # [Bash](#tab/bash) - - ```bash - az containerapp exec --resource-group $RESOURCE_GROUP --name web - ``` - - --- - -1. Next, use `env` to view the `REDIS_ENDPOINT` and `REDIS_PASSWORD` environment variables injected by the Azure Container Apps service binding, then `exit` to close the connection to the Container App: - - ```bash - env | grep "^REDIS_ENDPOINT" - env | grep "^REDIS_PASSWORD" - exit - ``` - -1. The `web` Container App is using the .NET Aspire integration for Redis, which loads the connection information from the app's configuration with the key `ConnectionStrings__cache`. Update the app configuration in ACA so that an environment variable with this name contains a valid connection string constructed using the details retrieved in the previous step. Note that .NET expects comma delimited values in the Redis connection string. For example, `redis:6379,password=jH7DePUiK5E...`: - - # [PowerShell](#tab/powershell) - - ```powershell - az containerapp update --name web --resource-group $env:RESOURCE_GROUP --set-env-vars 'ConnectionStrings__cache="redis:6379,password="' - ``` - - # [Bash](#tab/bash) - - ```bash - az containerapp update --name web --resource-group $RESOURCE_GROUP --set-env-vars 'ConnectionStrings__cache="redis:6379,password="' - ``` - - --- - -1. Then, update the target ports for the `web` and `apiservice` Container Apps as the default "Hello World" app and our app have different target ports: - - > [!NOTE] - > The string `aspiretoaca` is associated with the name of the .NET Aspire solution, in lowercase form. If, when you created the .NET Aspire solution with a different name, you'll need to tweak this string in the code below. For example, if you created an app in a directory named `MyNewAspireApp`, you'd swap the string `aspiretoaca` with `mynewaspireapp` or the command will fail. - - # [PowerShell](#tab/powershell) - - ```powershell - az containerapp ingress update --name web --resource-group $env:RESOURCE_GROUP --target-port 8080 - az containerapp ingress update --name apiservice --resource-group $env:RESOURCE_GROUP --target-port 8080 - az containerapp update --name web --resource-group $env:RESOURCE_GROUP --image "$($env:CONTAINER_REGISTRY).azurecr.io/aspiretoaca-web:latest" - az containerapp update --name apiservice --resource-group $env:RESOURCE_GROUP --image "$($env:CONTAINER_REGISTRY).azurecr.io/aspiretoaca-apiservice:latest" - ``` - - # [Bash](#tab/bash) - - ```bash - az containerapp ingress update --name web --resource-group $RESOURCE_GROUP --target-port 8080 - az containerapp ingress update --name apiservice --resource-group $RESOURCE_GROUP --target-port 8080 - az containerapp update --name web --resource-group $RESOURCE_GROUP --image "$($CONTAINER_REGISTRY).azurecr.io/aspiretoaca-web:latest" - az containerapp update --name apiservice --resource-group $RESOURCE_GROUP --image "$($CONTAINER_REGISTRY).azurecr.io/aspiretoaca-apiservice:latest" - ``` - - --- diff --git a/docs/toc.yml b/docs/toc.yml index 4e4bdefe24..6734e79716 100644 --- a/docs/toc.yml +++ b/docs/toc.yml @@ -402,6 +402,9 @@ items: displayName: azure container apps,aca,azd - name: Deploy using azd and CI/CD href: deployment/azure/aca-deployment-github-actions.md + - name: Customize deployments with infrastructure synthesis + href: deployment/azure/customize-deployments.md + displayName: azd infra synth,bicep,infrastructure,production - name: Use .NET Aspire with Application Insights href: deployment/azure/application-insights.md displayName: app insights