Bicep Variables

Variables in Bicep store calculated or composed values that the template uses internally. A variable cannot receive input from outside — it is always computed from other values already available in the file. Variables reduce repetition, improve readability, and make complex expressions easier to maintain.

Think of a variable like a sticky note. Instead of writing a long calculation on every page of a document, write it once on a sticky note and reference that note wherever needed. Change the sticky note once, and every reference updates automatically.

Parameters vs Variables – The Key Difference

+-----------------------------------------------------+
|         Parameters vs Variables                     |
+--------------+-------------------------------------+
|  Feature     |  param          |  var              |
+--------------+-----------------+-------------------+
|  Input       |  From outside   |  Inside file only |
|  (at deploy) |  (user/pipeline)|  (computed)       |
+--------------+-----------------+-------------------+
|  Purpose     |  Customization  |  Reuse & clarity  |
+--------------+-----------------+-------------------+
|  Changeable  |  Yes, per       |  No, fixed at     |
|  at deploy   |  deployment     |  file level       |
+--------------+-----------------+-------------------+
|  Default     |  Optional       |  Always required  |
|  value       |                 |                   |
+--------------+-----------------+-------------------+

Basic Variable Syntax

var <variableName> = <value or expression>

Variable declarations use the var keyword followed by a name, an equals sign, and a value. No data type is declared — Bicep infers the type from the value automatically.

var prefix = 'myapp'
var environment = 'prod'
var instanceCount = 3
var enableLogs = true

String Interpolation in Variables

String interpolation combines string text with variable or parameter values using the ${} syntax. This is the most common reason to use variables — building resource names from multiple parts.

param environment string = 'prod'
param appName string = 'orderservice'

// Build a consistent naming pattern
var storageName = 'st${appName}${environment}'
var appServiceName = 'app-${appName}-${environment}'
var keyVaultName = 'kv-${appName}-${environment}'

When environment = 'prod' and appName = 'orderservice', the variables produce:

storageName    = 'storderserviceprod'
appServiceName = 'app-orderservice-prod'
keyVaultName   = 'kv-orderservice-prod'

Variables with Built-in Functions

Variables become powerful when combined with Bicep's built-in functions. One of the most common use cases is generating unique resource names using uniqueString().

// uniqueString generates a 13-character hash from the resource group ID
// The hash is the same every time for the same resource group
var uniqueSuffix = uniqueString(resourceGroup().id)

// Combine with a prefix to create a unique storage account name
var storageAccountName = 'storage${uniqueSuffix}'

The uniqueString() function produces the same result every time it runs against the same resource group. This means re-deploying the template always produces the same name — no duplicate resources are created accidentally.

Object Variables

Variables can store entire objects. This is especially useful for tags, configuration blocks, and settings that appear across multiple resources.

param environment string = 'production'
param project string = 'e-commerce'

// Define tags once as a variable
var commonTags = {
  environment: environment
  project: project
  managedBy: 'Bicep'
  costCenter: 'IT-001'
}

// Apply the same tags to multiple resources
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: 'mystorage001'
  location: 'eastus'
  tags: commonTags    // reuse variable here
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}

resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
  name: 'my-app-plan'
  location: 'eastus'
  tags: commonTags    // same variable reused here
  sku: {
    name: 'B1'
  }
}

Without the commonTags variable, the same tag object would need to be written inside every resource block. Changing a tag value would require editing every resource individually — a maintenance risk.

Array Variables

// List of allowed IP addresses for a firewall rule
var allowedIpAddresses = [
  '203.0.113.10'
  '198.51.100.25'
  '192.0.2.100'
]

// List of subnet names
var subnetNames = [
  'frontend-subnet'
  'backend-subnet'
  'database-subnet'
]

Variables That Reference Other Variables

Variables can build on each other. Later variables can reference earlier variables in the same file.

param appName string = 'webapp'
param environment string = 'dev'

// Base naming prefix
var namingPrefix = '${appName}-${environment}'

// Resources named using the prefix variable
var storageNameFull = 'st${replace(namingPrefix, '-', '')}001'
var appServiceNameFull = 'app-${namingPrefix}'
var keyVaultNameFull = 'kv-${namingPrefix}'

Conditional Variable Values

A variable can take different values based on a condition using the ternary operator (condition ? valueIfTrue : valueIfFalse).

param environment string = 'prod'

// Choose the SKU based on environment
var storageSku = environment == 'prod' ? 'Standard_GRS' : 'Standard_LRS'

// Choose instance count based on environment
var instanceCount = environment == 'prod' ? 3 : 1

// Choose whether HTTPS is enforced
var httpsOnly = environment == 'prod' ? true : false
Logic Diagram – Conditional Variable

environment == 'prod'?
        │
   ┌────┴────┐
  YES       NO
   │         │
Standard   Standard
  _GRS       _LRS

Complete Example – Variables in a Real Template

// Parameters
param location string = 'eastus'
param appName string = 'inventoryapp'
param environment string = 'staging'

// Variables
var namingPrefix = '${appName}-${environment}'
var uniqueSuffix = uniqueString(resourceGroup().id)
var storageAccountName = 'st${replace(namingPrefix, '-', '')}${take(uniqueSuffix, 4)}'
var appServicePlanName = 'asp-${namingPrefix}'
var webAppName = 'app-${namingPrefix}'
var storageSku = environment == 'prod' ? 'Standard_GRS' : 'Standard_LRS'

var commonTags = {
  application: appName
  environment: environment
  managedBy: 'Bicep'
}

// Resources using variables
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageAccountName
  location: location
  tags: commonTags
  sku: {
    name: storageSku
  }
  kind: 'StorageV2'
}

resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
  name: appServicePlanName
  location: location
  tags: commonTags
  sku: {
    name: 'B1'
  }
}

resource webApp 'Microsoft.Web/sites@2023-01-01' = {
  name: webAppName
  location: location
  tags: commonTags
  kind: 'app'
  properties: {
    serverFarmId: appServicePlan.id
  }
}

Naming Rules for Variables

RuleCorrect ExampleIncorrect Example
Start with a letter or underscorevar appName, var _configvar 1appName
Use camelCase for readabilityvar storageAccountNamevar storageaccountname
No spaces in namevar namingPrefixvar naming prefix
No Bicep keywords as namesvar resourceNamevar resource
Descriptive namesvar storageAccountNamevar x, var temp

When to Use Variables vs Parameters

Decision Guide
──────────────

Does the value change between deployments?
│
├── YES ──► Use a PARAMETER
│           (e.g., environment name, location, SKU)
│
└── NO ───► Is the value calculated from other values?
            │
            ├── YES ──► Use a VARIABLE
            │           (e.g., resource names, tags, derived config)
            │
            └── NO ────► Use a LITERAL directly in the resource block
                         (e.g., a fixed API version, a constant kind)

Summary

Variables in Bicep store computed values that the template uses internally. They reduce repetition, enforce consistent naming, and make templates easier to read and maintain. Variables work with strings, integers, booleans, objects, and arrays. Combining variables with built-in functions like uniqueString() and the ternary operator makes Bicep templates intelligent and environment-aware.

Leave a Comment