Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 23, 2025

Summary

Updates the AzureEnvironmentResource implementation to emit separate PipelineStep instances for each AzureBicepResource that needs to be provisioned and for each compute resource that requires container image pushing, improving visibility and granularity in the deployment pipeline.

Changes

Provision Steps

Before:
The implementation created a single pipeline step named provision-azure-bicep-resources that provisioned all Azure Bicep resources together:

var provisionStep = new PipelineStep
{
    Name = "provision-azure-bicep-resources",
    Action = ctx => ProvisionAzureBicepResourcesAsync(ctx, provisioningContext!),
    Tags = [WellKnownPipelineTags.ProvisionInfrastructure]
};

After:
The implementation now creates individual pipeline steps for each resource, with names that include the resource being provisioned:

var bicepResources = factoryContext.PipelineContext.Model.Resources
    .OfType<AzureBicepResource>()
    .Where(r => !r.IsExcludedFromPublish())
    .ToList();

foreach (var bicepResource in bicepResources)
{
    var provisionStep = new PipelineStep
    {
        Name = $"provision-{bicepResource.Name}",
        Action = ctx => ProvisionSingleAzureBicepResourceAsync(ctx, provisioningContext!, bicepResource),
        Tags = [WellKnownPipelineTags.ProvisionInfrastructure]
    };
    provisionStep.DependsOn(createContextStep);
    provisionSteps.Add(provisionStep);
}

Push Steps

Before:
The implementation created a single pipeline step named push-container-images that pushed all container images together.

After:
The implementation now creates individual push steps for each compute resource:

var computeResources = factoryContext.PipelineContext.Model.GetComputeResources()
    .Where(r => r.RequiresImageBuildAndPush())
    .ToList();

foreach (var computeResource in computeResources)
{
    var pushStep = new PipelineStep
    {
        Name = $"push-{computeResource.Name}",
        Action = ctx => PushSingleContainerImageAsync(ctx, computeResource)
    };
    pushStep.DependsOn(buildStep);
    pushSteps.Add(pushStep);
}

Dynamic Dependency Wiring

The implementation uses PipelineConfigurationAnnotation to dynamically wire dependencies between push steps and container registry provision steps:

Annotations.Add(new PipelineConfigurationAnnotation(configContext =>
{
    var pushSteps = configContext.Steps.Where(s => s.Name.StartsWith("push-")).ToList();
    
    foreach (var pushStep in pushSteps)
    {
        var computeResourceName = pushStep.Name.Substring("push-".Length);
        var computeResource = configContext.Model.Resources.FirstOrDefault(r => r.Name == computeResourceName);
        
        if (computeResource != null && TryGetContainerRegistry(computeResource, out var containerRegistry))
        {
            var registryProvisionStep = configContext.Steps
                .FirstOrDefault(s => s.Name == $"provision-{containerRegistry.Name}");
            
            if (registryProvisionStep != null)
            {
                pushStep.DependsOn(registryProvisionStep);
            }
        }
    }
}));

Example

For an application with three Azure resources (storage1, registry, cosmos) and two compute resources (app1, app2), the pipeline now shows:

Pipeline Steps:

  1. validate-azure-cli-login
  2. create-provisioning-context
  3. provision-storage1 (tagged: provision-infra)
  4. provision-registry (tagged: provision-infra)
  5. provision-cosmos (tagged: provision-infra)
  6. build-container-images (tagged: build-compute)
  7. push-app1 (depends on: build + provision-registry)
  8. push-app2 (depends on: build + provision-registry)
  9. deploy-compute-resources (tagged: deploy-compute)
  10. print-dashboard-url

Benefits

  • Better Visibility: Users can see exactly which resource is being provisioned and which container image is being pushed at each stage
  • Improved Progress Tracking: Each resource and compute resource appears as a distinct step with its own status
  • Error Isolation: Failures in provisioning one resource or pushing one image don't block attempts to provision/push others
  • Explicit Dependencies: Push steps explicitly depend on their corresponding container registry provision steps
  • Step Filtering: Users can filter and run specific provision or push steps when needed
  • Parallel Execution: Resources without dependencies can potentially be provisioned and pushed in parallel

Implementation Details

  • Modified PipelineStepAnnotation factory in AzureEnvironmentResource constructor to enumerate both AzureBicepResource and compute resource instances from the model
  • Created new ProvisionSingleAzureBicepResourceAsync method to handle provisioning of individual Bicep resources
  • Created new PushSingleContainerImageAsync method to handle pushing individual container images
  • Added PipelineConfigurationAnnotation to dynamically wire dependencies between push steps and container registry provision steps during the pipeline configuration phase
  • Removed old methods: ProvisionAzureBicepResourcesAsync, PushContainerImagesAsync, LoginToAllRegistriesAsync, and PushImagesToAllRegistriesAsync
  • Updated dependencies to ensure deploy-compute-resources step depends on all push and provision steps
  • Each provision step is properly tagged with WellKnownPipelineTags.ProvisionInfrastructure as required

[!WARNING]

Original prompt

Update the AzureEnvironmentResource implementation to emit a seperate PipelineStep for each AzureBicepResource that needs to be provisioned. All these steps should be tagged with the WellKnownPipelineTags.ProvisioningInfrastructure tag. The step name should include the name of the resource being provisioning.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
Copilot AI changed the title [WIP] Update AzureEnvironmentResource to emit separate PipelineStep for Bicep resources Emit separate pipeline steps for each AzureBicepResource in AzureEnvironmentResource Oct 23, 2025
Copilot AI requested a review from captainsafia October 23, 2025 19:55
Copilot finished work on behalf of captainsafia October 23, 2025 19:55
@github-actions
Copy link
Contributor

github-actions bot commented Oct 23, 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://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 12324

Or

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

};
pushStep.DependsOn(buildStep);
pushStep.DependsOn(provisionStep);
foreach (var provisionStep in provisionSteps)
Copy link
Member

Choose a reason for hiding this comment

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

@copilot Update the implementation to emit a separate push step for each compute resource that is registered. Wire up a dependency between the push step for each compute resource and the provision step from the IContainerRegistry resource that it references. Use the configuration pipeline API introduced in b2f90eb to do this. Look at b9cdc57 for an example of how to implement the relationships using the PipelineConfigurationAnnotation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated in commit a8cbc8d. The implementation now:

  1. Creates separate push steps for each compute resource (named push-{resourceName})
  2. Uses PipelineConfigurationAnnotation to dynamically wire dependencies between push steps and their corresponding container registry provision steps
  3. Extracts the compute resource from each push step, finds its container registry via TryGetContainerRegistry, and adds a dependency on provision-{registryName}

Each push step now explicitly depends on both the build step and the provision step for its container registry.

…pendencies

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
Copilot AI changed the title Emit separate pipeline steps for each AzureBicepResource in AzureEnvironmentResource Emit separate pipeline steps for each AzureBicepResource and compute resource in AzureEnvironmentResource Oct 23, 2025
Copilot finished work on behalf of captainsafia October 23, 2025 20:30
Copilot AI requested a review from captainsafia October 23, 2025 20:30
@captainsafia
Copy link
Member

Closing in favor of taking this a different direction.

@dotnet-policy-service dotnet-policy-service bot added this to the 13.0 milestone Oct 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants