Bicep Conditions

Conditions in Bicep control whether a resource gets created during a deployment. Using the if keyword inside a resource declaration, a resource deploys only when a specified condition is true. This enables one Bicep file to serve multiple environments without creating separate templates for each one.

Think of a condition like a checkbox on a form. When the checkbox is ticked, that item is included in the order. When unchecked, it is skipped. Bicep conditions work exactly the same way — tick a flag for production, and the production-only resources appear automatically.

Condition Syntax

resource <symbolicName> '<ResourceType>@<ApiVersion>' = if (<condition>) {
  name: '<resourceName>'
  location: '<region>'
  <properties>
}

The if (condition) clause sits between the equals sign and the opening curly brace. When the condition is true, Azure creates the resource. When the condition is false, Azure skips the resource entirely.

Simple Condition Example

param environment string = 'prod'
param location string = 'eastus'

// Deploy the Azure CDN Profile only in production
resource cdnProfile 'Microsoft.Cdn/profiles@2023-05-01' = if (environment == 'prod') {
  name: 'cdn-myapp-prod'
  location: location
  sku: {
    name: 'Standard_Microsoft'
  }
}
Condition Flow Diagram

environment == 'prod'?
         │
    ┌────┴────┐
   true      false
    │         │
    ▼         ▼
 CREATE     SKIP
 CDN        CDN
 Profile    Profile

When deploying with environment = 'dev', the CDN Profile is not created. When deploying with environment = 'prod', it is created. The same template works for both environments.

Using a Boolean Parameter as a Condition

The clearest way to control resource creation is with a dedicated boolean parameter. The name of the parameter describes exactly what it does.

param location string = 'eastus'
param deployDiagnostics bool = false
param storageAccountName string = 'mystorage2024abc'

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}

// Deploy diagnostics settings only when the flag is true
resource diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (deployDiagnostics) {
  name: 'diag-${storageAccountName}'
  scope: storageAccount
  properties: {
    metrics: [
      {
        category: 'Transaction'
        enabled: true
      }
    ]
  }
}

Deploy with diagnostics:

az deployment group create \
  --resource-group myRG \
  --template-file main.bicep \
  --parameters deployDiagnostics=true

Deploy without diagnostics (default):

az deployment group create \
  --resource-group myRG \
  --template-file main.bicep

Conditions with Expressions

Conditions can evaluate any Boolean expression — not just simple equality checks.

param environment string = 'staging'
param enableBackup bool = true
param location string = 'eastus'

// Deploy backup vault only when BOTH conditions are true
resource backupVault 'Microsoft.DataProtection/backupVaults@2023-01-01' = if (environment == 'prod' && enableBackup) {
  name: 'bv-myapp-prod'
  location: location
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    storageSettings: [
      {
        datastoreType: 'VaultStore'
        type: 'LocallyRedundant'
      }
    ]
  }
}
Compound Condition

environment == 'prod'  AND  enableBackup == true
         │                        │
    ┌────┴────┐              ┌────┴────┐
   true      false          true      false
    │                        │
    └──── Both must be true ─┘
              │
         ┌────┴────┐
        true      false
         │         │
         ▼         ▼
      CREATE     SKIP
      Backup     Backup
      Vault      Vault

Condition with OR Logic

param environment string = 'staging'

// Create a Log Analytics workspace in staging OR production
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2023-09-01' = if (environment == 'staging' || environment == 'prod') {
  name: 'log-myapp-${environment}'
  location: 'eastus'
  properties: {
    retentionInDays: 30
  }
}

Multiple Resources with Conditions

param location string = 'eastus'
param environment string = 'prod'
param appName string = 'myapp'

var isProd = environment == 'prod'
var isNotDev = environment != 'dev'

// Always deployed
resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
  name: 'asp-${appName}-${environment}'
  location: location
  sku: {
    name: isProd ? 'P1v3' : 'B1'
  }
}

// Always deployed
resource webApp 'Microsoft.Web/sites@2023-01-01' = {
  name: 'app-${appName}-${environment}'
  location: location
  kind: 'app'
  properties: {
    serverFarmId: appServicePlan.id
  }
}

// Only in staging and production
resource appInsights 'Microsoft.Insights/components@2020-02-02' = if (isNotDev) {
  name: 'ai-${appName}-${environment}'
  location: location
  kind: 'web'
  properties: {
    Application_Type: 'web'
  }
}

// Only in production
resource redisCacheServer 'Microsoft.Cache/redis@2023-08-01' = if (isProd) {
  name: 'cache-${appName}-prod'
  location: location
  properties: {
    sku: {
      name: 'Basic'
      family: 'C'
      capacity: 0
    }
  }
}
Resource Deployment Matrix

Resource           | dev | staging | prod
─────────────────────────────────────────
appServicePlan     |  ✓  |    ✓    |  ✓
webApp             |  ✓  |    ✓    |  ✓
appInsights        |  ✗  |    ✓    |  ✓
redisCacheServer   |  ✗  |    ✗    |  ✓

Referencing a Conditionally Deployed Resource

When another resource needs to reference a conditionally deployed resource, the conditional check must match. Otherwise, a deployment that skips the resource will fail when another resource tries to reference it.

param environment string = 'prod'
param location string = 'eastus'

var isProd = environment == 'prod'

resource redisCacheServer 'Microsoft.Cache/redis@2023-08-01' = if (isProd) {
  name: 'cache-myapp-prod'
  location: location
  properties: {
    sku: {
      name: 'Basic'
      family: 'C'
      capacity: 0
    }
  }
}

// Only configure the app to use Redis when it actually exists
resource webApp 'Microsoft.Web/sites@2023-01-01' = {
  name: 'app-myapp-${environment}'
  location: location
  kind: 'app'
  properties: {
    serverFarmId: appServicePlan.id
    siteConfig: {
      appSettings: isProd ? [
        {
          name: 'REDIS_CONNECTION'
          value: redisCacheServer.properties.hostName
        }
      ] : []
    }
  }
}

Conditions vs Ternary Operator – When to Use Each

ScenarioUseExample
Entire resource should be created or skippedif (condition) on the resourceDeploy Redis only in prod
A property value changes based on a conditionTernary operator inside the propertySKU is P1v3 in prod, B1 in dev
A variable takes different valuesTernary operator in the variablevar replicas = isProd ? 3 : 1
// Full resource condition – entire resource appears or not
resource redis 'Microsoft.Cache/redis@2023-08-01' = if (isProd) { ... }

// Property condition – resource always exists, property value changes
resource appPlan 'Microsoft.Web/serverfarms@2023-01-01' = {
  name: 'asp-myapp'
  sku: {
    name: isProd ? 'P1v3' : 'B1'   // ternary inside the property
  }
}

Conditions in Parameter Files

Boolean parameters used as conditions work perfectly with environment parameter files:

// dev.bicepparam
using 'main.bicep'
param environment = 'dev'
param deployDiagnostics = false
param deployRedis = false

// prod.bicepparam
using 'main.bicep'
param environment = 'prod'
param deployDiagnostics = true
param deployRedis = true

The same Bicep template deploys a lightweight dev environment and a full production environment by switching only the parameter file.

Summary

Conditions in Bicep use the if (condition) clause on a resource declaration to control whether that resource is created. Conditions accept any Boolean expression including equality checks, logical AND/OR operators, and Boolean parameters. Combining conditions with parameter files makes a single Bicep template serve multiple environments cleanly. Use full resource conditions when a resource should be completely absent in some environments, and the ternary operator when only a property value changes.

Leave a Comment