Taking Azure Bicep for a Spin – Getting Free SSL Certificates as a Reward


Last year Microsoft apparently finally decided that maybe ARM templates is not going to catch on with the mainstream Azure community, as a result they started working on what I would describe as a spiritual successor which they have named Bicep.

Bicep is a new DSL, domain specific language, that is designed solely to be used to author Azure deployment scripts, that gets converted into ARM templates which then can be deployed to Azure in the same way as we have have deployed ARM templates the last 6 years.

I’m very confused about, why now, people have been complaining about ARM templates since the early days, why Microsoft listens now when people are starting to understand ARM or have just decided to completely ignore them and go with Azure cli, it beyond me. But I have always been a fan of ARM template and its declarative approach to deploying Azure resources, so naturally I’m curious to see what Bicep has to offer. I didn’t jump onto it when it was first released because it was so unfinished and I wasn’t even sure that it was going to stick around. But now it really looks like Microsoft is pouring a lot of energy into making Bicep a viable replacement to ARM templates, so last Saturday I decided to try it out for a few hours.

The version I played with was version 0.3.1, so still a somewhat early version, but it has close to feature parity with ARM templates, so a GA this summer or in the fall seems likely to me.

Test Case – Free SSL Certificates

The best way to try new software, is to use it for building something real. The tasks I wanted use Bicep for was to create a deployment template that can be used to request and setup SSL certificates for Azure Web Sites, using the free managed SSL certificates service that Microsoft provides. Yes, you heard it right, Let’s Encrypt is no longer needed to get free SSL certificates for Azure Web App.

The service is called Azure App Service Managed Certificates, and it has actually been around since November 2019 – but it had one major flaw, it couldn’t be used to request certificates for the naked/apex domain, e.g. it could be used to request certificate for www.mydomain.com but not mydomain.com, which was a bit awkward, as in most cases you would want a SSL certificate for both domains. But since March 2021, this limitation have been lifted (yes the service is still in preview, so use with caution for your high profile web sites).

So what goes into setting up SSL on an Azure Web App. Not much actually it boils down to 3 steps

  1. Getting the hostname bindings configured for your custom domain names (this requires some fiddling with your DNS), so I will leave that out of my template
  2. Requesting the App Service Certificates for your two domain names (assuming that you are just using www.domain.com and the apex domain).
  3. Setting up the SSL binding between the certificates and the web app

So my test case is simply to build a Bicep template that can do step 2 and 3. To make my life a little more challenging I have decided to not place the App Service Plan in the same resource group as the actual Web App. I have decided to go with this setup, as I think it is a pretty common one if you are trying to save money you probably want to cram as many web sites onto the same hosting plan.

So lets take a look at the final bicep template which actually consists of 3 bicep files (main.bicep, sslbindings.bicep and certificate.bicep)


I’m not going to explain the templates in details, as they should be pretty self-explanatory, but I will cover a few of the Bicep specific things I noticed while building the templates.

The ability to break the deployment into multiple smaller files, really helps with the maintainability of a large deployment, but even smaller deployment like this one benefit from it. Yes you could do this with ARM templates, but it was really crappy to work with because your referenced sub-templates had to be located somewhere accessible over https, or they had to be inlined into your main template. With Bicep it just works as you would expect it to, you can reference the sub template from where they are located on your file system. And when the Bicep templates have been transformed into ARM templates, the sub-templates are stored as inlined as sub deployments in the main template.

The verbosity of the templates are reduced, this is often high-lighted by Microsoft as one of the main selling points of Bicep. To me that is a load of BS, if you are an avid user of ARM templates you have a catalog of templates and snippets you copy from, you are not writing them from scratch. I’m expecting it to be the same for Bicep templates. So yes you have to write less curly braces, but really it is a small benefit when most of your templates are copy paste.

To me the main benefit of the new language is the tooling support, I used VS code while creating the templates, and man the support is a lot better already than where we are with ARM templates 6 years in. Obviously this is due to it being a real DSL and not just JSON, but this alone justifies it to me that they are making a new language, they can now make the tooling support we have come to expect from Microsoft which was never really there for ARM templates. A few of the nice benefits I noticed was that the error messages are a lot more specific now, it will catch a lot of things as red squigglies while your are authoring, but also when it transpiles the Bicep file into ARM templates it will give a lot more detailed descriptions when it fails.

The image here shows a few Errors and warnings. The really nice part here is that the errors point to the exact line and character where the issue is. I have spent countless hours hunting for badly formatted JSON based ARM templates, with Bicep that seems to be a thing of the past.

With that said, there is still some way to go for the tooling. The VScode extension isn’t always right sometimes there are red squigglies everywhere although your bicep file is fine. Bicep also seems to be very finicky when it comes to placement of brackets. Example

var certs = [

This is valid bicep code. But the example below is not

var certs = [certificate.outputs.thumbprint1, certificate.outputs.thumbprint2]

The first example is more readable so I understand why they are forcing us down that path, but without auto-correction or linting rules, which there are none of right now (at least not visible in vscode), it is a bit confusing to get errors claiming that your braces are not in the right position.

The bicep files uses a few of the latest additions to the language namely scopes and loops. I struggled a bit with understanding how the scoped was used, something which I needed to be able to deploy to two different resource groups (remember App Service Plan in one and Web App in another). I think once the documentation is better, most new users will not struggle with it, and once you have worked with it once or twice, it is pretty easy to understand, again definitely better than subscription scoped ARM templates.

The looping contruct is also easy to use and pretty much works as you would expect if you are used any programming language in the last 20 years, so no more copyIndex wierdness.

The only thing I didn’t manage to solve in my templates was how to return an array of output parameters. As you might have noticed I have two ugly output parameters from my certificate.bicep file, but I just couldn’t get it to validate my template if I returned the collection object that should be the result of the loop, I might be missing something or it might be a thing that needs to get fixed. If you have a hint let me know!

Update: Microsoft PM Alex Frankel, @adotfrank – was quick and posted a solution, for some reason the Bicep interpreter cannot see that it is an array, but it can be tricked into understand it is an array in one of the two ways


I have to say I’m positively surprised by Bicep, I wish they had made it 5 years ago, then I believe it would have been the defacto standard today. Now I’m not so sure, e.g. at our work pretty much all my colleagues have abandoned ARM templates for scripts that run Azure cli, and I’m not sure Bicep will change that – programmers just love their imperative languages, and ARM which is still underneath Bicep is just hated by so many that it will be hard to win them back.