Apply puppet automatically

Posted 03.01.2013 · 2 min read

I recently started using github web interface as editor for my puppet configuration. I wanted to be able to push a new configuration without doing it manually, as I do not have a puppet master I wanted to try using Github hooks as in the Github lamp code. I have the puppet-repo cloned to /puppet/ and the main manifest is in /puppet/manifests/site.pp. The code below is the web.py script. It checks the payload from Github and will only apply the configuration if changes are pushed to the master branch. A GET request would simply get a 404.

from fabric.api import local, lcd
import web, json
urls = (
'/', 'GithubHook',
)
render = web.template.render('.')
class GithubHook:
def POST(self):
data = json.loads(web.input().payload)
if 'ref' in data:
if data['ref'] == 'refs/heads/master':
with lcd('/puppet/'):
local('git pull origin master')
local('puppet apply /puppet/manifests/site.pp')
print "applied puppet"
else:
print "ref: %s" % data['ref']
else:
print "no ref"
return ""
def GET(self):
raise web.notfound()
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
application = web.application(urls, globals(), True).wsgifunc()

I running this with uWSGI and Nginx in front. To make the setup a little more secure I added deny all and allow to Github's IP-addresses.

server {
listen 80;
server_name puppet.example.com;
access_log /var/log/nginx/puppet_apply.access.log;
error_log /var/log/nginx/puppet_apply.error.log;
location / {
allow 207.97.227.253;
allow 50.57.128.197;
allow 108.171.174.178;
deny all;
proxy_pass http://127.0.0.1:9060;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location = /favicon.ico {
access_log off;
log_not_found off;
return 204;
}
}

The web.py script is in /home/web/puppet_apply/puppet_apply.py. The ini-file used by uWSGI is below.

[uwsgi]
chdir = /home/web/puppet_apply
virtualenv = /home/web/puppet_apply/venv
pythonpath = /home/web/puppet_apply
procname-prefix = puppet_apply
daemonize=/var/log/uwsgi/puppet_apply.log
wsgi-file = /home/web/puppet_apply/puppet_apply.py
http-socket = 0.0.0.0:9060
master = True
processes = 1