AWS Elastic Beanstalk is a fantastically easy way to deploy simple to medium complexity apps with confidence and ease. We have been using it exclusively at Kounta to deploy our web application and other services.

Recently we have started creating services in Go, or at least one service in Go. Beanstalk was an obvious choice. Beanstalk does support Go but unfortunately only supports up to Go 1.4, which for a lot of us is just a tad too old.

There are a few ways to get a newer Go version on Beanstalk. You can use a preconfigured docker container or compile the app yourself as a linux executable and deploy the binary alone.

Both of these options require more work than we would have liked. We wanted to be able to specify the Go version with the deploy and change versions reliably and easily. The simple solution is to download the Go binaries as part of your deploy process.

When you deploy the application in Beanstalk make sure you select a stack that is already preconfigured for Go. At the time of writing this that was v1.4. Now you can use a Buildfile. The Buildfile (case-sensitive, sits in the root of your project) lets you run one or more custom scripts in parallel to compile your application. It is as simple as one line:

build: ./build.sh

The build.sh (in this case also in the root of your project, but you can put it anywhere you like) is where all the action is at:

#!/usr/bin/env bash

# Fail immediately if any of the commands below fail.
set -x

# Display the existing Go info before we change it.
go version
echo GOROOT=$GOROOT
echo GOPATH=$GOPATH

# Install a newer version of Go.
GOGZ=go1.6.2.linux-amd64.tar.gz
curl -O "https://storage.googleapis.com/golang/$GOGZ"
tar -zxf $GOGZ
rm $GOGZ

export GOROOT=/usr/local/go
export GOPATH=$GOROOT/bin
rm -rf $GOROOT
mv go $GOROOT
export PATH=$GOPATH:$PATH

# Make sure we are now using the newer version.
go version
echo GOROOT=$GOROOT
echo GOPATH=$GOPATH

# Move the application into the correct package for $GOPATH.
rm -rf $DEST
mkdir -p $DEST
cp -r * $DEST # NOTE: must be 'cp', not 'mv' here.

# Install/update dependencies.
go get -u gopkg.in/redis.v3
go get -u github.com/Sirupsen/logrus
go get -u gopkg.in/yaml.v2

# Build the server. Beanstalk will look for an 'application' executable.
cd $DEST
go build -o application
chmod +x application
mv application /usr/bin

If you use this script as a base you really only need to be aware a few lines:

  • GOGZ=go1.6.2.linux-amd64.tar.gz: This is the name of the download, simply change this to get a different version - but make sure you specify the linux distribution.
  • DEST=$GOROOT/src/github.com/your/package: You will need to move your source into the appropriate package folder.