Azure Bicep Basics
· 5 min read
in-progress AzureBicep
What is Azure Bicep
Bicep is a declarative language that is used to deploy Azure recourses.
Bicep file sections
// 1. TARGET SCOPE (optional, defaults to resourceGroup)
targetScope = 'resourceGroup'
// 2. PARAMETERS (inputs to your template)
param parameterName type = defaultValue
// 3. VARIABLES (reusable values within the file)
var variableName = expression
// 4. RESOURCES (the actual Azure infrastructure)
resource symbolicName 'resourceType@apiVersion' = { ... }
// 5. OUTPUTS (values returned after deployment)
output outputName type = value
1. Target Scope
The target scopes defines at what level of the azure hierarchy the bicep file will operate at.
// Three possible values:
targetScope = 'resourceGroup' // Default - deploys TO a resource group
targetScope = 'subscription' // Deploys ACROSS subscriptions
targetScope = 'managementGroup' // Deploys across multiple subscriptions
2. Parameters
This is what makes the templates reusable, this allows the file to accept input values. Basically when deploying the parameters the console will ask for user input.
The basic Syntax of a parameter is:
param <name> <type> = <defualtValue>
parameter types available:
| Type | Description | Example | | ———— | ———————— | ————————- | | string | text values | ‘eastus’ | | int | Numbers | 100 | | bool | ture/false | true | | array | List of values | [‘value’,’value’] | | object | Dictionary of properties | {key: “value”} | | secureString | String encrypted at rest | used for passwords | | secureObject | Object encrypted at rest | used for sensitive values |
Decorators & Metadata decorators
Metadata decorators are basically comments and decorators constraint/validation rules you attach to a declaration. This is useful to control or limit the behavior of deployment or even block wrong value deployments. Some common decorators are:
| Decorator | Description |
|---|---|
| @allowed([…]) | Restricts the parameters to specific values |
| @minValue( ) | Create a minimum value for int input |
| @maxValue( ) | Create a maximum value for int input |
| @minLength( ) | Create a minimum value for string input |
| @maxLenght( ) | Create a maximum value for string input |
| @secure( ) | Makes a parameter a secret. (never logged, stored, and is encrypted in deployment state) |
| @discriminator(‘type’) |
Pure metadata decorators:
| Decorator | Description |
|---|---|
| @decription( ) | Helps create humen readable docs and shows up as text when you run a interactive deployment. |
| @metadata({ }) | Key value pairs that basically work as tags to key information and infrastructure organized |
3. Variables
Variables are named values used inside a template to improve readability and to avoid repetition. The basic syntax of a variable is:
var <name> = <experesion>
Example:
//retreves the resourcesGroupes location and assigns it to the veriable location
var location = resourceGroup().location
Common built-in Functions used with variables
| Function | Purpose | Example |
| — | — | — |
| resourceGroup() | Gets info about current resource group | resourceGroup().location |
| subscription() | Gets subscription info | subscription().subscriptionId |
| uniqueString() | Creates unique string | uniqueString(resourceGroup().id) |
| toLower() / toUpper() | Case conversion | toLower('NAME') → ‘name’ |
| concat() | Joins strings | concat('prefix-', 'suffix') |
| length() | Gets array/string length | length(arrayVar) |
| if() | Conditional expression | if(condition, trueValue, falseValue) |
4. Resources
This is where you declare the azure infrastructure. The basic syntax for declaring a resource:
resource <symbolicName> '<resourceType>@<apiVersion>' = {
name: '<resourceName>'
location: '<location>'
<properties>: {...}
}
5. Child Resources
Child recourses are resources that are part of another resource and are dependent that the parent resource exists. For example a Virtual network and a subnet. The subnet can’t exist without the virtual network.
resource sqlServer 'Microsoft.Sql/servers@2022-05-01-preview' = {
name: sqlServerName
location: location
properties: {
administratorLogin: adminUser
administratorLoginPassword: adminPassword
}
// Child resource nested inside parent
resource database 'databases' = {
name: databaseName
location: location
sku: {
name: 'Basic'
}
}
}
6. Modules
Modules allow you to break down complex deployments into smaller more manageable files. In other works instead of declaring all the whole deployment in one file, you can declare them in multiple smaller files. The basic module structure is:
// main.bicep (parent)
module storageModule './storage-account.bicep' = {
name: 'deploy-storage-${uniqueString(resourceGroup().id)}'
params: {
storageAccountName: storageName
location: location
sku: 'Standard_LRS'
}
}