Drupal deployments & workflows with version control, drush_make, and Aegir

It's the million dollar question. And it's rarely been answered because it's so darn hard to do so.

How to solve the dev / staging / live workflow problem in Drupal?



Today I'd like to tell you how I do it with my favourite deployment weapons: Aegir, Version control, and Drush Make.


This'll be a rather low-level article designed for power-users. For a more high-level overview of the benefits described, check out the recent blog post by Development Seed.

The Problem

While many or most of us are using version control to keep track of our code and so on, a problem still persists, and it is twofold:

1) A lot of important data gets stored in the database in many database-driven content management systems, such as Drupal
2) The transition of updates through version control to the site can be a royal PITA.

Recently 1) has pretty much been conquered thanks to Features, which provides the ability to export the 'mechanics' of a Drupal site from the database into module-like code, which can then be version-controlled.

Adrian Rossouw covered how Features can help solve the classic Dev / Stage / Production workflow problem in a great blog post. Features is one of those big guns we've all been waiting for. I mean, google 'development live workflow', and it's this post that is number 1.

With the rising popularity of the Aegir hosting system, and its ability to fire off sites like a proverbial machine gun, the other question is becoming even more important.

Because Aegir is this fantastic system for managing your sites, right? Of course, I would say that. But how can you keep a site under version control when Aegir's capable of making and manipulating sites almost on-the-fly with the click of a button?

The Solution

Enter: Drush Make

The answer has come in the form of Drush Make, which provides an extension to Drush, the command line tool I often refer to as 'apt-get' for Drupal.

What Drush Make does, is through the implementation of flat files (similar in appearance to .info files from modules), provide a mechanism to fetch data from practically any source you tell it to, and do $stuff.

This can include downloading Drupal core, as well as a bunch of contrib modules from drupal.org . However, it also supports the ability to fetch:

  • code from CVS repos, including tag-specific
  • ditto for svn
  • ditto for git, including checking out a particular branch after cloning the repo
  • grabs .tar.gz stuff, wget-style, useful for libraries
  • can fetch and apply patches

Sure, you say, that's great. It's basically doing batch drush dl's with some extra features/protocols thrown in. But how does this help with version control? Not only that, but how is that going to help keep this stuff under control while managing the site in Aegir?

Certainly for me, much of the issue has been that Aegir is inherently 'on the fly' with its actions. It has no concept of version control. But eventually I realised I had to stop expecting Aegir to handle this aspect, and realise that I could work with it by bringing version-controlled data to it for processing.

Or, put another way, I realised the very act of moving data around, does not need to be a version-control procedure in itself.

One must start to think like Aegir: and that is that the Platform and its application is the important data, that needs to be controlled. The site is just an instance of the application, and so long as your application is controlled, your site can be manipulated as an instance of it.

Adrian mentioned it in his podcast interview with Lullabot on October 15th:

It helps to think of install profiles as applications, and sites as instances of those applications.

If you can grasp that, you're on the home stretch already.

The Platform becomes the Platform Build.

One of the concepts I struggle with the most when training users on Aegir, is that of the 'Platform'. It turns out that many developers haven't been using Drupal's multisite design even prior to Aegir, despite the fact that the design's been around forever. So the idea of having multiple sites inside the /sites/ folder of Drupal core - in other words, sharing the core codebase between sites - is somehow (often, but not always) already enough of a paradigm shift.

In Aegir, one creates Platforms, which are just code bases, or a copy of Drupal core (or Open Atrium, etc). Only then can we create and manage Sites, which live on Platforms.

The analogy is directly like this:

/var/aegir/drupal-6.14 /var/aegir/drupal-6.14/sites/www.mig5.net

What makes this hard is that some users are still getting used to this idea, even though Aegir isn't doing anything different here. It's just exposing that multisite design of Drupal, by making it easier.

If you can grasp the idea of multisite, you'll find it easier to understand how Aegir works with your sites, and how a workflow can be developed to handle build management.

I mentioned Drush Make, and it's ability to grab the Drupal core.
And I mentioned shifting one's mindset to think of Install profiles as just 'Profiles', or 'Applications', and sites as instances of those Applications.

