Managing Golang Versions with Configuration Management

The latest version of a package may not always be available to your production systems, particularly if they run an LTS release, and the package happens to be the subject of a growing, and developing ecosystem like Golang, where if you want to run a later version on an older, but still supported OS (for example, Go 1.8 on Ubuntu 14.04), your options are using a third-party repository (for example, a PPA to run a version newer than 1.6 on Ubuntu 14.04), or building it from source.

That latter option is, usually, not ideal, and particularly if you want to manage versions a little more dynamically, but configuration management can make this a lot less painful, and a more practical option.

Take, for example, a Saltstack repo with the following structure:

/salt
/salt/app_state
-> app.sls
files/
-> file.tar.gz
/salt/pillar
-> app_state

Let’s start by setting up the pillar to use your desired Go version. In /salt/pillar/app_state set up the following:

app_state:  
lookup:
go_version: 1.8.3

Great. So, now (and you can do this in the state itself, but for the sake of simplicity, we’ll do this step manually) download the archive for the versions you want to manage:

wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz

and you’ll use the above pillar data to select the version to extract to your hosts in the state itself (so you can switch the version in the pillar when you want to affect the state):

In the above example, when you change the pillar to reflect your current working version (for example, you might use different versions in different branches, if you control this in git), it will attempt to extract the version of the archive in the files directory (provided it exists; you can extend the above state, like I said, to handle the download as well, if you’d like).