Skip to content

Add conditional service deployment via condition field#6684

Open
Copilot wants to merge 6 commits intomainfrom
copilot/add-service-deployment-condition
Open

Add conditional service deployment via condition field#6684
Copilot wants to merge 6 commits intomainfrom
copilot/add-service-deployment-condition

Conversation

Copy link
Contributor

Copilot AI commented Feb 2, 2026

Adds support for conditional service deployment in azure.yaml. Services can now specify a condition field with environment variable expansion to control deployment based on runtime configuration.

Changes

ServiceConfig (pkg/project/service_config.go)

  • Added Condition osutil.ExpandableString field supporting envvar expansion
  • Added IsEnabled(getenv) (bool, error) method evaluating truthy values: 1, true|TRUE|True, yes|YES|Yes
  • Returns error for malformed condition templates instead of silently disabling
  • Undefined/empty conditions default to enabled (backward compatible)

ImportManager (pkg/project/importer.go)

  • Added ServiceStableFiltered() method that centralizes condition filtering
  • Filters services based on condition before returning to commands
  • Provides clear error when targeting a disabled service

All Service Commands

  • azd deploy, azd package, azd restore, azd build, azd publish all respect service conditions
  • Services with false conditions are filtered out (no "skipped" messages shown)
  • Targeting a specific disabled service returns error with evaluated condition value

Tests

  • Unit tests for condition parsing and evaluation
  • Integration tests for envvar expansion and YAML parsing
  • Test for malformed condition template error handling

Usage

services:
  api:
    project: ./src/api
    host: containerapp
    
  ml-model:
    project: ./src/ml-model  
    host: ai.endpoint
    condition: ${DEPLOY_ML_MODEL}  # Deployed only when truthy
$ azd env set DEPLOY_ML_MODEL true
$ azd deploy  # Deploys both api and ml-model

$ azd env set DEPLOY_ML_MODEL false
$ azd deploy  # Deploys only api (ml-model filtered out)

$ azd deploy ml-model  # Error: condition evaluates to 'false'
Original prompt

This section details on the original issue you should resolve

<issue_title>Add ability to setup 'condition:' for Service deployment</issue_title>
<issue_description>I'm trying to setup an AZD template that deploys a solution with multiple services, including a service that I want to be deployed only if a specific input parameter to the Azure Bicep is set to 'true'. Such as 'DEPLOY_AML_MODEL' = 'true'. I'm using this to conditionally provision Azure Resources in the 'infra' provisioning. In my case it's an Azure Machine Learning service. I'm using an AZD service to deploy the AML Model, and I'd like to have that model deployment conditional based on if the infra has provisioned the AML service or not.

I'd like to add a 'condition' element to the Service, when evaluated to be 'true' will trigger the deployment, when 'false' it wont deploy the service, like this:

condition: ${DEPLOY_AML_MODEL}

Here's an example of what I'm trying to do when setting up the Azure Machine Learning model deployment within the azure.yaml:

  AMLReranker:
    condition: ${DEPLOY_AML_MODEL}
    project: ./src/amlreranker
    host: ai.endpoint
    config:
      workspace: ${AZURE_AML_WORKSPACE_NAME}
      model:
        path: ./model/
        code_configuration:
          code: ./scoring/
          scoring_script: score_bgev2m3_aml.py
        environment:
          name: bgev2m3-env 
          build: 
            path: ./environment/
        instance_type: STANDARD_D16AS_V4
        instance_count: 1
        request_settings:
          request_timeout_ms: 120000
    dependsOn:
      - infra

It would be really amazing if azd could implement this functionality! Thanks!</issue_description>

<agent_instructions>Add a bool field "condition" to ServiceConfig and make it an expandable osutil.ExpandableString so it can be mapped to env vars.
When this field is defined for the service config, it disables the service if the value in it can't be parsed to a true boolean. For example, values like 1, true, TRUE, True, yes should be parsable to true to activate the service.
But any other value like 0, false, no, or random string should be resolved to false.

Then update the service manager to ignore those services which defines this field with a non-possitive value.

If the field is not defined, the service should be enabled, ensuring backward compatibility.

