Skip to content

Make app dependencies more explicit#2019

Open
flanakin wants to merge 3 commits intodevfrom
flanakin/app-dependencies
Open

Make app dependencies more explicit#2019
flanakin wants to merge 3 commits intodevfrom
flanakin/app-dependencies

Conversation

@flanakin
Copy link
Collaborator

Summary

  • Replace implicit dependsOn relationships between hub apps with explicit typed metadata outputs, making inter-app contracts clear and compile-time verified
  • Add metadata.bicep files to each app (Core, Analytics, Exports, ManagedExports) that define typed metadata contracts for what each app exposes to dependents
  • Add package-manifest.json to include metadata files in build output
  • Update Build-Toolkit.ps1 and Package-Toolkit.ps1 to support the new manifest-driven file copying

Test plan

  • Verify bicep build succeeds for all modified templates
  • Deploy hub and confirm all app modules wire up correctly via metadata outputs
  • Verify build scripts copy metadata.bicep files to release output

🤖 Generated with Claude Code

Copy link
Contributor

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 pull request refactors the FinOps hub architecture to replace implicit dependsOn relationships with explicit typed metadata outputs, making inter-app dependencies compile-time verified and contracts clear.

Changes:

  • Added metadata.bicep files to Core, Analytics, Exports, and ManagedExports apps defining typed metadata contracts
  • Removed implicit dependsOn declarations in hub.bicep, relying on Bicep's automatic dependency inference from metadata parameters
  • Updated build and package scripts to support manifest-driven copying of metadata files to release output

Reviewed changes

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

Show a summary per file
File Description
src/templates/finops-hub/package-manifest.json New manifest file specifying metadata.bicep files should be recursively copied to deployment output
src/templates/finops-hub/modules/hub.bicep Removed explicit dependsOn declarations, now passes metadata outputs between modules as parameters; updated outputs to reference metadata properties
src/templates/finops-hub/modules/fx/hub-types.bicep Added isSupportedVersion() function for validating metadata version compatibility
src/templates/finops-hub/modules/Microsoft.FinOpsHubs/RemoteHub/app.bicep Updated to consume Core metadata instead of using hardcoded values; added version validation
src/templates/finops-hub/modules/Microsoft.FinOpsHubs/Core/metadata.bicep Defines typed metadata contract for Core app resources (containers, datasets, linked services, etc.)
src/templates/finops-hub/modules/Microsoft.FinOpsHubs/Core/app.bicep Added shared azurerm linked service; outputs typed metadata instead of individual properties
src/templates/finops-hub/modules/Microsoft.FinOpsHubs/Analytics/metadata.bicep Defines typed metadata contract for Analytics app resources (cluster, databases, linked services, datasets)
src/templates/finops-hub/modules/Microsoft.FinOpsHubs/Analytics/app.bicep Consumes Core metadata as parameter; outputs typed metadata; replaced old individual outputs
src/templates/finops-hub/modules/Microsoft.CostManagement/ManagedExports/metadata.bicep Defines typed metadata contract for ManagedExports app pipelines
src/templates/finops-hub/modules/Microsoft.CostManagement/ManagedExports/app.bicep Consumes Core and Exports metadata; uses metadata values throughout pipelines; outputs typed metadata
src/templates/finops-hub/modules/Microsoft.CostManagement/Exports/metadata.bicep Defines typed metadata contract for Exports app resources (containers, datasets)
src/templates/finops-hub/modules/Microsoft.CostManagement/Exports/app.bicep Consumes Core metadata; outputs typed metadata; removed individual container output
src/templates/finops-hub/bicepconfig.json Enabled userDefinedConstraints experimental feature for @validate decorator support
src/scripts/Package-Toolkit.ps1 Enhanced file copying logic to support recursive pattern matching and wildcard destinations
src/scripts/Build-Toolkit.ps1 Added version placeholder replacement in app.bicep files for metadata URLs

@flanakin flanakin added this to the v14 milestone Feb 23, 2026
- Use core metadata for ingestion ID separator instead of local hardcoded value
- Add source folder validation in Package-Toolkit.ps1 manifest processing
- Add changelog entry for typed metadata contracts

🤖 Generated with [Claude Code](https://claude.ai/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@flanakin
Copy link
Collaborator Author

🤖 [AI][Claude] PR Update Summary

Addressed: 3 thread(s)

  • ✅ Implemented: 3
  • 🤔 Needs discussion: 0
  • ❓ Questions: 0

Changes:

  • Analytics app now references core.ingestionIdFileNameSeparator from Core metadata instead of a local hardcoded separator value
  • Added Test-Path validation with descriptive throw in Package-Toolkit.ps1 manifest processing
  • Added v14 changelog entry for typed metadata contracts

@flanakin flanakin enabled auto-merge (squash) February 24, 2026 11:03
@flanakin flanakin added the Tool: FinOps hubs Data pipeline solution label Feb 24, 2026
Copy link
Collaborator

@RolandKrummenacher RolandKrummenacher left a comment

Choose a reason for hiding this comment

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

Review: Metadata contract pattern looks great 👍

The overall approach — replacing implicit dependsOn with typed metadata contracts — is clean and well-structured. All metadata types match their output objects, and the orchestrator in hub.bicep is properly wired up.

A few things that seem to have been missed:

1. Hardcoded 'ingestion_files' in Analytics app.bicep

Around line 1689, there's a hardcoded dataset reference:

referenceName: 'ingestion_files'

All other dataset references in the file use Core metadata (e.g., core.datasets.config on lines 733, 1215). This should be:

referenceName: core.datasets.ingestionFiles

2. Hardcoded 'settings.json' in ManagedExports app.bicep (5 occurrences)

Core metadata already exposes core.settings.file for exactly this purpose, but ManagedExports still hardcodes 'settings.json' in ~5 places (lines ~393, 649, 882, 1687, 1719). For example:

// Current:
defaultValue: 'settings.json'
storagePathEndsWith: 'settings.json'

// Suggested:
defaultValue: core.settings.file
storagePathEndsWith: core.settings.file

3. Minor inconsistency: MSEXPORTS vs exportContainer.outputs.containerName in Exports app.bicep

The CSV dataset on line ~180 correctly uses exportContainer.outputs.containerName for fileSystem, but the gzip (~line 210) and parquet (~line 241) datasets use the hardcoded MSEXPORTS variable. Not a bug, but inconsistent within the same file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs: Review 👀 PR that is ready to be reviewed Tool: FinOps hubs Data pipeline solution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants