Author image
Senior Developer

Automated deployments using Aegir

There are a few write-ups about using Aegir to automate your deployment process notably one from Mig5: Zero-touch Drupal deployment with Jenkins, Aegir, Git, Fabric and Drush. I recently wanted to set this up for our own project, but felt like I could make some improvements.

I don’t like deploying branches, because it can be really hard to actually find out what was deployed at a later date, and you can’t reliably re-deploy that previous code later on. I think it’s much better to deploy tags. It also gives you an easy way to flag when you do want to do a deploy. We tend to commit early and often, and doing a complete deploy for every single commit is wasteful and usually pointless really.

Inspired by Mig5’s scripts I started to write my own, they have the following key features:

  • Configuration is stored along with the code in the git repository.
  • Deploys are triggered by tags on specified branches.
  • Configuration can be per-branch.
  • A template (stub) make file is used that is also stored in the git repository.

They are available on Github: https://github.com/computerminds/aegir-deploys

Here’s how they work.

We add a .aegir-deploy.yml file to the root of the repo to contain our configuration information, something like the following:

master_server: 'master-server.example.com'
platform_base: 'Example site'
web_server: 'remote_server'
branches:
    master:
        site_name: 'live.example.com'
    develop:
        site_name: 'staging.example.com'

Starting at the top, this would tell the deployment scripts to talk to an Aegir master server at master-server.example.com. You should set up ssh access from the machine running these scripts to that master server. Then we define a naming prefix for platforms that are going to be automatically created. Then we define the web server that these platforms should be being created on, this allows us to use the remote servers feature in Aegir.

Finally we define a list of branches and some options specific to them, the deployment scripts won’t do anything to a branch that isn’t listed in this section, so you can just include the branches you want, and then set the site_name which the Aegir managed site that should be being migrated when a new deployment is made.

Because we specify configuration per-branch, you can easily use these scripts just for your staging site, or just for production, it’s up to you!

Full details of all the configuration options is available in the readme file in the deployment scripts repo.

Running the scripts

Download the scripts to your machine, and additionally get yourself a git checkout of the site that you want to deploy, with the correct branch and tag on the current HEAD.

Now, from the root of the deployment scripts folder, run:

fab setup:/path/to/checkout/of/site validate_and_run

This scans the checkout of the site to find tags to deploy out the Aegir master. If it does find a tag to deploy, then it’ll use a specified template to generate a Drush make file that will build the platform. It will then connect to the Aegir master and create a new platform using this Drush make template. If that succeeds then it’ll also migrate the site over to use the new platform and update the Aegir frontend to reflect these changes.

Running the scripts using Jenkins

We use Jenkins to make the process of monitoring a repo for changes and then running these scripts to deploy those changes super easy, but I’m sure a similar tool would do the job fine too.

I set up a new Jenkins job for each branch that I want to build, and use the git SCM plugin to monitor our site’s repo for changes. I set up a few configuration options so that the deployment scripts work correctly, they are:

  • Branches to build: master (or whatever branch you want to monitor for new tags)
  • Checkout/merge to local branch master (same as above)
  • Skip internal tag: true
  • Local subdirectory for repo: site

I also checkout the deployment scripts using the git SCM plugin (using the multiple SCM plugin to allow multiple git repos to be checked out) into a folder called aegir-deploys.

Then I add a single build step: Execute shell, with the following code:

# Remove old make files.
rm aegir-deploy-*.make | true
# Run deployment script
fab --fabfile=aegir-deploys/fabfile.py setup:"$WORKSPACE/site" validate_and_run

Set up monitoring of the git repos however you want, either using polling, or Github hooks and you’ll be able to just push a tag to your git repo to perform a release of your site!