If the user runs azd depoy foo and foo is a service with the condition false, return an error and tell the user the service requires a possitive value as conditiion to be deployed and its currently false.

If the user runs azd deploy for all services, just skip those with a negativite resolved condition
</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@vhvb1989 related and previous context: https://github.com//issues/3514

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits February 2, 2026 04:23
Co-authored-by: vhvb1989 <24213737+vhvb1989@users.noreply.github.com>
Co-authored-by: vhvb1989 <24213737+vhvb1989@users.noreply.github.com>
Co-authored-by: vhvb1989 <24213737+vhvb1989@users.noreply.github.com>
Copilot AI changed the title [WIP] Add ability to setup condition for service deployment Add conditional service deployment via condition field Feb 2, 2026
Copilot AI requested a review from vhvb1989 February 2, 2026 04:31
@vhvb1989 vhvb1989 marked this pull request as ready for review February 2, 2026 18:06
Copilot AI review requested due to automatic review settings February 2, 2026 18:06
}

// Check if the service condition is enabled
if !svc.IsEnabled(da.env.Getenv) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does condition mean disabled for azd deploy or all service commands?

Copy link
Member

Choose a reason for hiding this comment

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

all service-commands

Copy link
Contributor

Choose a reason for hiding this comment

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

Left a comment here. I think this still needs to be addressed. Initial thoughts would be to have it incorporated into ServicesStable in some fashion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Implemented in c8fa45a. Added ServiceStableFiltered() to ImportManager which applies condition filtering. Now used by all service commands (deploy, package, restore, build, publish).

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 PR adds support for conditional service deployment in azure.yaml, allowing services to be deployed only when a specified condition evaluates to a truthy value. The feature enables runtime-based deployment decisions through environment variable expansion.

Changes:

  • Added Condition field to ServiceConfig with support for environment variable expansion
  • Implemented IsEnabled() method to evaluate conditions based on truthy values (1, true, TRUE, True, yes, YES, Yes)
  • Updated deploy command to skip services with false conditions or error when explicitly targeting a disabled service
  • Added comprehensive unit and integration tests for condition parsing and evaluation

Reviewed changes

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

