diff --git a/states/apache/init.sls b/states/apache/init.sls
new file mode 100644
index 0000000..f40322b
--- /dev/null
+++ b/states/apache/init.sls
@@ -0,0 +1,38 @@
+apache:
+ pkg.installed:
+ - name: apache2
+
+apache_cgi_module:
+ apache_module.enabled:
+ - name: cgi
+
+apache_cgid_module:
+ apache_module.enabled:
+ - name: cgid
+
+apache_remoteip_module:
+ apache_module.enabled:
+ - name: remoteip
+
+apache_rewrite_module:
+ apache_module.enabled:
+ - name: rewrite
+
+apache_ssl_module:
+ apache_module.enabled:
+ - name: ssl
+
+apache_disable_default_site:
+ apache_site.disabled:
+ - name: 000-default
+
+apache_disable_default_ssl_site:
+ apache_site.disabled:
+ - name: default-ssl
+
+apache_service:
+ service.running:
+ - name: apache2
+ - enable: True
+ - require:
+ - pkg: apache2
diff --git a/states/mercurial/hg.lunch.org.uk.conf b/states/mercurial/hg.lunch.org.uk.conf
new file mode 100644
index 0000000..0fea9be
--- /dev/null
+++ b/states/mercurial/hg.lunch.org.uk.conf
@@ -0,0 +1,43 @@
+
+
+
+ ServerName hg.lunch.org.uk
+
+ ErrorLog /var/log/apache2/hg-error.log
+ CustomLog /var/log/apache2/hg-access.log combined
+
+ RemoteIPProxyProtocol On
+
+ ScriptAliasMatch (.*) /srv/mercurial/hgweb.cgi/$1
+
+ Options +ExecCGI +FollowSymLinks
+ AllowOverride Limit
+ Order allow,deny
+ Allow from all
+ Require all granted
+
+
+ SSLEngine on
+ SSLCertificateFile /var/lib/dehydrated/certs/hg.lunch.org.uk/fullchain.pem
+ SSLCertificateKeyFile /var/lib/dehydrated/certs/hg.lunch.org.uk/privkey.pem
+
+
+
+
+
+ ServerName hg.lunch.org.uk
+
+ ErrorLog /var/log/apache2/hg-error.log
+ CustomLog /var/log/apache2/hg-access.log combined
+
+ RemoteIPProxyProtocol On
+
+
+ #
+ # This redirects all accesses to the HTTPS version of the site.
+ #
+ RewriteEngine On
+
+ RewriteRule ^/?(.*) https://hg.lunch.org.uk/$1 [R=301,L]
+
+
diff --git a/states/mercurial/hgpaths.rc b/states/mercurial/hgpaths.rc
new file mode 100644
index 0000000..a8dd475
--- /dev/null
+++ b/states/mercurial/hgpaths.rc
@@ -0,0 +1,12 @@
+[paths]
+dottes = /srv/mercurial/repos/dottes
+noffle = /srv/mercurial/repos/noffle
+noffle-website = /srv/mercurial/repos/noffle-website
+gecko-app = /srv/mercurial/repos-private/gecko-app
+gecko-web = /srv/mercurial/repos-private/gecko-web
+pelican-app = /srv/mercurial/repos-private/pelican-app
+pelican-web = /srv/mercurial/repos-private/pelican-web
+lj-web = /srv/mercurial/repos-private/lj-web
+lj-app = /srv/mercurial/repos-private/lj-app
+emacs.d = /srv/mercurial/repos/emacs.d
+salt = /srv/mercurial/repos-private/salt
diff --git a/states/mercurial/hgweb.cgi b/states/mercurial/hgweb.cgi
new file mode 100644
index 0000000..d99753e
--- /dev/null
+++ b/states/mercurial/hgweb.cgi
@@ -0,0 +1,22 @@
+#!/usr/bin/env python3
+#
+# An example hgweb CGI script, edit as necessary
+# See also https://mercurial-scm.org/wiki/PublishingRepositories
+
+# Path to repo or hgweb config to serve (see 'hg help hgweb')
+config = b"/srv/mercurial/hgweb.config"
+
+# Uncomment and adjust if Mercurial is not installed system-wide
+# (consult "installed modules" path from 'hg debuginstall'):
+# import sys; sys.path.insert(0, "/path/to/python/lib")
+
+# Uncomment to send python tracebacks to the browser if an error occurs:
+# import cgitb; cgitb.enable()
+
+from mercurial import demandimport
+
+demandimport.enable()
+from mercurial.hgweb import hgweb, wsgicgi
+
+application = hgweb(config)
+wsgicgi.launch(application)
diff --git a/states/mercurial/hgweb.config b/states/mercurial/hgweb.config
new file mode 100644
index 0000000..50cab39
--- /dev/null
+++ b/states/mercurial/hgweb.config
@@ -0,0 +1,6 @@
+[paths]
+/ = /srv/mercurial/repos/*
+
+[web]
+allow_archive = bz2 gz zip
+contact = Jim Hague, jim.hague@acm.org
diff --git a/states/mercurial/init.sls b/states/mercurial/init.sls
new file mode 100644
index 0000000..b29bfc6
--- /dev/null
+++ b/states/mercurial/init.sls
@@ -0,0 +1,44 @@
+mercurial:
+ pkg.installed: []
+
+mercurial_user:
+ user.present:
+ - name: mercurial
+ - usergroup: true
+ - home: /srv/mercurial
+ - system: true
+ - fullname: Mercurial repositories
+
+mercurial_repos:
+ file.directory:
+ - name: /srv/mercurial/repos
+ - makedirs: true
+ - user: mercurial
+ - group: mercurial
+
+mercurial_web:
+ file.managed:
+ - require:
+ - sls: apache
+ - sls: certificates
+ - names:
+ - /etc/apache2/sites-available/hg.lunch.org.uk.conf:
+ - source: salt://mercurial/hg.lunch.org.uk.conf
+ - /srv/mercurial/hgweb.cgi:
+ - source: salt://mercurial/hgweb.cgi
+ - user: mercurial
+ - group: mercurial
+ - mode: 0755
+ - /srv/mercurial/hgweb.config:
+ - source: salt://mercurial/hgweb.config
+ - user: mercurial
+ - group: mercurial
+ apache_site.enabled:
+ - require:
+ - file: /etc/apache2/sites-available/hg.lunch.org.uk.conf
+ - name: hg.lunch.org.uk
+ service.running:
+ - name: apache2
+ - reload: true
+ - watch:
+ - file: /etc/apache2/sites-available/hg.lunch.org.uk.conf
diff --git a/states/top.sls b/states/top.sls
index 7612598..4e0f8ad 100644
--- a/states/top.sls
+++ b/states/top.sls
@@ -8,3 +8,5 @@ base:
'scabbers.lunch.org.uk':
- debian
- certificates
+ - apache
+ - mercurial