With this in mind, a bigger picture starts to form regarding the potential of Drush Make, since it can, in one fell swoop,

  • download the core,
  • fetch the install profile from your git repo
  • fetch some contrib modules
  • fetch some custom themes and modules from your other repos
  • maybe apply a patch against a module
  • fetch some extra third-party libraries, i.e jquery.ui, or geshi

No, really. Look at this (entry-level) example of mig5_net.build:

core = 6.x
projects[] =  drupal
projects[mig5_net][type] = "profile"
projects[mig5_net][download][type] = "git"
projects[mig5_net][download][url] = "git@git.mig5.net:/drupal/profiles/mig5_net"
projects[mig5_net][download][branch] = "build_2009101601"

Executable from the command line like this:

php /var/aegir/drush/drush.php make mig5_net.build /var/aegir/drupal-6.14_build_2009101601

My install profile or 'application' is the git repo that I'm cloning. Note the branch reference: after Drush_make 'git clone's it, it'll check out a specific branch, or 'build'. This is how this release is different from past and future builds: it's a specific release I'm building for.

Suddenly with this one execution of a single flat file, you've built a copy of Drupal core, and dropped in the profile or 'application' into its /profiles/ directory. That's a platform in Aegir's eyes, and not just any platform: but what I call a 'Platform build'. It's a specific release of a your application, right from the top of core, down to the last css file of your site's theme.

Hang on, .css file? Where's the contrib and all that? You only cloned the install profile from git

Yes, in the makefile above, I'm only grabbing the core and my install profile application. Here's the secret: it turns out Drush Make has a recursive nature! I tuck away another makefile inside my install profile repo, called mig5_net.make, and this is the real gem.

core = 6.x
projects[] = admin_menu
projects[] = captcha
projects[] = geshifilter
projects[] = install_profile_api
projects[] = pathauto
projects[] = recaptcha
projects[] = tagadelic
projects[] = token
projects[] = twitter
projects[] = views
projects[singular][type] = "theme"
projects[singular][download][type] = "git"
projects[singular][download][url] = "git@git.mig5.net:/drupal/themes/singular"
projects[tao][location] = "http://code.developmentseed.org/fserver"
projects[mig5][type] = "module"
projects[mig5][download][type] = "git"
projects[mig5][download][url] = "git@git.mig5.net:/drupal/modules/mig5"

What we have here is a series of contrib modules from drupal.org. Also I have a slightly hacked version of singular (css stuff), so I don't use Development Seed's feature server repo to grab this: I keep my own copy in my own git server. However, I *do* use the Tao base theme from their feature server, because I know, like contrib, I don't make any changes to it.

Alternatively, if I was smarter, I could have grabbed Singular from DevSeed's feature server, and written a patch for the css change, and asked Drush Make to apply the patch instead. Here's a snippet of such a thing, taken from the Managing News makefile in its install profile, where the Context module is patched:

; Patched.
; Explicit versions specified to ensure patches apply cleanly.
projects[context][subdir] = "contrib"
projects[context][version] = "2.0-beta7"
projects[context][patch][] = "http://drupal.org/files/issues/606816-1_node_form_context.patch"

...just so you don't think I'm making this stuff up :) Yes, such features exist, and are in active use!

So, this make file gets downloaded when the install profile git repo gets cloned and the build-specific branch is checked out. While Drush Make grabs the profile from the first makefile (I call it the .build file), it scans the directory and finds this make file, and recursively executes it - thus grabbing all the site-specific components in the process.

Time to tell Aegir about the new Platform build

Suddenly what I have is the entire platform, complete with any updated components I made in the makefile of that specific branch in git. At this point, I just have to tell Aegir about it!

So I go to Create Content > Platform in Aegir, give it a name (usually suffixed with the build number I give it as above), and tell it the path to the new platform I made (/var/aegir/drupal-6.14_build_2009101601)

Aegir goes and checks the platform, learns about it, adds the package information it finds within it to its database, and if all's well, gives me the big green tick.

But where's the settings.php? The site files? This isn't actually the *site*!

Exactly. It's only the application that we've built, and it's only the application we store in version control and generate with makefiles. The site still exists on the old platform, and Aegir knows it does. What we have to do here is stop thinking of the /sites/www.mig5.net/settings.php etc as the *site*, but rather, the current running 'instance' of the application.

