Late last year, I first heard about Project Bicep at Ignite 2020 and it's goals of how it bring improvements to the current ARM template development experience. After a recent update on Project Bicep, I thought about getting it started rightaway after watching a video by Microsoft on Microsoft DevBlogs.
What is Project Bicep?
Bicep is a Domain Specific Language (DSL) for deploying Azure resources declaratively. It aims to drastically simplify the authoring experience with a cleaner syntax and better support for modularity and code re-use. It's a next generation tooling for ARM templates! Warning:
Project Bicep is still in experimental preview and not advisable for production yet.
Project Bicep is still in experimental preview and not advisable for production yet.
Thoughts about current ARM templates experience
- When I initially started ARM template development, I find it difficult to understand without a proper documentation to refer - until today!
- I usually have more than one templates that needs almost a similar modules (e.g. ServerFarm, Storage, Certificates, etc.). All the time, copy & paste is the only solution which does not adhere to DRY principle and I repeat myself on every templates.
-
Assigning parameters or variables needs
[...]
syntax. Template functions(e.g.concat
) can get really complicated if you have more than three strings to combine which ends up as[concat(parameters('first'), parameters('second'), parameters('third'))]
- If you're building templates from scratch, you can easily make mistakes by missing quotes, indent, etc as the usual JSON problems.
- No proper type safety(e.g.
string
) validation can only be tested after running the Azure resource deployment. - Via Intellisense, when describing ARM templates, it does not provide an idea of the required fields.
Getting started
I've been trying to learn Bicep for a couple of weeks now and how it can improvise my ARM template development experience. During this progress, I've the recorded the steps to get started and I could achieve it in less than 10 minutes.Pre-requisite
- Installing Bicep with guide
- Try out Bicep playground for learning with community examples
Azure Static Web App example
In order to get started, I started building my first.bicep
file using Visual Studio Code as the Bicep extension
provides the intellisense to build the .bicep
. Please refer the example below for creating bicep for Azure Static Web App.
main.bicep
param name string // param is equivalent to parameters in ARM template
param location string
param sku string
param skucode string
param repositoryUrl string
param branch string
param repositoryToken string {
secure: true // helps to secure the string from printing out confidential information
}
param appLocation string
param apiLocation string
param appArtifactLocation string
var simpleVariable = 'for example' // var is equivalent to variables in ARM template
resource static_site 'Microsoft.Web/staticSites@2020-06-01' = { // static_site here refers as resource identifier to ease dependsOn implementation
name: name // parameter assignment is equivalent to [parameters('name')] in ARM template
location: location
properties: {
repositoryUrl: repositoryUrl
branch: branch
repositoryToken: repositoryToken
buildProperties: {
appLocation: appLocation
apiLocation: apiLocation
appArtifactLocation: appArtifactLocation
}
}
sku: {
tier: sku
name: skucode
}
}
Once you are done and happy with the bicep file, on your Visual Studio Code terminal you can run the below
Terminal
> bicep build ./main.bicep
Upon a successful build, the bicep cli will transpiles the code to main.json which is your ARM template.
main.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"sku": {
"type": "string"
},
"skucode": {
"type": "string"
},
"repositoryUrl": {
"type": "string"
},
"branch": {
"type": "string"
},
"repositoryToken": {
"type": "string"
},
"appLocation": {
"type": "string"
},
"apiLocation": {
"type": "string"
},
"appArtifactLocation": {
"type": "string"
}
},
"functions": [],
"variables": {
"simpleVariable": "for example"
}
"resources": [
{
"type": "Microsoft.Web/staticSites",
"apiVersion": "2020-06-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"properties": {
"repositoryUrl": "[parameters('repositoryUrl')]",
"branch": "[parameters('branch')]",
"repositoryToken": "[parameters('repositoryToken')]",
"buildProperties": {
"appLocation": "[parameters('appLocation')]",
"apiLocation": "[parameters('apiLocation')]",
"appArtifactLocation": "[parameters('appArtifactLocation')]"
}
},
"sku": {
"tier": "[parameters('sku')]",
"name": "[parameters('skucode')]"
}
}
]
}
You can now deploy this template via Powershell commands
Powershell
> az deployment group create -f ./main.json -g my-rg
Okay, how about your existing ARM templates, can you convert it into
.bicep
format? YES, you can!
Terminal
> bicep decompile ./main.json
Things have become so much easier now with Project Bicep help where you can now start generating ARM template with Project Bicep!
How does Project Bicep solves?
- Breaking part of templates to separate modules is the best improvement. I don't need to repeat myself anymore for common templates (e.g. ServerFarm, Storage, Certificates, etc.)
-
Visual studio Code intellisense able to provide your the properties that needs to be configured by using CTRL + Spacebar
-
Type safety validation is so much better now as it provides real-time validation for incorrect input
- Much lesser code compared as you can see the examples above that it has cut half the size(32 lines of code) of the development experience.
-
Developer experience is unified. I love the idea of assigning parameter as simple as assigning with equals(=) sign.
To join two strings, it can be done as easy as
'${prefix}_site'
which brings a unified experience similar to string interpolation.
Limitations
I believe before it turns out to be a production use, there are couple of things which I anticipate that bicep can help to solve:- Current Intellisense experience with Visual Studio Code still has places to improve (e.g. providing intellisense types of locations)
-
The moment we selected a resource (e.g.
'Microsoft.Web/staticSites@2020-06-01'
), if it can auto-generate basic boiler plate code on the pre-requisite parameters and default values, that would be very handful for users like me to kickstart quickly. With the current experience, CTRL + Spacebar can still be achieved but it does not provide a full experience of the values can be configured. - Deployments are done separately via Powershell today. It will look great if bicep cli can offer deployments as well.