Flexible deployment patterns with a Pantheon custom upstream

Flexible deployment patterns with a Pantheon custom upstream

While Acquia Site Factory is like a traditional Drupal multisite (one codebase, multiple sites), Pantheon’s model results in a unique codebase per site, with shared code in the custom upstream. While it is possible to consider each site as a standalone entity, I wanted to imitate Site Factory and use the upstream as the single code source for all sites.

The secret sauce to making this run fast is GNU Parallel, which executes commands in parallel rather than serially.

Routine maintenance and feature updates

My standard workflow is best for routine maintenance tasks like Drupal core and module updates, or theme and feature updates that can be installed automatically. All sites are updated in sync, from dev, to test, to live. This workflow has the highest level of automation and therefore lowest level of friction.

Code deployed to all sites simultaneously
Image
Diagram illustrating code deployed to all sites.
Standard workflow
  1. Merge pull requests into upstream codebase
    • Apply upstream updates to all sites on dev (always do this!)
      terminus org:site:list --upstream [uuid] --field name | parallel terminus site:upstream:clear-cache {}
      terminus org:site:list --upstream [uuid] --field name | parallel terminus upstream:updates:apply {}.dev
  2. Test the release
    • Clone live to test and deploy code to test on all sites
      terminus org:site:list --upstream [uuid] --field name | parallel terminus env:clone-content {}.live test
      terminus org:site:list --upstream [uuid] --field name | parallel terminus env:deploy {}.test
  3. Release code
    • Deploy code to live on all sites
      terminus org:site:list --upstream [uuid] --field name
      | parallel terminus env:deploy {}.live

Working on sites in batches

A batched workflow is sometimes needed for updates needing a lot of intervention, such as when content needs to be evaluated by a human or for updates that involve comprehensive or breaking configuration changes. I update sites in arbitrary groups—usually starting with simpler, low-risk sites and working up to more complex, higher-profile sites. This workflow is comprised of mostly manual processes and requires careful attention.

Code deployed to selected sites only
Image
Diagram illustrating code deployed to sites in batches.
Batched workflow
  1. Merge pull requests into upstream codebase
    1. Apply upstream updates to all sites on dev (always)
      terminus org:site:list --upstream [uuid] --field name | parallel terminus site:upstream:clear-cache {}
      terminus org:site:list --upstream [uuid] --field name | parallel terminus upstream:updates:apply {}.dev
  2. Test and release the first batch
    1. Test the release on batch 1 sites
      • Clone live to test and deploy code to test on batch 1 sites
        cat batch-1.txt | parallel terminus env:clone-content {}.live test
        cat batch-1.txt | parallel terminus env:deploy {}.test
    2. Release code on the batch 1 sites
      • Deploy code to live on batch 1 sites
        cat batch-1.txt | parallel terminus env:deploy {}.live
  3. Test and release the second batch
    1. Test the release on batch 2 sites
      • Clone live to test and deploy code to test on batch 2 sites
        cat batch-2.txt | parallel terminus env:clone-content {}.live test
        cat batch-2.txt | parallel terminus env:deploy {}.test
    2. Release code on batch 2 sites
      • Deploy code to live on batch 2 sites
        cat batch-2.txt | parallel terminus env:deploy {}.live
  4. Test and release the third batch
    1. Test the release on batch 3 sites
      • Clone live to test and deploy code to test on batch 3 sites
        cat batch-3.txt | parallel terminus env:clone-content {}.live test
        cat batch-3.txt | parallel terminus env:deploy {}.test
    2. Release code on batch 3 sites
      • Deploy code to live on batch 3 sites
        cat batch-3.txt | parallel terminus env:deploy {}.live
  5. Continue batch operations as above until code is deployed to all sites

Working on a single site

I use a focused workflow for tasks like building a new site or implementing a custom feature that impacts a single site. As with the other scenarios, I always deploy changes to all dev environments so I can evaluate the impact to the shared codebase. I deploy code for a single site to test—or even all the way to live—at many times throughout the sprint, sometimes multiple times in a single day. Once I’m satisfied with the code for that particular site, I roll it out to the rest of the fleet following a normal release process.

Code deployed to single site
Image
Diagram illustrating code deployed to a single site.
Focused workflow
  1. Merge pull requests into upstream codebase
    1. Apply upstream updates to all sites on dev (always)
      terminus org:site:list --upstream [uuid] --field name | parallel terminus site:upstream:clear-cache {}
      terminus org:site:list --upstream [uuid] --field name | parallel terminus upstream:updates:apply {}.dev
  2. At various times throughout the sprint, test the release on a single site. In some circumstances, it may be necessary to deploy a single site all the way to live to test the changes.
    1. Test the release on a single site
      • Clone live to test and deploy code to test on single site
        terminus env:clone-content site-n.live test
        terminus env:deploy site-n.test
    2. Optionally, release code on a single site
      • Deploy code to live on single site
        terminus env:deploy site-n.live
  3. Test the release on remaining sites
    • Deploy code to test on remaining sites
      terminus org:site:list --upstream [uuid] --field name | parallel terminus env:clone-content {}.live test
      terminus org:site:list --upstream [uuid] --field name | parallel terminus env:deploy {}.test
  4. Release code on remaining sites
    • Deploy code to live on remaining sites
      terminus org:site:list --upstream [uuid] --field name | parallel terminus env:deploy {}.live