It sounds a bit weird, doesn't it? But you don't realise, if you're already using Aegir, you're already probably doing this already. Drupal 6.14 came out recently, and your sites were on 6.13. You built a new platform (6.14, by downloading it), told Aegir about it, and you used the Migrate task to upgrade all your 6.13 sites to 6.14 at the click of a button.

We're doing exactly the same thing here: you've got your new platform, with your updates. Now you just need to Migrate the site onto that new build. Your settings.php and files from /sites/www.mig5.net/ get carried across to the new build, and any component code/database updates will get applied in the process.

Suddenly, you've just exercised the perfect workflow:

  • You kept the application, important stuff, in version control
  • You managed to keep *less* of a) in version control because drush make can fetch the contrib you don't hack, from drupal.org and other sources
  • You built the whole new release with just one command on the shell
  • You managed to seamlessly upgrade your site onto the new release, applying all the updates, and
  • you did that last one via Aegir, which means you were protected with the rollback functionality of Provision and Drush, meaning if it all went pear-shaped, you'd be back on the previous release as though nothing had happened.

This is how Aegir can cooperate with version control: all it needs from you is to get that Platform, or build, in place, so it can use it and take care of the release process for you.

And while it used to be difficult to build an entire distribution complete with all the nitty gritty components required, it's now never been easier to do this step in a matter of seconds, because Drush Make does this job for you.

This application, www.mig5.net, is literally two files in my git repository, plus the theme (I hacked on Young Hahn's Singular theme a bit). The two files are the install profile itself (which, of course, I only ever once: first time install of the site) and the mig5_net.make file, that does everything else.

Dealing with the dev > live process

This really packs a powerful punch when you're working on a development version of your site to make changes prior to sending live (and if you're not, you should be). The process above fits perfectly into this model. This is how one does it:

Need to make changes?

Dev

  • Make a new build using drush_make to grab the latest bits of everything. Add that platform to Aegir. I might call this build 'drupal-6.14_build_dev_2009102601'
  • Use the 'Clone' feature to clone your current Live site to the test build.
  • Make your changes to the dev site (maybe you are changing the theme, or adding a module)
  • Commit those changes back to the repo (the theme changes, maybe adding that new module as a ''project' in your drush_make file inside your install profile). Make a branch of the repo in preparation for a new live build.

Live

  • Make a new build using drush_make to grab the latest bits of everything (this grabs the changes you just committed). Add that platform to Aegir. I might call this build 'drupal-6.14_build_live_2009102601'
  • Use the 'Migrate' feature to migrate your live site to the new build, which picks up and applies any changes/upgrades

I shared some ideas with Adrian Simmons (@adrinux) who has taken the build/deployment logic I describe here and generated an absolutely fantastic workflow diagram showing the transition of data from dev to live, as well as the relationship between drush_make, version control, and Aegir. Here is the diagram - it does a hell of a better job explaining it all than me and my wordy ways :)


The status of Drush Make

Awesomeness.

No, you'd know by now that I'd say that, but that's actually the release notes for the 6.x-2.0-beta1 release, which Dmitri unleashed today, after an amazing night (well, my time) by Adrian Rossouw who obliterated a bunch of bugs after being given commit access. The Aegir project now depends on drush_make to build the frontend system and its relevant components, as of HEAD and the upcoming release 0.4-alpha3 (stay tuned for that very shortly). For this reason, we have a direct interest in the project and its future, and so we were lucky to work with Dmitri and squash a few issues very quickly - some of which were actually identified during the writing of this article :)

The recent changes to Drush Make include bringing it in line with changes in the also-recently-released Drush 2.1, adding support for checking out git branches after a git clone, and supporting absolute paths for destination of builds on the server.

Need to play with it some more to try it out? You can see examples of my 'build' makefiles in my git repo as well as my application install profile for mig5.net, which contains the 'bigger' drush_make file. Or check out the Managing News install profile and its make file - it's the first project other than Aegir to use a make file to build itself.

If you're new to Aegir, Drush and Drush make, I hope this article gives you the incentive to try it out and see why it rocks. If you're using Aegir and Drush already, I hope Drush Make makes more sense now, and that this gives you that 'ah hah!' moment if you've been scratching your head about how to handle build management in an Aegir environment.

