Simple Scripts Are Better

I'm currently building my new product, Storigible, and where I get stuck is the marketing component of the website. Specifically, the difficult part for me is getting the design right because I don't see myself as a designer 1. All of that aside, what I'm writing about today is the usage of shell scripts versus more complex scripts to automate things like deployment.

Storigible's marketing website is a static website served by Amazon S3. I created it this way because the marketing component can be fully decoupled from the application component (which resides at another subdomain). I needed a good way to deploy the website files onto S3, which is basically saying, I needed a good way to upload the files to S3's server. Deployment isn't much more than a simple copy when you are dealing with a static website.

Originally I looked at using Capistrano for deployment, but then I realized that I shouldn't be so "smart" by using a complex piece of software for such a simple operation. I ended up going with a simple deploy script written in Bash 2 that contains 6 lines (including comments).

#!/bin/bash

# Syncs to S3
# - uses RRS for cost-savings
# - deletes files on S3 that don't exist locally
aws s3 sync build/ s3://storigible.com --storage-class=REDUCED_REDUNDANCY --delete

This script is kept simple because it uses Amazon's S3 command-line utility to perform a sync (like rsync) from the local system to the Production server. It even helps save money by using S3's reduced redundancy format because I can simply reupload any files that are lost/corrupted over time.

Wow. Much simple.

So why do people go to great lengths to use complex automation scripts? It could be that their environment requires something complex (not everyone's use case includes static websites) or, as I have done in the past, it is because using something complex shows how smart one is and how much more of a transferrable skill set one has. I'm guilty of that at times and I work to avoid doing that by using ever more simple tools.

The two added benefits of using simple scripts is that they are easy to read and improve over time 3. I thanked myself for this just today as I needed to deploy the website files to a QA environment instead of Production. I was able to update the shell script to accept an environment target.

#!/bin/bash

# Syncs to S3
# - uses RRS for cost-savings
# - deletes files on S3 that don't exist locally

deploy () {
  target=$1;

  aws s3 sync build/ s3://${target} --storage-class=REDUCED_REDUNDANCY --delete
}

deployQA () {
  deploy "qa.storigible.com"
}

deployProduction () {
  deploy "storigible.com"
}

usage () {
  echo "Usage: $0 ENVIRONMENT"
  echo
  echo "    ENVIRONMENT can be one of: qa, prod"
}

if [ -z "$1" ]; then
  usage
  exit 1
fi

case "$1" in
  qa|QA)
    deployQA
    ;;
  prod|PROD)
    deployProduction
    ;;
  help)
    usage
    ;;
  *)
    echo "Invalid environment target.  Type $0 help for more information."
    exit 1
esac

The shell script is still simple to read (assuming you know Bash) and it now includes proper support for arguments, error handling, and usage output. All in all, this meets my standard of a good script, and it is still under 50 lines of super easy-to-read code.

What I am showing here is that writing code to automate processes doesn't need to be complicated or pull in a bunch of libraries. The script above isn't sexy or even that interesting, it is so trivial that one should look at it and say "so what?", which is exactly what I want. My goal is that I could give this to a system administrator and they will be able to understand it without knowing the least bit of programming.

Footnotes

  1. Not seeing myself as a designer is the first roadblock to overcome. If you allow yourself to be hindered by something then you will only fulfill that fate, further validating your own fears. Just keep trying and eventually things will work out. I'm saying this more for myself than for anyone else. 

  2. The Bash requirement does restrict me to using a Linux or OSX environment, but that's fine with me. 

  3. You'll notice that I use the full argument (--storigible-class) in my shell scripts. This is because I saw the light some time ago after reading an article (can't find it now) that one should use full arguments in shell scripts for readability. Nobody remembers what -s does in a shell script 6 months later without opening up a man page, but everyone will understand what --storigible-class does. That being said, when typing these commands in my terminal, I use the short-form arguments for brevity. 

« Previous: The tinfoil gem