Proposal: Allow Extensions to Define Local Preflight Checks
Summary
This proposal introduces a mechanism for azd extensions to register local preflight checks that azd core runs alongside its own checks before Bicep provisioning. Extension check results are merged into the unified PreflightReport, giving extensions access to the same warning/error/abort UX flow and the rich validation context (Bicep snapshot, resource properties) that core checks use.
This is a continuation of #7053, which established the local preflight validation infrastructure.
Problem
Today, extensions that need to validate deployment preconditions before provisioning have limited options:
-
preprovision event handler — Can only return an error (blocking failure) or succeed silently. There is no way to produce warnings that let the user decide whether to proceed.
-
Init-time validation — Extensions like azure.ai.agents validate manifests during azd agent init, but this happens long before provisioning and cannot inspect the deployment's predicted resource graph.
-
Mimicking the warning UX — Extensions can try to replicate the preflight warning-then-prompt pattern, but the result is inconsistent with core's UX, duplicates logic, and doesn't integrate with telemetry.
None of these approaches give extensions access to the validation context that azd core generates during preflight — the Bicep snapshot (fully resolved resource graph), deployment scope, resource properties, or the consolidated PreflightReport.
Benefits
| Benefit |
Description |
| Unified UX |
Extension warnings and errors appear in the same PreflightReport as core checks — consistent user experience |
| Rich context access |
Extensions can inspect the full predicted resource graph (Bicep snapshot), deployment scope, and derived resource properties |
| User control |
Warnings prompt the user for continuation; errors block — same behavior as core checks |
| Concurrent execution |
Core runs extension checks alongside its own checks — no sequential bottleneck |
| Extension composability |
Multiple extensions can independently contribute checks without coordinating |
| Telemetry integration |
Extension diagnostic IDs flow through the same telemetry pipeline as core diagnostics |
| Delegation to core |
Extensions don't need to implement their own warning/prompt/abort logic — they declare findings and core handles the UX |
Proposed Design
Scope
This proposal targets Bicep-based deployments exclusively. All current core extensions use Bicep, and the preflight infrastructure from #7053 is Bicep-specific.
New Extension Capability: preflight-checks
Extensions declare the capability in extension.yaml:
capabilities:
- preflight-checks
Extension-Side API
Extensions register preflight checks through the extension host, similar to how they register service targets or event handlers:
host := azdext.NewExtensionHost(azdClient).
WithPreflightCheck("agent-manifest-validation", func(ctx context.Context, args *azdext.PreflightCheckArgs) (*azdext.PreflightCheckResult, error) {
// Access the Bicep snapshot resources
for _, res := range args.SnapshotResources {
if strings.EqualFold(res.Type, "Microsoft.MachineLearningServices/workspaces") {
// Validate extension-specific requirements
if !hasRequiredConfig(res) {
return &azdext.PreflightCheckResult{
Severity: azdext.PreflightWarning,
DiagnosticID: "azure.ai.agents/missing-workspace-config",
Message: "AI workspace is missing required identity configuration.",
}, nil
}
}
}
return nil, nil // all good
})
gRPC Contract
New proto messages for the preflight request/response:
message PreflightCheckRequest {
// Deployment scope information
string subscription_id = 1;
string resource_group = 2;
string location = 3;
// Bicep snapshot: fully resolved predicted resources
bytes snapshot_resources_json = 4;
// Derived resource properties
ResourceProperties properties = 5;
}
message PreflightCheckResponse {
// nil/empty = check passed
repeated PreflightCheckResultItem results = 1;
}
message PreflightCheckResultItem {
string diagnostic_id = 1; // e.g. "azure.ai.agents/missing-config"
PreflightSeverity severity = 2; // WARNING or ERROR
string message = 3;
}
enum PreflightSeverity {
PREFLIGHT_WARNING = 0;
PREFLIGHT_ERROR = 1;
}
message ResourceProperties {
bool has_role_assignments = 1;
// Extensible for future derived properties
}
Core-Side Integration
In BicepProvider.validatePreflight():
- Discover extensions that declare the
preflight-checks capability
- Send the
PreflightCheckRequest with snapshot resources and deployment scope to each extension
- Run extension checks concurrently with core checks (with a timeout)
- Merge extension
PreflightCheckResultItems into the PreflightReport alongside core results
- Apply the same UX flow: warnings prompt, errors block
azd provision
├── Compile Bicep module → ARM template + parameters
├── ► Local preflight validation
│ ├── Generate Bicep snapshot
│ ├── Analyze resources (derive properties)
│ ├── Run core checks (e.g., role_assignment_permissions)
│ ├── Run extension checks (concurrent, gRPC) ← NEW
│ │ ├── Extension A: preflight check results
│ │ └── Extension B: preflight check results
│ └── Merge all results into PreflightReport
│ ├── Warnings → prompt user
│ └── Errors → abort
├── Server-side preflight (Azure ValidatePreflight API)
└── Deploy
Example: AI Agents Extension
The azure.ai.agents extension could use this to validate:
- Agent manifest references match predicted resources in the Bicep snapshot
- Required identity/RBAC configuration is present for AI workspaces
- Required dependent services (e.g., Azure OpenAI, Bing Search) are included in the deployment
Instead of failing during deploy or relying on init-time checks, these validations would surface as warnings before the user commits to a potentially long provisioning operation.
Relationship to #7053
This proposal builds directly on the preflight infrastructure established in #7053:
- The
PreflightCheck / PreflightCheckFn / validationContext pattern is the foundation
- The
PreflightReport UX component handles the merged output
- The warning/error/abort flow and exit code behavior remain unchanged
- No breaking changes to existing preflight behavior — this is purely additive
The key change is extending the check registration from internal-only (localPreflight.AddCheck()) to include extension-contributed checks via gRPC.
Proposal: Allow Extensions to Define Local Preflight Checks
Summary
This proposal introduces a mechanism for azd extensions to register local preflight checks that azd core runs alongside its own checks before Bicep provisioning. Extension check results are merged into the unified
PreflightReport, giving extensions access to the same warning/error/abort UX flow and the rich validation context (Bicep snapshot, resource properties) that core checks use.This is a continuation of #7053, which established the local preflight validation infrastructure.
Problem
Today, extensions that need to validate deployment preconditions before provisioning have limited options:
preprovisionevent handler — Can only return an error (blocking failure) or succeed silently. There is no way to produce warnings that let the user decide whether to proceed.Init-time validation — Extensions like
azure.ai.agentsvalidate manifests duringazd agent init, but this happens long before provisioning and cannot inspect the deployment's predicted resource graph.Mimicking the warning UX — Extensions can try to replicate the preflight warning-then-prompt pattern, but the result is inconsistent with core's UX, duplicates logic, and doesn't integrate with telemetry.
None of these approaches give extensions access to the validation context that azd core generates during preflight — the Bicep snapshot (fully resolved resource graph), deployment scope, resource properties, or the consolidated
PreflightReport.Benefits
PreflightReportas core checks — consistent user experienceProposed Design
Scope
This proposal targets Bicep-based deployments exclusively. All current core extensions use Bicep, and the preflight infrastructure from #7053 is Bicep-specific.
New Extension Capability:
preflight-checksExtensions declare the capability in
extension.yaml:Extension-Side API
Extensions register preflight checks through the extension host, similar to how they register service targets or event handlers:
gRPC Contract
New proto messages for the preflight request/response:
Core-Side Integration
In
BicepProvider.validatePreflight():preflight-checkscapabilityPreflightCheckRequestwith snapshot resources and deployment scope to each extensionPreflightCheckResultItems into thePreflightReportalongside core resultsExample: AI Agents Extension
The
azure.ai.agentsextension could use this to validate:Instead of failing during deploy or relying on init-time checks, these validations would surface as warnings before the user commits to a potentially long provisioning operation.
Relationship to #7053
This proposal builds directly on the preflight infrastructure established in #7053:
PreflightCheck/PreflightCheckFn/validationContextpattern is the foundationPreflightReportUX component handles the merged outputThe key change is extending the check registration from internal-only (
localPreflight.AddCheck()) to include extension-contributed checks via gRPC.