pyratelog

personal blog
git clone git://git.pyratebeard.net/pyratelog.git
Log | Files | Refs | README

20220124-make_believe.md (4687B)


      1 A while I ago I saw [this tweet](https://twitter.com/silascutler/status/1353385026994511872?s=19) by @silascutler who was using `make` to run `docker` commands.
      2 
      3 I was intrigued so I made a (very) similar Makefile and tried it when using Docker
      4 ```
      5 override TAG = $(shell basename $$PWD)
      6 VER := latest
      7 IMAGE_ID = $(shell eval sudo docker images -qa ${TAG} | head -n 1)
      8 
      9 .PHONY build test buildtest deploy
     10 
     11 build:
     12 	sudo docker build -t ${TAG}:${VER} .
     13 
     14 test:
     15 	sudo docker run -d ${TAG}:${VER}
     16 
     17 buildtest: build test
     18 
     19 deploy:
     20 	@echo ${IMAGE_ID}
     21 	sudo docker tag ${IMAGE_ID} pyratebeard/${TAG}:${VER}
     22 	sudo docker push pyratebeard/${TAG}:${VER}
     23 ```
     24 
     25 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
     26 ```
     27 make build VER=1.0
     28 ```
     29 
     30 The rest is pretty straight forward.  A new container built from the current directory can be created and started if you incant
     31 ```
     32 make build
     33 make test
     34 ```
     35 
     36 Or you can perform both actions at the same time by incanting
     37 ```
     38 make buildtest
     39 ```
     40 
     41 Pushing your image to your remote repo is as easy as
     42 ```
     43 make deploy
     44 ```
     45 
     46 ## earth shaping in the cloud
     47 
     48 After using this for a while I thought it was working well so I decided to try it with a few other tools.
     49 
     50 I wrote this Makefile for use with `terraform`
     51 ```
     52 NAME := test
     53 VARS := terraform
     54 
     55 .PHONY init plan apply planapply refresh destroy clean
     56 
     57 init:
     58 	terraform init
     59 
     60 plan: init
     61 	terraform plan -var-file=${VARS}.tfvars -out ${NAME}.tfplan
     62 
     63 apply:
     64 	terraform apply -auto-approve -state-out=${NAME}.tfstate ${NAME}.tfplan
     65 
     66 planapply: init plan apply
     67 
     68 refresh:
     69 	terraform refresh -state=${NAME}.tfstate
     70 
     71 destroy: refresh
     72 	terraform destroy -var-file=${VARS}.tfvars -state=${NAME}.tfstate
     73 
     74 clean: destroy
     75 	rm -f ${NAME}.tf{plan,state{,.backup}}
     76 ```
     77 
     78 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.
     79 
     80 To create a "test" plan you incant
     81 ```
     82 make plan
     83 ```
     84 
     85 This will produce `test.tfplan`.  You can then apply this plan by incanting
     86 ```
     87 make apply
     88 ```
     89 
     90 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
     91 ```
     92 make planapply NAME=newtest
     93 ```
     94 
     95 Coming back later you can destroy everything from `newtest.tfplan` if you incant
     96 ```
     97 make destroy NAME=newtest
     98 ```
     99 
    100 This will leave the `newplan.tfstate` file if you wanted to re-apply, or use `make clean` to delete everything.
    101 
    102 ## as you drist
    103 
    104 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](https://log.pyratebeard.net/entry/20210305-the_usefulness_of_drist.html) about it)
    105 ```
    106 SERVER := inventory
    107 FILESDIR = files
    108 
    109 .PHONY patch pkgs create_user ssh_keys new_server sshd_config fail2ban dots secure commission
    110 
    111 env-%:
    112         cd $* ; if [ ! -d ${FILESDIR} ] ; then mkdir ${FILESDIR} ; fi
    113         cp env $*/${FILESDIR}
    114 
    115 patch:
    116         cd patch ; drist ${SERVER}
    117 
    118 pkgs:
    119         cd packages ; drist ${SERVER}
    120 
    121 create_user: env-create_user
    122         cd create_user ; drist ${SERVER}
    123 
    124 ssh_keys:
    125         cd ssh_keys ; drist ${SERVER}
    126 
    127 new_server: env-ssh_keys
    128         cd create_user ; drist ${SERVER}
    129         cd ssh_keys ; drist ${SERVER}
    130 
    131 sshd_config: env-sshd_config
    132         cd sshd_config ; drist ${SERVER}
    133 
    134 fail2ban:
    135         cd fail2ban ; drist ${SERVER}
    136 
    137 dots:
    138         cd deploy_dots ; drist ${SERVER}
    139 
    140 secure: sshd_config fail2ban
    141 
    142 commission: new_server patch pkgs secure dots
    143 ```
    144 
    145 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
    146 ```
    147 make commission SERVER=newhost
    148 ```
    149 
    150 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).
    151 
    152 ## meet the maker
    153 
    154 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.
    155 
    156 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](https://gitlab.com/pyratebeard/makefiles).