A while I ago I saw this tweet by @silascutler who was using make
to run docker
commands.
I was intrigued so I made a (very) similar Makefile and tried it when using Docker
override TAG = $(shell basename $$PWD)
VER := latest
IMAGE_ID = $(shell eval sudo docker images -qa ${TAG} | head -n 1)
.PHONY build test buildtest deploy
build:
sudo docker build -t ${TAG}:${VER} .
test:
sudo docker run -d ${TAG}:${VER}
buildtest: build test
deploy:
@echo ${IMAGE_ID}
sudo docker tag ${IMAGE_ID} pyratebeard/${TAG}:${VER}
sudo docker push pyratebeard/${TAG}:${VER}
This Makefile will use the directory name as the container tag if not specified. I did it that way so I can have one Makefile and symlink it into every project directory. The version is set to “latest” unless declared with the command
make build VER=1.0
The rest is pretty straight forward. A new container built from the current directory can be created and started if you incant
make build
make test
Or you can perform both actions at the same time by incanting
make buildtest
Pushing your image to your remote repo is as easy as
make deploy
After using this for a while I thought it was working well so I decided to try it with a few other tools.
I wrote this Makefile for use with terraform
NAME := test
VARS := terraform
.PHONY init plan apply planapply refresh destroy clean
init:
terraform init
plan: init
terraform plan -var-file=${VARS}.tfvars -out ${NAME}.tfplan
apply:
terraform apply -auto-approve -state-out=${NAME}.tfstate ${NAME}.tfplan
planapply: init plan apply
refresh:
terraform refresh -state=${NAME}.tfstate
destroy: refresh
terraform destroy -var-file=${VARS}.tfvars -state=${NAME}.tfstate
clean: destroy
rm -f ${NAME}.tf{plan,state{,.backup}}
Using this Makefile I can init, plan, and apply a terraform state with one command. I can also manage multiple plans in the same directory.
To create a “test” plan you incant
make plan
This will produce test.tfplan
. You can then apply this plan by incanting
make apply
If you then wanted to use the same variables file (terraform.tfvars) to create another plan and apply it without losing test.tfplan
you can incant
make planapply NAME=newtest
Coming back later you can destroy everything from newtest.tfplan
if you incant
make destroy NAME=newtest
This will leave the newplan.tfstate
file if you wanted to re-apply, or use make clean
to delete everything.
Then I got more adventurous and decided to write a Makefile for use with my drist
modules (if you’re not sure what drist
is you can read my post about it)
SERVER := inventory
FILESDIR = files
.PHONY patch pkgs create_user ssh_keys new_server sshd_config fail2ban dots secure commission
env-%:
cd $* ; if [ ! -d ${FILESDIR} ] ; then mkdir ${FILESDIR} ; fi
cp env $*/${FILESDIR}
patch:
cd patch ; drist ${SERVER}
pkgs:
cd packages ; drist ${SERVER}
create_user: env-create_user
cd create_user ; drist ${SERVER}
ssh_keys:
cd ssh_keys ; drist ${SERVER}
new_server: env-ssh_keys
cd create_user ; drist ${SERVER}
cd ssh_keys ; drist ${SERVER}
sshd_config: env-sshd_config
cd sshd_config ; drist ${SERVER}
fail2ban:
cd fail2ban ; drist ${SERVER}
dots:
cd deploy_dots ; drist ${SERVER}
secure: sshd_config fail2ban
commission: new_server patch pkgs secure dots
There seems like a lot there but it should be fairly easy to figure out. I normally run this when I have built a new server and want to “commission” it with my settings
make commission SERVER=newhost
This will create a user and upload my ssh public keys, update the system (patch) and install a set of packages which I always want to have. It will then set a preconfigured sshd config file, install and configure fail2ban, and deploy my user configurations (dotfiles).
Using make
like this will probably make a lot of people shudder. I don’t use it for everything but after trying the above I found writing a simple Makefile was slightly quicker than writing a wrapper script, and it’s another way for me to confuse coworkers that like buttons over text.
If you like this idea I would be interested to see what other tools people use Makefiles for. If you think the above can be improved let me know or raise a Gitlab merge request.