(thanks to Adrian Simmons, Adrian Rossouw and Eric Gundersen for their contributions/ideas for this article, and most of all to Dmitri Gaskin for his mad skills.. thanks for changing the game with Drush Make!)

Comments

Drush make seems great, and I can see some uses for it (it could be just the magic sauce needed to turn install profiles into real distributions) -- however, I don't fully understand why only having make files/profiles in your version control is preferable to just having the codebase in version control altogether during custom site development workflow. Sure, it's "small" (but who cares?), but it seems like you might lose out on a lot of nice revision information and history. Oh, and what if Drupal.org or some other third-party resource is offline? Now your makefile is useless.

My workflow using Aegir has been to keep the full codebase (drupal, contrib modules and all) in SVN. When I'm ready to deploy a new platform, I simply check it out of SVN, tell Aegir, and migrate. This is technically simpler than make and doesn't rely on as many external resources. But, at this point, I'm assuming I've either missed something or I haven't been handed the cool aid yet.

Hi Josh, you make some good points. Yes, the design of Drush Make does introduce a dependency on a working network at each end of the request.. for this reasonm storing everything in your own repository is a strength.

That said, what I like about Drush Make is that I don't need to keep track of / maintain updates to various contrib components myself.. fetching and incorporating the updated modules into my own VCS. Maybe certain sites need an older or newer version of the module to make it work.. that means I'd have to keep several copies of it in my VCS.. why not reference a specific version in the make file instead per application.. or, if I had to hack a module, why not download the module as normal via the make file and apply a patch of my own from my repo...

If Drush Make can grab the latest version (or any version that I specify) for me during the build itself, I save myself time, resources and effort.

I guess it's a trade-off: network issues to me are not so common, and they don't accumulate the way data does over time. Yes, disk is cheap, but I find doing all the hard work of putting a complete copy of the whole application into my repositories can build up cruft and just feels like overkill. Ultimately it feels to me that the real win here is the elimination of a lot of manual labour.

It's a 'your mileage may vary thing' perhaps :)

I find all of this highly fascinating. Will be trying this out soon.

Thank you for taking the time to write about this. This post is like a .make file for our brains :-)

The first blog post I printed out for safe keeping in the last three years.
I'm currently using git as a tool to both deploy sites from my home-baked drupal-distro and manage local, dev and live versions (put in different branches) of all the sites I do. But this blows it out of the water. Great!

In the development process there're some tools we can get advantage of. Namely modules dbscripts, node import / migrate and import/export features of cck, views and panels (that can be used independent of features if I'm not wrong).
The workflow is not the same: clonning can be interesting in some first stages of development but as far as a site goes live, you have to synchronize instead of clonning.
Also, the configuration in a production site may not be the same as in development, as an example: in development you can use devel module, have caches turned off... additionally in a production site you can avoid using non-devel especific modules as Views UI, advanced help or admin_menu.

I'm in Josh B's camp, although I like the idea of drush and drush make, I haven't switched my workflow completely to it as SVN has been working great for me.

mig5 you say "That said, what I like about Drush Make is that I don't need to keep track of / maintain updates to various contrib components myself."

But, what if the latest version of a contrib module breaks something or switches APIs on you, etc? Drush + Drush make might be great for preparing applications and default configs, but once you're deploying or distributing code, I think you'd want to be pragmatic and know that the bundle of code works.

once you're deploying or distributing code, I think you'd want to be pragmatic and know that the bundle of code works.

That's what a dev environment is for, right? :)

Drush Make isn't changing anything here, it just provides a smarter and faster way to bundle up that code for you, and makes it faster to deploy. It's still up to the developer to ensure that the bits that are being bundled together, actually work.

And even if that contrib module breaks something, you can still use Drush Make to apply a patch on each build. I would rather do that than keep the modified full version in my VCS and have to keep changing it as upstream changes, but still need to patch it for my case.

The idea is you get it working in dev, and you then know that with one command, you can deploy an identical build and seamlessly migrate your live site onto it (at least, it's that graceful when using Aegir, as the steps are fewer, but it doesn't depend on it).

