Webhooks

I spent some time configuring automatic deployments for a previous version of this website.
Here is how I did it.

Assumptions

update.php

This should get deployed in the webroot for your domain.
Something like /var/www/domain.com or /var/www/vhosts/...
Forgive the extra whitesapce in the php open tag, it seems like I have found a bug in prism.js where if you put valid php in this block it will get run by the browser.

< ?php
require 'secretfile.php';
list($algo, $hash) = explode('=', $_SERVER['HTTP_X_HUB_SIGNATURE']);
$payload = file_get_contents('php://input');
$data = json_decode($payload);
$payloadHash = hash_hmac($algo, $payload, $secret);
if ($hash !== $payloadHash) {
  header("HTTP/1.0 404 Not Found");
  exit;
}
exec("sudo salt-call --local state.highstate &> /var/www/website.com/logs/git.log", $output);
print_r($output);
?>
  

secretfile.php

Make sure this is not in your git repository.
Also make sure that it is not saved in a directory that your webserver is serving.

  
< ?PHP
$secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
?>
    

sudoers

We need to allow the webserver user permisiions to run the salt hightstate, but we dont want it to be too open.
So we restrict the webserver to just running the specific salt command to run the highstate.
Add these two lines to /etc/sudoers on your webserver.

  
Cmnd_Alias WEBHOOK = /usr/bin/salt-call --local state.highstate
www-data ALL = (ALL) NOPASSWD: WEBHOOK
      

Make sure these changes get reflected in your highstate or the next time salt runs this will all break. My next post will most likely be about this topic.

And then add a git webhhook with:

  
Payload URL: http://website.com/update.php
Content type: application/x-www-for-urlencode
Secrect: xxxxxxxxxxxxxxxxxxxx from the above secretfile.php script
    

Now to test this all we need to do is push a commit to our git repository and the webhook will reach out and run the php script that will in turn run the saltstack highState.

  
echo 'hello' > /path/to/DocumentRoot/testfile.html
git add -A
git commit -m 'testing deployments'
git push
    

Now we check to see if our new page got pushed. curl http://domain.com/testfile.html

That should return the following.

  
hello
    

You can find more information about github webhooks here.