If you’ve been working with Azure for more than a few months, you’ll find that deploying resources with the portal is a tedious, time consuming and, at times, a frustrating excercise. It’s the best starting point you can get, because the portal will show you a lot of options and offers a easy learning curve. But when you need to deploy a number of resources that are more or less the same, you’ll soon want to automate this.
Why IaC?
There are a number of reasons why you want to use IaC.
First of all, as I said in the intro, redoing the same steps over and over becomes tedious and prone to mistakes. We’re still human, remember ;).
If you have to deploy a solution to just a production environment, you might get away with doing it in the portal. But when you have to deploy a Sandbox, Development, Test, Acceptance and Production environment, your carpal tunnel syndrome will act up. Whereas with code, you can define the environments and let it loop through all the needed resources. Every environment is the same. Or, you can prepare your code in a way that non-production has less expensive resources.
Second major point of using IaC is traceability. Because you can (and in my opinion have to) store your code into a DevOps solution. This way you can make sure your code is validated before deployment and it’s clear who made the change, when it was made and why. Yes it takes some getting used to it but you’ll learn to love it.
If you work in a team, it’s way easier to transfer work to someone else. You can point to the code and tell them where you left off. They can pick it up from that point. If you only work with the portal, you’ll have to download the template (if possible) and work from there or keep clicking around. And that’s tedious, boring work.
What are your options?
There are quite a lot of options available. To be honest, I haven’t tried all of these out in depth, but I have tried all of them at times. Each option has it’s own way of working and some drawbacks. Spoiler alert, there’s not one best method. Every resource or combination of resources has it’s own best solution, besides the fact that you’ve got to find a language you’re comfortable with.
Powershell or Bash
When you’re logged in at the portal, you can either use the PowerShell or Bash console in the Command Line Interface (CLI). The main advantage of these is that all they need is a place to store some stuff. After that, you’re ready to go and the examples you find on the Microsoft site all fit into that console. No need to install stuff and if you’re lucky you’re logged in into the correct tenant and subscription. But please, always check this.
The main disadvantage is the time-out of the console. This means that if your scripts takes too much time to finish, the console will stop. This happens after 20 minutes of inactivity from your side. In the background, processess may or may not continue or finish. So it’s very useful for quick scripts containing new deployments or modifications.

Visual Studio Code
Although it is possible to use git with the portal CLI, it’s not intuitive. Using a tool like Visual Studio Code will make this a whole lot easier. It’s got integrated git support (github, gitlab and Azure Devops) and you can run your code from this awesome tool. Seriously, I can’t work without it anymore, though I regularly use Windows Terminal as a second screen to keep the output at hand.
If you want to run powershell on your own system, you’ll need to install the azure commandlets. Not a big deal, unless your company policy prevents this. Always check if you’re allowed to install software before you do this. You can run bash from VSCode too.
ARM Templates
Azure has it’s own deployment language called ARM. These are templates in a kind of JSON format that contain all the information needed to deploy resources. When you dive into these templates, it all gets overwhelming quite quickly. To alleviate this, Microsoft came up with Bicep (part of the arm ;)).
Bicep
This is a much easier language that resembles both JavaScript and JSON. It takes a bit of time to get used to but there are a number of advantages to be found here. You can use modules to create resources and a central file with variables you can call from the commandline. With loop constructions you can create similar resources without coding everything over and over again. Downsides are that the language doesn’t support all resources yet. I’ve hit some walls when deploying a KeyVault in the west europe region and joining to existing resources in different resource groups is a bit of a hassle. Also after deployment you might have to comment some elements to prevent errors when modifying your deployment.

Terraform
Then there’s Terraform (Terrorform when things don’t go the way you want). Like Bicep a statefull deployment language but with it’s own quirks. When you create a number of resources with dependencies, Terraform won’t check those during deployment. It just fires off all the scripts and then returns errors when certain dependecies aren’t met. If you build your environment from the ground up, you can manually make sure dependencies are met. Terraform likes passwords to be coded into the files. You can hide them, but they’re logged. Make sure to only use temporary passwords as they can’t be encrypted as far as i know. Terraform offers the option to import existing resources to start managing them centrally and has a cloud service that removes the need to locally save credentials.
Looping is possible but takes some weird code, just like if-then-else constructs.

Major differences between the languages
There are, of course, a number of major differences between the languages. Because PoSh is different to Bash and so forth.
The major thing that makes Bicep stand out from other languages is that you can create dependencies in the code. If your VNet needs a new resource group, you can code it like that. Other languages require you to deploy in the correct order. I like it that I can prepare the code, set the dependencies and fire off the entire deployment.
Something I personally like less is the fact that Bicep doesn’t check the state of the subscription. If you delete a resource from your code, it will remain in your resource group. The really strong point of Terraform is that it has a state. Delete something in the code and it disappears from the resourcegroup. This way I’m sure my code matches the environment. Again something I really like, because I can delete stuff from code and I don’t have to log into the environment and delete stuff manually.
Both Bicep and Terraform use files where you can script out an entire environment. You can do that with Powershell or Bash as well but it’s more of a commandline task where you keep running different commands in a row (serial deployment) where the other languages can deploy in parallel.
Poll
I was wondering what my friends from the sql family are using, so I started a poll. I was expecting one tool or technique to really jump out. But from the 22 replies, this were the results:

Powershell/Bash code has an advantage over the others, but bear in mind that many people in the SQL community are (rightfully) in love with the Powershell DBA Tools. This might lower the threshold to deploy stuff to Azure with Powershell because of the familiarity with the language. Also I’ve been told that Powershell is the first level that receives the updates from the platform, followed by ARM/Bicep and Terraform. If you need the latest and greatest, PoSh is the way to go.
Resources
Bicep is the latest deployment language by Microsoft and that’s what the early adopters are working with. People like Rob Sewell are already providing pre-con sessions on this to give you an enormous head start. If you’re able to attend this session you’ll learn a great deal. Heini Illmarinen has an excellent session on the basics of Terraform that will show you how easy most things are. Again, if you can catch her session do it. Unfortunately she hasn’t got her own blog (yet) but provided some very good links to share with you:
Fear of oblivion
SQL DBA with a beard (and yes, you’ve seen his name a few lines above)
My advice? Try all of them to get some footing. What are your requirements, what do you like and don’t you like. Start small, begin with a resource group, network, VM and a SQL Database. Check out all the options and what happens when you deploy all at once or in stages. If you’re comfortable with the basics, try and expand in a direction your work is taking you. Before you know it, you might call yourself an expert.
Thanks for reading and if you want to share your experiences, I’d love to hear them!