Whatever works for you! :) But your subject was 'I still prefer VCS', and I want to point out that Drush Make is not a replacement for a sensible VCS, and I wouldn't want it to be. The point is that you can use your VCS alongside Drush Make, and just hand over to Drush Make, the task of generating the build for you, and also potentially store less in your VCS by not reinventing the wheel.

Under this scenario - it appears all my themes have to live at sites/all/themes . this is has the small disadvantage that on one site, you can see all the themes for all sites in the platform.

Correct? Or did I miss something?

No, the theme would be fetched from a repo or somewhere, by the drush_make file in the install profile. This means the theme would be located, similar to modules, in /path/to/core/profiles/$profile_name/themes/$theme

And in terms of visibility: only a site that has *that* specific install profile set in its database, can read the modules/themes located in that area. (it's the 'install_profile' field in the system table, from memory. Settable either by installing the site using that install profile, or doing a variable_set to change the existing profile. Drush 2.1 comes with a 'vset' and 'vget' command that makes this easy now.)

Per my drush_make file above:

projects[singular][type] = "theme"
projects[singular][download][type] = "git"
projects[singular][download][url] = "<a href="mailto:git@git.mig5.net">git@git.mig5.net</a>:/drupal/themes/singular"

Thanks! Very inspiring!

Maybe offtopic, sorry. How to separate the main theme and a set of templates/styles that belongs to сertain feature? For example, some feature have some views with custom themeing. How to package and install it with feature, not with theme?

I'm happy to get Aegir installed. Now digg into the deep :)

I think you can control theme aspects with Context (at the very least, with css). And you can export Contexts with Features :) Sorry, it's not really my area, I'm no designer :)

Love it!
Like many of the previous commenters, I currently use an svn based workflow with a vendor repository from which specific versions of modules - which may or may not have been patched in some way - can be linked into individual site repositories with svn:externals. It works, and it works well, there is no doubt about that. But I totally agree that it feels too clunky, overweight, messy and time and resource intensive to manage.

I was a convert from the moment you showed that drush make can apply patches as part of the build process. To me, a flyweight setup like you have so kindly, outlined in such great detail seems like the next logical progression and a real step forward.

However... I do still have reservations about the underlying decision to store only the configuration of a site in version control, as opposed to the entire site including the content. Whilst this is clearly not an issue for things like installation profiles or new platform builds, what about actual sites? When I am in control of a site, I like to include EVERYTHING to do with that site in svn. This includes the database (dumped in an svn friendly way thanks to dbscripts), and all of the files too. This way, I can check out the entire site from svn, run the dbscripts import script and have the site up and running in a matter of minutes. DBscripts also makes it very easy to synchronise database changes from Production back to Development.

Should VCS really only be used to store configuration (the application)? I tend to think not when working with actual live sites (instances) because an actual site is a combination of it's configuration and it's content. Not just one, or the other. And with the entire thing in svn, I can jump back in time to any point and get to the entire site as it was then. As a developer, it's easy to think that the code, or the application is the really important thing, but what is the point of having all the code, with no content?!

I'd love to know how you deal with managing actual site instances like this... Do you just rely on having backups of the database and the files directory? And if you're not storing the database in VCS along with the code, how can you ever be sure that the database you restore will match up to the specific version of the code you are working with? having it all in VCS ensures that every single revision has everything it needs, exactly as it was when that revision was created.

First some questions from me to check whether I understand correctly..

1# Is it correct to state that such a platform 1.x basically only 'contains' a single site. (in this case mig5.net)?
2# So in case you're following all 16 major release of drupal6 core, and some extra upgrades for critical contrib security upgrades + some own custom theme/module improvements .. you would end up with +/- 30 platform builds with each a single site running over the livespan of 2 to 3 years. Is that correct?
3# Is it correct that Aegir is only used in the staging environment, and that the LIVE server is basically not aware of Aegir at all. It's basically a push-model where the latest stable release gets 'pushed' live.

4a# Isn't that a lot of overhead just keep a single site up-to-date? 4b# Or would you basically delete all releases in order to keep eg. only the last three or so?

5# How about the urls for to those dev sites. Would you call them build.2009101601.mig5.net or something?

6# In the process, I see (optionally) deploying to live remote server. Is there an Aegir task for doing that, or is it something that needs to be done manually?

