Automate Drupal 8 Deployment On Pantheon With Quicksilver Scripts

Drupal 8 has made it a lot easier to deploy the configuration of a site from one environment to another, but there are still quite a few tasks that you often end up needing to do manually.

For example, you usually want Drupal's Google Analytics module uninstalled on Dev and Test environments, but installed on Production. Also once Google Analytics has been installed on Production, you want to set it up to use your site's Google Analytics ID and other configuration options.

Automating Deployments

Completely automating deployments obviously saves a lot of time, it makes deployments much safer as there's less chance of forgeting to make some critical change, fits in with automated testing workflows, and also saves people from having to do boring repetative work that's best handled by a machine.

Wouldn't it be great if we could automate these tasks for each environment and have a one-click deployment? 

Pantheon Drupal Hosting

We've been using Pantheon hosting for some of our Drupal site development projects for a while now and have come to quite like their built in workflows, in fact the process is so smooth that it makes having to do all the post deployment manual steps feel all the more annoying!

Luckily the fine folks at Pantheon have also provided us with a way to script the automation of all these tasks with a feature that integrates beautifully with Drupal 8.

Quicksilver Platform Hooks & Drupal

Quicksilver is a feature of Pantheon hosting that can trigger actions when a step of a workflow happens.

Triggers can be code being deployed, code being committed via Git, the database being cloned, or cache being cleared, and each of these triggers can be specified as a before or after the workflow step happens.

Each trigger can run one, or more, custom PHP scripts that you add to a /private directory at the top level of your project.

Triggers, and which script they run, are specified in a pantheon.yml file which also sits at the top level of your project.

Here's an example of what that looks like:

workflows:
  clone_database:
    after:
      - type: webphp
        description: Uninstall modules
        script: private/scripts/uninstall_modules/uninstall_modules.php
      - type: webphp
        description: Enable modules
        script: private/scripts/enable_modules/enable_modules.php
  deploy:
    after:
      - type: webphp
        description: Import specific configuration
        script: private/scripts/import_config/import_config.php
      - type: webphp
        description: Clear cache
        script: private/scripts/clear_cache/clear_cache.php

Scripting Drupal Tasks

Your scripts should be coded in PHP and put into a top level /private directory, that you'll need to create, which Pantheon automatically prevents anyone from accessing through the web.

What scripts you add and how you organise them within the /private directory is up to you, as you can set the path to scripts in the pantheon.yml file.

At Code Positive we've established a few patterns as part of our Drupal support and maintenance work which I'd like to share with you....

Organising Quicksilver Scripts

Following the Drupal pattern we treat each script as it's own self contained module, with a standard set of files and directories:

  • README file for documentation
  • PHP file that contains all the code for what the script does
  • Config directory that has a sub-directory for each environment
  • Settings files that can be added to the sub-directory of each environment

This pattern enables us to provide specific settings for each environment and keep the logic of the script completely seperate.

We're able to use PANTHEON_ENVIRONMENT in our code to check which environment is currently being acted on and load the settings file for that environment:

if (defined('PANTHEON_ENVIRONMENT')) {

  switch(PANTHEON_ENVIRONMENT) {
    case 'live':
    case 'test':
    case 'dev':
      $config_file = dirname(__FILE__) . '/config/' . PANTHEON_ENVIRONMENT . '/config.inc';
      break;
    default:
      // Multidev instances.
      $config_file = dirname(__FILE__) . '/config/multidev/config.inc';
      break;
  }
}

Drush

Drush is a command line interface for Drupal that provides a huge number of commands for a wide range of Drupal tasks.

We can use Drush in our scripts to do most of the work by using the passthru() function to set Drush commands.

For example, to enable specific modules:

passthru("drush pm-enable -y $module");

If we need to use a Drush command to get data from Drupal use the shell_exec() function.

For example, to get a list of enabled modules:

$module_list = shell_exec("drush pm-list --type=module --status=enabled --pipe 2>&1");
$enabled_modules = explode("\n", $module_list);

Debugging

Use Terminus, Pantheon's command line interface, to debug scripts.

Once you're logged into your site on Terminus you can see debugging messages printed out by your scripts.

For example:

echo('Configuration imported.' . "\n");

Code Positive Quicksilver Scripts For Drupal Deployment

Quicksilver scripts for automating Drupal 8 deployments on Pantheon are fairly quick and easy to write, but even better than that, you may not need to write them at all!

We're making available the scripts we use at Code Positive, which cover most of the tasks we used to do manually.

These scripts are ready to be used on any site, all you need to do is read the instructions in the README file for each script and set them up the way you want them to work on each environment.

Here's what they do....

Enable Modules

This script enables whatever Drupal modules you specify to be enabled.

Make sure you have the modules in your code base, and then list their machine names in the config.inc file for the environment they should be enabled on.

For example create a config.inc file and add it to .../enable_modules/config/dev/

<?php

$config = array(
   'devel',
   'kint',
   'update'
);

If a module is already enabled the enable command is skipped for that module and the script tries to enable the next module on the list.

Uninstall Modules

This script uninstalls whatever Drupal modules you specify to be uninstalled.

Configuration is the same as for the Enable Modules script.

Make sure that the module(s) are still in the code base before uninstalling as they contain uninstall steps for removing themselves cleanly from the database.

Import Config

This script imports specific configuration into Drupal, such as the settings for the Google Analytics module.

Use Drupal to export specific settings as individual files and add the files to the config directory of the environment it should run on.

The settings files will be auto-detected so this is both incredibly powerful and incredibly easy to use.

Clear Cache

This script clears the Drupal cache.

To use this create a config.inc file and add it to the environment you want to clear cache on, for example: .../enable_modules/config/dev/config.inc

  <?php

  $clear_cache = TRUE;

If you're interested in writting your own scripts this is the best of these script to look at first as it's a very simple script built around the Drush command for clearing cache.

Get The Scripts

All of the above Drupal deployment scripts can be downloaded from our repository.

Let us know in the comments below if you find the scripts useful, and if there's any improvements you can suggest.