File Description
cli/azd/pkg/project/service_config.go Added Condition field and IsEnabled() method to support conditional deployment logic
cli/azd/pkg/project/service_config_test.go Added unit tests for condition evaluation with various truthy/falsy values and environment variable expansion
cli/azd/pkg/project/service_condition_integration_test.go Added integration tests for YAML parsing and environment-based condition evaluation
cli/azd/internal/cmd/deploy.go Updated deploy command to check service conditions and provide appropriate error messages or skip disabled services

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 262 to 265
return fmt.Errorf(
"service '%s' has a deployment condition that evaluated to '%s'. "+
"The service requires a truthy value (1, true, TRUE, True, yes, YES, Yes) to be deployed",
svc.Name,
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

When a targeted service has a false condition, the error message could be more actionable by including the condition expression itself, not just the evaluated value. Consider showing both the expression and the evaluated value, e.g., "service 'ml-model' has a deployment condition '${DEPLOY_ML_MODEL}' that evaluated to 'false'". This would help users understand which environment variable needs to be changed.

Suggested change
return fmt.Errorf(
"service '%s' has a deployment condition that evaluated to '%s'. "+
"The service requires a truthy value (1, true, TRUE, True, yes, YES, Yes) to be deployed",
svc.Name,
conditionExpression := fmt.Sprint(svc.Condition)
return fmt.Errorf(
"service '%s' has a deployment condition '%s' that evaluated to '%s'. "+
"The service requires a truthy value (1, true, TRUE, True, yes, YES, Yes) to be deployed",
svc.Name,
conditionExpression,

Copilot uses AI. Check for mistakes.
// Environment variables to set for the service
Environment osutil.ExpandableMap `yaml:"env,omitempty"`
// Condition for deploying the service. When evaluated, the service is only deployed if the value
// is a truthy boolean (1, true, TRUE, True, yes). If not defined, the service is enabled by default.
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The comment should list all accepted truthy values for consistency with the implementation. The implementation accepts "yes", "YES", and "Yes", but the comment only lists "yes". Consider updating to: "is a truthy boolean (1, true, TRUE, True, yes, YES, Yes)".

Suggested change
// is a truthy boolean (1, true, TRUE, True, yes). If not defined, the service is enabled by default.
// is a truthy boolean (1, true, TRUE, True, yes, YES, Yes). If not defined, the service is enabled by default.

Copilot uses AI. Check for mistakes.
Comment on lines 105 to 109
value, err := sc.Condition.Envsubst(getenv)
if err != nil {
// If condition can't be evaluated, consider it disabled
return false
}
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The error handling for malformed condition templates silently disables the service. Consider adding a test case for this scenario to ensure the behavior is intentional and well-documented. For example, a condition like "${UNCLOSED" would return an error from Envsubst, and the service would be disabled without any indication to the user that their template is malformed.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@weikanglim weikanglim Feb 4, 2026

Choose a reason for hiding this comment

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

I think this feedback is really valid -- I believe it's appropriate to surface errors directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Implemented in c8fa45a. IsEnabled() now returns (bool, error) and surfaces malformed template errors directly instead of silently disabling the service.

// If a specific service was targeted but its condition is false, return an error
if targetServiceName != "" && targetServiceName == svc.Name {
da.console.StopSpinner(ctx, stepMessage, input.StepFailed)
conditionValue, _ := svc.Condition.Envsubst(da.env.Getenv)
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The error from Envsubst is being silently ignored. If the condition template is malformed, the error message will show an empty string as the evaluated value, which might be misleading. Consider handling the error explicitly to provide a more informative message to the user, such as "service 'X' has a malformed deployment condition template" when err != nil.

Suggested change
conditionValue, _ := svc.Condition.Envsubst(da.env.Getenv)
conditionValue, err := svc.Condition.Envsubst(da.env.Getenv)
if err != nil {
return fmt.Errorf("service '%s' has a malformed deployment condition template: %w", svc.Name, err)
}

Copilot uses AI. Check for mistakes.
@vhvb1989
Copy link
Member

vhvb1989 commented Feb 2, 2026

@copilot apply changes based on the comments in this thread

Copy link
Contributor

@weikanglim weikanglim left a comment

Choose a reason for hiding this comment

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

Overall, I'm really happy with the direction here. I do believe adding condition support is a good thing. There's been a few user asks along these lines. It is indeed the cheapest way for us to get to a "configurable AST". I'd like to see changes merged to support this feature.

I believe based on our PR discussion earlier, we are thinking the conditional should be applied to all service commands. This should be addressed and I'm waiting for this.

Implementation wise, I'd love us to clean up both implementation and UX -- avoid writing the skipped message (address #4605), and perhaps incorporate the enablement logic into ServicesStable. We can perhaps support a conditional name filter and report if the targetted service was disabled one way or another.

@vhvb1989
Copy link
Member

vhvb1989 commented Feb 5, 2026

@copilot implement comments from this #6684 (review)

…mmands

- Move condition checking from deploy.go into ImportManager.ServiceStableFiltered
- Apply filtering to all service commands (deploy, package, restore, build, publish)
- Return errors for malformed condition templates instead of silently disabling
- When targeting a specific service with false condition, return clear error
- Remove spinner "skipped" messages for disabled services
- Update IsEnabled to return (bool, error) to surface malformed templates
- Add test for malformed condition templates
- Update all tests to handle new IsEnabled signature

Co-authored-by: vhvb1989 <24213737+vhvb1989@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 5, 2026

@copilot implement comments from this #6684 (review)

Implemented in c8fa45a:

  • Condition filtering applied to all service commands via ServiceStableFiltered()
  • No "skipped" spinner messages for disabled services (filtering happens before iteration)
  • Enablement logic incorporated into ImportManager.ServiceStableFiltered()
  • Clear error when targeting a disabled service with condition value shown

Co-authored-by: vhvb1989 <24213737+vhvb1989@users.noreply.github.com>
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.

Add ability to setup 'condition:' for Service deployment

3 participants