7# By using features and well written updates (and extra resources provided by the client) it should be possible to upgrade a live running site while keeping all the content intact. But to be sure that this upgrade will work, you'd like to test this out in a QA/Staging/test environment first. In the above scenario I never see an arrow coming from the live to the dev environment to clarify that we're running our tests with the latest content. In theory, that should not be needed, but in practice i'd like to verify for myself that the upgraded site still looks and reacts the same way as the current live site. How would you handle that process?

8# How will this scale for many sites? I mean - having 50 sites in multiple builds results in 100's of platforms running within Aegir with each have only 1 instance. 8a#Is there a way to tell Aegir that a certain build is in fact the one running Live? Or would the naming of the build eg. release.1_2.mig.net take care of that? 8b# Is the Aegir interface able to handle that many platforms? 8c# Is there a way to group all these different releases in Aegir by using a single tag for each site e.g 'mig5 releases' ?

Lot's of questions, I know. But i'd be very gratefull if you could look into those. Or otherwise I'll catch you at drupalconSF in a few weeks :p

Thanks for all the great work up till now!

The answers to the latest list of questions from Roel De Meester are interests me as well!

Hi Roel,

Thanks for taking the time to send through your thoughts. I enjoyed watching the screencast of your talk at Paris.

1# Actually, no. Drush_Make supports the fetching of multiple profiles just as much as multiple modules or themes, so you could maintain a 'mega' build file that fetches multiple profiles so you can use the one platform for many sites. Here's an example:

;Core
core = 6.x
projects[] = drupal
; Profile 1
projects[mig5_net][type] = "profile"
projects[mig5_net][download][type] = "git"
projects[mig5_net][download][url] = "git://git.mig5.net/drupal/profiles/mig5_net"
; Profile 2
projects[managingnews][type] = "profile"
projects[managingnews][download][type] = "cvs"
projects[managingnews][download][revision] = "DRUPAL-6--1"
projects[managingnews][download][root] = ":pserver:anonymous:<a href="mailto:anonymous@cvs.drupal.org">anonymous@cvs.drupal.org</a>:/cvs/drupal-contrib"
projects[managingnews][download][module] = "contributions/profiles/managingnews"
; Profile 3
projects[openatrium][type] = "profile"
projects[openatrium][download][type] = "cvs"
projects[openatrium][download][module] = "contributions/profiles/openatrium"
projects[openatrium][download][revision] = "HEAD"

I don't know if DevelopmentSeed use a 'bulk' makefile like this, but I know they deploy platforms with multiple profiles to avoid the build-up of platform-per-site that you're hinting at.

#2 It is very easy to end up with a lot of platforms, yes. Realising this after writing this article, I set to work coding the 'Platform Management' features in to Aegir that allow you to run a Delete task against an entire Platform once no sites are running on the platform (i.e once a site has been migrated off). The Platform Management work made it into the last 0.4 alpha release and is here to stay :) and it makes things easier being able to blow away old stale platforms that are no longer required.

#3 You could use a push model, but it's not required. Given that Drush Make can fetch from your repository, and check out any relevant 'live' branch you would like, you can just generate a new 'live' build of code you know to be working (from your dev/staging environment testing) and then use Migrate to put your live instance onto the new build.

#4a and #4b yes it has been rather clunky and a fair bit of overhead. However, per #2, it is a LOT easier now that you can blow away old platforms after migration. The other thing is, it is not a perfect solution and I fear I've painted it as such. What I have tried to demonstrate is, when working with dynamic Drupal sites and using Aegir, this is the most *elegant* solution (not the easiest :) )

#5 Yep. A different dev subdomain for each dev instance, or you can blow away the old dev site first and clone the live site to a dev site of the same name after.

#6 Deploying to remote servers (such as a 'live' server) is a feature that is part of the multiserver work we are currently developing for the 0.4 main release. In HEAD, I believe you can currently deploy to remote databases - not sure about remote web servers, but I know it is the main priority right now and almost ready.

