As a DevOops professional, I’m always excited to experiment with the latest tooling available. This week, we take a look at Bicep, which is a domain specific language (DSL) created by Microsoft to assist with the creation of Azure Resource Manager (ARM) templates.
At a very high level, there are two types of programming languages. General purpose languages (GPLs) are the programming languages you are most familiar with. Things like Ruby, Python, C#, Go, etc all fall in to this category. These programming languages are broadly applicable across various application domains, which is just a fancy way of saying you can use them to solve lots of problems in lots of contexts.
A domain specific language (DSL), on the other hand, is a language created fit for a small subset of purposes. The line between GPLs and DSLs is blurry at the best of times. Examples of DSLs would include things like Sed, Gawk, SQL, HTML, etc.
Bicep was created for one reason, to assist in the creation of ARM templates. This makes it a DSL for creating ARM templates. You can read the official docs here.
Bicep is effectively an application that converts templates written in the Bicep DSL to an ARM template. At this point, technically speaking, the ARM template becomes an Intermediate Language (IL) much like bytecode is for compiled languages. You can then work with the ARM template as you normally would (by submitting it to Azure for processing, or framing it on your wall).
At time of writing, bicep only has a single command build.
Here is a sample bicep file that:
You can read about the directives used here.
param location string = resourceGroup().location
param aadLoginName string
param aadLoginSid string
param aadLoginTenant string
param clientIpAddress string
// Generic DB Settings
var databaseName = 'sample-db-with-tde'
var databaseEdition = 'Basic'
var databaseCollation = 'SQL_Latin1_General_CP1_CI_AS'
var databaseServiceObjectiveName = 'Basic'
var sqlServerName = 'sqlserver${uniqueString(resourceGroup().id)}'
// -----------------------------------------
// Security Settings, no touchey!
// -----------------------------------------
var minTlsVersion = '1.2' // Should always be latest supported TLS version
var transparentDataEncryption = 'Enabled' // Why would you ever disable this?
var sqlAdministratorLogin = 'user${uniqueString(resourceGroup().id)}' // Using AAD auth, so create random user
var sqlAdministratorLoginPassword = 'p@!!${uniqueString(resourceGroup().id)}' // Using AAD auth, so create random pw
resource sqlServer 'Microsoft.Sql/servers@2019-06-01-preview' = {
name: sqlServerName
location: location
properties: {
administratorLogin: sqlAdministratorLogin
administratorLoginPassword: sqlAdministratorLoginPassword
version: '12.0'
minimalTlsVersion: minTlsVersion
}
}
resource db 'Microsoft.Sql/servers/databases@2019-06-01-preview' = {
name: '${sqlServer.name}/${databaseName}'
location: location
properties: {
edition: databaseEdition
collation: databaseCollation
requestedServiceObjectiveName: databaseServiceObjectiveName
}
}
resource tde 'Microsoft.Sql/servers/databases/transparentDataEncryption@2014-04-01-preview' = {
name: '${db.name}/current'
properties: {
status: transparentDataEncryption
}
}
resource aadLogin 'Microsoft.Sql/servers/administrators@2019-06-01-preview' = {
name: '${sqlServer.name}/aadLogin'
properties: {
administratorType: 'ActiveDirectory'
login: aadLoginName
sid: aadLoginSid
tenantId: aadLoginTenant
}
}
resource fwRule 'Microsoft.Sql/servers/firewallRules@2015-05-01-preview' = {
name: '${sqlServer.name}/fwRule1'
properties: {
startIpAddress: clientIpAddress
endIpAddress: clientIpAddress
}
}
As you can see from the above, Bicep feels like an interesting mix between YAML and some other object-like templating language. A couple of observations:
YAY! I can finally add comments in a useful way to my template files to communicate valuable information to others running it
I like the lack of braces and other syntax elements required to create parameters and variables. While not shown in the example above, you can make your parameters complex (adding defaults and allowed values, etc). Just have a look at the docs.
Bicep seems to auto calculate inputs to be either variables or parameters. This means you cannot have the same name defined in both sections (this generates a “compiler” error).
In conclusion, I plan to fool around a bit more with Bicep before I pass any judgment. By the end of the year Bicep should be ready for “production use” and be on feature parity with ARM, which will be nice.
If I had to give feedback right now, I’d say that I’d want to see the bicep code expanded so that I don’t have to deal with the intermediate ARM template files at all. Effectively, I’d want to be able to run
New-AzResourceGroupDeployment -TemplateFile blah.bicep
and have it do all the build/conversion steps required.
 
Shamir is a Microsoft Most Valuable Professional (MVP – Azure) and has extensive experience building solutions in the cloud, from strategy to deployment to automation