The usual way to manage Azure resources is to open the Azure portal and click everything. Do you want a new App Service? Click and it’s there. Need a place to store uploaded images? Click ‘add new Storage Account’ and there you go. You can start uploading images to new blob. And what if you need a new SQL Server DB for your data? Just click the button, wait five to ten minutes and you are all set up J. You have your new dev environment for your awesome project. Everything is great right?
And then do the same for testing, QA, and production. And did you hear about the possibility of having a short-lived environment for each development branch? Suddenly, even this simple 3 service setup doesn’t look so cool. This is where Infrastructure as Code comes to save us. And I would like to show you one little project I particularly like – Farmer.
To understand what Farmer is, first you need to have a basic understanding of the nature of Azure Resource Manager.
Similar to AWS’s CloudFormation, Azure has its own Infrastructure as Code (IaC) framework named Azure Resource Manager (ARM).
ARM templates use JSON to define Azure resources in a declarative way. Within a template, you can use special template expressions that extend the capabilities of JSON. These expressions use the Resource Manager’s functions such as parameters, variables, or even user-defined functions. The deployment process then converts the template to a series of REST API calls to create final resources.
You can do everything with it on Azure, but it also has a few disadvantages.
It’s incredibly verbose. The example above is maybe as simple as possible, and it still takes over ten lines of code to define. When you start combining multiple resources, setting parameters, and so on, it rapidly gets enormous.
Another strong argument against useing ARM directly is that it is not statically checked, compiled, and contains many magic strings you need to use, like values of “type” and “location” properties in an example.
For that reason, I think it’s better to look for some solution that uses your programming language of choice. For me, that language is F#, and thankfully there is one library that is just perfect for the job.
Created by Compositional IT, Farmer utilises the power of F# and its computation expressions to define your Azure resources and generate ARM templates.
A template defined using Farmer is just normal F# code and can be run as an application or inside a F# script. That means that you can create complex structure of functions to generate your desired infrastructure. Names of the services, and as a matter of fact every service parameter, can be injected as parameters from a configuration. Thanks to this it is easy to create a copy of the infrastructure for the QA/production environments.
This is the same example as before but created using Farmer. Much simpler, isn’t it?
F# is a succinct language, so even the most complex infrastructure definition will most likely fit in a single file. This can be a big benefit when you are onboarding new team members, since they will be able to understand it quickly. Even our customers can read this kind of code and we can discuss the changes using a single document.
Because everything is just a F# code every value is strongly typed. The only string in the example is the name of the service. The result of such an expression is an instance of an object and when you want to define relationships and dependencies between the resources it is as easy as assigning a value to a field.
No, not at all. Just do it J. If you already have some infrastructure defined some other way there is no need to throw it all away and start over with Farmer.
In the end the result of a Farmer program is an ARM template file so you can just integrate that into you existing pipeline. And if you don’t have a pipeline at all you can create one. It’s a better way to do things anyway J
Nothing is just rainbows and butterflies. Even a project as awesome as Farmer has some.
For me the main one is that it does not support all the services in Azure. But they are trying. Did I mention that the whole project is open source? So, if you are missing some service support or just some configuration value, nothing is stopping you from creating a pull request. They are fast with feedback. If pull requests are not your cup of tea, Compositional IT even provide commercial support.
The second issue is that Farmer does not support ARM parameters and variables. They have their own reasoning about that. But because the whole ARM template is just a F# program anyway it is easy to work around that and have such logic implemented outside of an ARM template.
Even if there are much larger alternatives such as Pulumi or Terraform, there is still place for project like Farmer. It doesn’t have all the bells and whistles of its competitors. It does not support multiple cloud providers or programming languages. It’s simple, and straightforward. It does one thing and does it great. If you are just starting to experiment with Infrastructure as Code frameworks, I think Farmer is a great first step. If you are an experienced developer in this field, it is a good tool to have in your toolbelt.