#7 "In the above scenario I never see an arrow coming from the live to the dev environment to clarify that we're running our tests with the latest content." Actually, per #5, that *is* the way it works in the diagram. To make a dev site, you Clone the live site to a dev instance. Thus the dev instance is running fresh data in the database that is a copy of the latest live. The work you then do is code work (modules, themes) which go into VCS, and you can push new content from dev back to live using Backup/Migrate or something (which I don't bother doing)

#8 It does scale and it used to be very clumsy but again, I think the new Platform management work reduces that pain a bit by being able to blow away old platforms.

#8a Not yet, but what you are thinking of here is a feature we have called 'site relationships'. I have started some early dev work in this direction, here is the ticket. We will introduce a way to make sites 'relate' to one another eg 'this is a dev version of site X; this site Z has a 'clone' relationship to site Y, and site Y is its 'parent', and so on. We will then implement rules in the backend based on what these relationships are. For instance, we will make a configurable option that if a site X already has been cloned to site Y, you may *overwrite* site Y with a new clone of the same name, and so on.

#8b The Aegir interface has no problem handling many platforms. In Aegir, the only thing the system can struggle with is too many tasks in the queue being executed at once (Batch Migrate is a good example of this), but you can control this by adjusting the frequency thresholds of the queue.

#8c Same as #8a - this sort of thing will be what we'll try to achieve with Site Relationships.

A final disclaimer: As a sysadmin I'm not in the business of developing sites, only managing them. So I'm not too precious over the ideas here, and they aren't all mine. I welcome your thoughts and suggestions on how to make this always-difficult procedure even better.

There'll be plenty more news to tell soon and I'll be happy to answer more questions at DrupalCon. I arrive there 4 weeks from today, can't wait. See you there! :)

Hi Miguel, I'm trying to set up an aegir+git workflow. Not rethinking it I would feel secure to have a local git copy of existing patches that i put into a build (platform). But following your reasoning, that is actually just extra stuff in version control for no good reason. Am I "getting the drift", so to speak? What's the practical course of action?

Ps Thanks for the aegir dojo cast, sorry for the many questions. We should just let you do your thing next time. (Looking forward to it).

O also, i keep forgetting to bring this up, I saw the features video by Jeff Micolis, in which he mentioned your features server. He also did this almost rant about 30 minutes in about never ever using the nodeid as a meaningful id. Can it be that that is exactly what is holding up the multiserver part of aegir 0.4, which uses sequential id's for the platforms and sites? So then how about adding a seperate field for namespace-id.

Hey Willem,

There's nothing wrong with patching other contrib to suit your needs as far as I'm concerned. Fortunately Drush Make comes shipped with the capability to patch various projects as required. It even generates a PATCHES.txt at the end, letting yourself or other developers know what modules got patched and by what.

Take a look at the example Open Atrium makefile; in it you can see several patches defined (copied and paste the Organic Groups patch definition below):

; Patched
 
projects[og][subdir] = "contrib"
projects[og][download][type] = "cvs"
projects[og][download][module] = "contributions/modules/og"
projects[og][download][revision] = "DRUPAL-6--2:2010-02-28"
; <a href="http://drupal.org/node/701420
projects[og][patch][]">http://drupal.org/node/701420
projects[og][patch][]</a> = "<a href="http://drupal.org/files/issues/701420_2010-02-28.patch"

">http://drupal.org/files/issues/701420_2010-02-28.patch"
[/geshifilter-code]

Using node ids is a drawback in Aegir to define important objects, and you are on the money here. Fortunately we are blessed by the developments in Drush 3, which introduced 'aliases' that provide an easy way to get access to the attributes of an object.

The Multiserver work in our dev-services git branch makes very heavy use of Drush aliases so that every server is able to access each other server, platform and site by its alias without having to rely on the node id.

Read the Development Seed article for more on Drush Aliases.

Cheers!

Thank you for this wonderful article. But is creating new "build" in Aegir easy ? Can new platform builds be automated so I could drush-make-checkout-apply-patches-create-platform with a single button ? Imho giving platform a name manually is still time consuming in a rapid development model.

Am I right, that drush_make doesn't work properly with aegir 0.3 ?

It's probably more likely that drush_make struggles to work with the version of Drush that was released alongside Aegir 0.3 at the time, and not a direct incompatibility with Aegir itself. I recommend you upgrade Aegir to the latest 0.4 release, which also involves upgrading Drush to 3.3.

