For all of my personal projects deployment is always a nightmare. I get wrapped up in building something exciting and I forget that it will need to run elsewhere. When I get to the point that I'm ready to share my creation with the world I set aside a weekend for deployment. My deployment is always a tedious and error-prone slog. A vast majority of that time is untangling the mess I created last time. I have decided that it is time to find a better solution.

This is a common problem and there are many solutions. The myriad of choices is also part of the reason I have waited so long to dive in. In the past I have investigated some solutions: custom bash scripts, Chef, and Puppet. None of these solutions felt natural. The bash scripts simplified the archaeological portion of my deployments, but were still ad hoc and incomplete. Chef is difficult to get started with since the first step is 'install a server' (or even worse, pay us for one. Puppet and Chef also offer enterprise editions which creates an uncomfortable (and often ambiguous) dichotomy in features, documentation, and community.1

The next tool on my list is Salt. Salt has technical and social advantages over the previous tools. Chef and Puppet try to abstract away the distributed nature of the environment, similar effect to running commands over ssh.2 Salt uses a master/minion3 paradigm and 0mq to handle communication asynchronously. The asynchronous message queue and processes running on each node allow for faster deploys without relying on hacks like parallel-ssh. Salt is also completely open source not just 'open core'. This choice has helped grow the developer/user community and is a significant reason I am learning it.

My first project with salt is to deploy a git server with a web interface. I have been running GitLab for 2 years. It works, but I do not need many of the features (users & permissions, wiki, task management, ...) so I have been on the lookout for a new tool.4 After some experimentation on my local system I have decided to use cgit5 with nginx and Arch Linux.

Installing all of the necessary packages was simple enough thanks to Arch's excellent package manager pacman. One additional package is necessary for this setup, fcgiwrapper, a bridge between nginx and cgit. Specifically the service that it provides to manage a socket that cgit and nginx use for communication. One problem, someone decided to name the service fcgiwrapper.socket. Why is this a problem? Salt uses . as a delimiter for locating functions in states.

Here is the offending sls file:

fcgiwrap:
  pkg:
    - installed
  require:
    - pkg: nginx
  service:
    - name: fcgiwrap.socket
    - enable: True
    - running: True

This is the error produced by running salt \* state.highstate:

srctest05:

        Data failed to compile:
    ----------
        No function declared in state "service" in sls fcgiwrap

Solution: convince salt to eat up a period before hitting the service's name attribute. This solution works because Salt's parser only interprets the first period, passing the rest through unaltered.

Here is the corrected file:

fcgiwrap:
  pkg:
    - installed
  require:
    - pkg: nginx
  service.running:
    - name: fcgiwrap.socket
    - enable: True

After this tweak I am now able to repeatably and automatically deploy cgit to an Arch Linux machine. Thanks to retrospek in the Salt IRC channel for suggesting the fix.6 I look forward to more explorations with salt and interactions with the community.


  1. Noah Kantrowitz elegantly explains the sentiment https://coderanger.net/chef-open-source/

  2. Ansible has a similar, albeit improved, structure to Chef and Puppet. 

  3. a.k.a. master/slave for the less sensitive 

  4. I am also offended by their decision to switch to a split model (Consumer and Enterprise). The focus on providing enterprise features and partitioning the developer time has deteriorated the quality of the Consumer edition's documentation and limited external developer contributions. For evidence of the hypocrisy see the contrasting blog posts: GitLab 3.0 Released and Announcing GitLab Enterprise Edition

  5. maintained by Jason Donenfeld, the developer of one of my favorite projects, pass

  6. Salt IRC Log 18 July 2014.