Automate Bitbucket in a Saltstack Workflow

For folks who manage their infrastructure via salt deploys via manual machine updates can be tedious and error prone. I initially met this need with a terribly hacky bash script that would prompt the developer to figure out what needed to be done. After some exploration I was able to come up with a better setup below:


salt 2015.5.3 (Lithium) with reactor configured running SSL and the hook api configured to not require auth. Note that this means that you need to secure your request or only support requests that don’t harm your environment bitbucket (web-based) 2.0 API

Gather environmental variables

You’ll need the following details from your environment  

#Project Full Name We use this to build out the git config and identity config 
# Project shortname This should be a unique alphanumeric name to allow salt to act on the right state. 
#Project UUID you can find it with this curl -u '$USERNAME:$PASSWORD' "$FULLNMAE" 
#Salt hook endpoint 
SALTHOOK=https://$SALT:8000/hook # or similar

Setup webhooks

Bitbucket will notify salt via a webhook that a change has been made to a repo. I explicitly use the bitbucket/request resource to help target and allow more granular changes in the future. You can do this on any major state you prefer. I use an accepted merge here but you can find out all of your options at Also note you may need to change SSL cert recognition for the created webhook if you have self-signed certs or certs bitbucket can’t find a trust chain for.

curl -u '$USERNAME:$PASSWORD' -s -d '{ 
 "description" : "SaltPush", 
 "url" : "https://$SALTHOOK/bitbucket/request", 
"events" : [ 
"active": "true" } '$FULLNAME/hooks

Setup reactor config

You’ll need to add the following to your salt-master config to support the new bitbucket config

  - 'salt/netapi/hook/bitbucket/*':
    - /etc/salt/reactor/bitbucket.sls

Restart your salt master and you’ll now have the ability to recognize the incoming bitbucket requests. Inside the bitbucket.sls you’ll need to drop in the following data. Modify the tgt command to match the nodes you need the state to run on in your environment.

{% set build = data.get('post', {}) %}
{% if build.repository.uuid == "$UUID" %}
    - tgt: 'I@gitrepos:$SHORTNAME and I@gitenv:{{ }}'
    - expr_form: compound
    - arg:
      - git.$SHORTNAME
{% endif %}

This file is the equivalant of all requests that match the repo $UUID run this command

salt -C 'I@gitrepos:$SHORTNAME and I@gitenv:{{ }}' state.sls git.$SHORTNAME

Once you’ve added the sls file you should be ready to start deploying the state defined. If you have any troubles stop the master and minion on the target host and restart them in debug mode and look for issues.

Leave a Reply

Your email address will not be published. Required fields are marked *