Bicep makes Azure Resource Management a great deal simpler than ARM templates. The selling point here is grokkability. This post takes a look at the "Hello World" example recently added to the Bicep repo to appreciate quite what a difference it makes.
More than configuration
The "Hello World" added to the Bicep repo by Chris Lewis illustrates the simplest usage of Bicep:
This bicep file takes a
yourName
parameter and adds that to ahello
variable and returns the concatenated string as an ARM output.
This is, when you consider it, the very essence of a computer program. Taking an input, doing some computation and providing an output. When I think about ARM templates, (and because Bicep is transpiled into ARM templates I mentally bracket the two together) I tend to think about resources being deployed. I focus on configuration, not computation
This is an imperfect mental model. ARM templates can do so much more than deploy by slinging strings and numbers. Thanks to the wealth of template functions that exist they have much more power. They can do computation.
The Hello World example focuses just on computation.
From terse to verbose
The Hello World example is made up of two significant files:
main.bicep
- the bicep codemain.json
- the ARM template compiled from the Bicep file
The main.bicep
file amounts to 3 lines of code (I have omitted the comment line):
param yourName string
var hello = 'Hello World! - Hi'
output helloWorld string = '${hello} ${yourName}'
- the first line takes the input of
yourName
- the second line declares a
hello
variable - the third line computes the new value of
helloWorld
based uponhello
andyourName
, then passes it as output
Gosh is it ever simple. It's easy to read and it's simple to understand. Even if you don't know Bicep, if you've experience in another language you can likely guess what's happening.
Let's compare this with the main.json
that main.bicep
is transpiled into:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "dev",
"templateHash": "6989941473549654446"
}
},
"parameters": {
"yourName": {
"type": "string"
}
},
"functions": [],
"variables": {
"hello": "Hello World! - Hi"
},
"resources": [],
"outputs": {
"helloWorld": {
"type": "string",
"value": "[format('{0} {1}', variables('hello'), parameters('yourName'))]"
}
}
}
The above ARM template expresses exactly the same thing as the Bicep alternative. But that 3 lines of logic has become 27 lines of JSON. We've lost something in the transition. Intent is no longer clear. We've gone from something easy to reason about, to something that is hard to reason about. You need to think a lot less to write the Bicep alternative and that's a good thing.
I was chatting to someone recently who expressed it well by saying:
ARM is the format that the resource providers understand, so really it’s the Azure equivalent of Assembler – and I don’t know anyone who enjoys coding in Assembler.
This is a great example of the value that Bicep provides. If you'd like to play with the Hello World a little, why not take it for a spin in the Bicep playground.