Thank you so much for an amazing article mig5!

The part I'm having trouble with is if I had platform with say 30 client sites running on it. Then one needs its custom theme reworked or a module added. If I follow the diagram, I end up with 29 clients on one platform and 1 client on a new but "same" platform. I'd like to keep the platforms very streamlined, and I'd hate to have to migrate all 30 every time one needed an upgrade.

I'm probably missing something, as I haven't quite figured out the details of the differences between /sites/all/* and sites/example.com/* as they relate to aegir platforms and drush functions. Anyone can link to any articles on that?

Thanks for all your work on this Mig... exciting to follow.

Maybe I missed something in my read but I didn't see how this resolves the issue of having content information that's different on both dev and prod.

For example if I'm building a new area of a site that needs new nodes and CCK fields and whatnot how does this system address that? The live site is constantly seeing node additions and updates and new users and obviously the NIDs and UIDs are going to fall out of sync between the databases. While aegir does seem to address the configuration data issue I don't see how it's merging the content data.

Can you enlighten me?

Hi Alan,

Yes that's the clincher, and as far as I'm concerned there is no real solution for that.

I consider that problem to extend beyond Drupal to *anything* with a database-driven backend.

In Drupal, your only solutions are:

1) Try and use Features wherever possible, which allows you to export as much data as possible out of the database and into code (not nodes though)

2) Try and programatically create your nodes and cck data in custom modules, and use hook_update() to apply subsequent changes to the live environment (those updates will be executed on a Migrate task)

Personally I have come to the decision that as long as there's a database, there's disappointment :) You've got little chance of controlling something dynamic unless you can rip it out and back into code again. Features/Exportables are the modules pushing the way forward for that, and you can already export Views into code (which Features will also do for you if your Feature depends on a view).

Not too uplifting a response, I know! Such is the plight of database-driven systems.

That's the response I was afraid of getting... oh well... I've had some degree of success using Toad for MySQL to at least give me some good output of what's changed for my merges but it's tedious with a lot of changes. I really find it hard to believe that there isn't a better way but I have yet to find one. There's a few projects out there attempting a solution (dbscripts, deploy, migraine) but they're all in their infancy and lacking the momentum and community I would have hoped they'd have.

I think the issue is that Drupal is a flexible platform so there is no way to dictate what is content and what is configuration for all use cases. In a custom platform, the developers can make that separation for their specific use case and then only update the related config tables on a live site.

The only flexible way for Drupal to handle this is to have a way for site builders to check a box for each change they make saying "this is config" or "this is content". With that you can script a db merge that just pushes config from dev to live.

hi migeul, alan, all

firstly, all praise and thanks for your work on Aegir, wonderful product and am hoping to get into it in a big way in 2011

a question and a comment or two

(stupid) question: does your workflow assume we have dev platforms directly in Aegir?
.. that is, we are dev'ing direct into Aegir hosted platforms ... or do we have a platform hosted on a web server outside of Aegir and then we bring that dev server into Aegir for test ? I like the idea of using Aegir integrated into dev, alongside git and other tools, but I wonder if Aegir would choke doing loads of verifications during busy dev phases ?

obvious comment 1: regarding the idea of using build files and keeping the local repo's relatively free, keeping everything upstream. Another example of this approach, is the very elaborate OCTOPUS/BARACUDA scripting in Grace's Omega8cc aegir approach i.e. OCTOPUS.sh.txt and barracuda/AegirSetupC.sh.txt . You can see in Grace's install scripts for Platforms she is very particular about module versions, something not so clear in your tutorial above

obvious comment 2: I see Dave Hall is working on porting UUID to D7 and there is already a UUID Features module which looks promising http://drupal.org/project/uuid_features

The UUID Features Integration module provides a mechanism for exporting content (nodes, taxonomy, fields) into a features module. What's that you say? You thought features was only for configuration? This module is meant to be used in the cases where certain pieces of content straddle the line between pure content and configuration.

personally I favor the idea Deployment as an approach, hopefully a sponsor for D7 port can be found and some serious content workflow can be built alongside UUID and Aegir

maintain the rage

-N

Great article.

Just curious, why do you use two make files instead of one?

Add new comment