Sometimes we find ourselves with modern day problems, that have 100-year old solutions that still work great 🙂 I find this is the case with Makefiles. I want to explain in this article how simple Makefiles can make working with cloud deployment templates more easy for both experienced and new users.
Each of these providers has their own deployment template language – with AWS it’s CloudFormations templates, with Azure it’s ARM templates, with GCP, there are Deployment Manager templates. Each of these effectively do the same thing, that is to define a deployment as code (ie, infrastructure as code).
Defining deployments and infrastructure as code has many advantages, most notably, making it easy to repeat and iterate on with improvements. However, it can be really tedious to keep running commends like;
cloud-deployment-tool -f mytemplate.json -g myGroup -e production ...
…not to mention it’s quite error prone and difficult for other users in your team to get started with. Introducing our 100-year old solution that still works great.
Introduction to Makefiles
Makefiles were created a long time ago, okay, maybe not quite 100 years ago, but if you’ve used any Linux/Unix like operating system you’ve probably bumped into them. They’re intended to be used much like scripts, but were specifically designed for building source code. When working with source code, there are many common operations like cleaning out old artifacts, building a new version and updating some metadata files. Programmers use Makefiles to automate these common operations, let me show you a quick example;
clean: rm -rf bin/ build: gcc myprogram.c update: echo date &gt; VERSION.txt .PHONY: clean build update
Implementing this for the Cloud Provider’s templates
So, how can we use these Makefiles for each of the cloud providers? Lets Look at each example indvivdiaully.
Azure (ARM Template)
user@host: tree ├── Makefile ├── myDeployment.parameters.json └── myDeployment.json
So, lets take a look at what this Makefile might look like to go with the arm template (myDeployment.json) and the parameters file (myDeployment.parameters.json). We define 3 simple goals; validate, deploy, clean and a helper goal, retry.
validate: az group deployment validate --resource-group myGroup --template-file myDeployment.json --parameters @myDeployment.parameters.json deploy: az group deployment create --resource-group myGroup --template-file myDeployment.json --parameters @myDeployment.parameters.json clean: az group delete -n myGroup az group create -n myGroup --location "West Europe"
That’s it! very simple. Of course you’d need to have the az command installed and authenticated, but Makefiles provide for really nice shortcuts as you can see.
Under development 😐
user@host: tree ├── Makefile └── awsTemplate.json
GCP (Deployment Manager)
Under development 😐
user@host: tree ├── Makefile └── gcpTemplate.json
Why don’t I just use a bash script?
You absolutely could just use a bash script, the principle is almost the same. However, as the number of goals/shortcuts you has increases, bash scripts tend to get messy fast. Why bother writing code to check which goal needs to run when Makefiles do this by default as well? Just unneeded complexity in most cases. Of course you could separate your goals into separate bash scripts, like ./deploy.sh, ./clean.sh, and similar, but you’re going to get a couple of scripts over time. Makefiles keep everything in one place that is very easy to use.
Summary: What does this get me?
Using simple makefiles with these complex deployment templates makes your deployments a little more human-friendly. Others in your team can share these templates and not worry so much about “which parameters do I need?”, or simply “how do I run this?”. When you get a little more used to using these templates as well, you can feel more confident that you can re-run these easily, efficiently, and without changing the parameters each time – this makes your deployments far more repeatable.
If you get further down the road of integrating CI (like Jenkins) into your deployments, these Makefiles can make your build jobs a lot more easy and repeatable there as well. Give it a try – an old tool used for a new purpose!