Skip to content

Instantly share code, notes, and snippets.

@neilellis
Last active December 7, 2019 22:51
Show Gist options
  • Save neilellis/2d25f0ade3d6cae6f7c9 to your computer and use it in GitHub Desktop.
Save neilellis/2d25f0ade3d6cae6f7c9 to your computer and use it in GitHub Desktop.
An example Blue/Green deployment using Tutum and Cloudflare (for DNS)

Expects one argument the name of the production stack file for Tutum.

(see https://support.tutum.co/support/solutions/articles/5000569899-stacks )

Requires these environment variables to be set

  • CLOUDFLARE_DOMAIN - root domain of your app, e.g. example.com
  • CLOUDFLARE_KEY - your Cloudflare API key
  • CLOUDFLARE_EMAIL - your Cloudflare email address e.g. fred@example.com
  • PROJECT_NAME - a short name for your project e.g. example
  • TUTUM_USERNAME - your Tutum username
  • TUTUM_PASSWORD - your Tutum password
  • CLUSTER_SIZE - final cluster size

NB: The script assumes you have a loadbalancer service within your stack called 'lb'. You should have created a node cluster called ${PROJECT_NAME} and it is assumed that you normally have one node in the cluster and expand to 2 during deployment.

#!/usr/bin/env bash
# Expects one argument the name of the production stack file
#
# Requires these environment variables to be set
#
# CLOUDFLARE_DOMAIN - root domain of your app, e.g. example.com
# CLOUDFLARE_KEY - your Cloudflare API key
# CLOUDFLARE_EMAIL - your Cloudflare email address e.g. fred@example.com
# PROJECT_NAME - a short name for your project e.g. example
# TUTUM_USERNAME - your Tutum username
# TUTUM_PASSWORD - your Tutum password
# CLUSTER_SIZE - the initial cluster size (default 1)
#
# NB: The script assumes you have a loadbalancer service within your stack called 'lb'
# You should have created a node cluster called ${PROJECT_NAME}
# It is assumed that you normally have one node in the cluster and expand to 2 during deployment.
set -eu
cd $(dirname $0)
cluster_normal_size=${CLUSTER_SIZE:-1}
cluster_expanded_size=$(( cluster_normal_size * 2 ))
project=${PROJECT_NAME}
state=
alt_state=
if ! which tutum
then
echo "Please install Tutum CLI using 'sudo -H pip install tutum'"
exit 1
fi
if ! which cfcli
then
echo "Please install Cloudflare CLI using 'npm install -g cloudflare-cli'"
exit 1
fi
if (( $# == 0))
then
echo "Usage: $0 <stack-file>"
exit 1
fi
echo "Logging in to Tutum"
tutum login -u $TUTUM_USERNAME -p $TUTUM_PASSWORD
echo "Scaling out for blue/green deployment"
tutum nodecluster scale --sync ${project} ${cluster_expanded_size}
if tutum stack list | grep ${project}-blue | grep Running
then
echo "Current state is blue"
state=blue
alt_state=green
else
echo "Current state is green"
state=green
alt_state=blue
fi
while tutum stack list | grep ${project}-${alt_state} | grep -v Terminated
do
echo "Terminating exisiting ${alt_state} deployment"
if tutum stack terminate --sync ${project}-${alt_state}
then
echo "Terminated"
else
sleep 20
fi
done
echo "Starting new ${alt_state} deployment"
tutum stack up -n ${project}-${alt_state} --sync -f $1
echo "Changing DNS"
#Change DNS
cfcli --token ${CLOUDFLARE_KEY} --email ${CLOUDFLARE_EMAIL} --domain ${CLOUDFLARE_DOMAIN} --type cname -ttl 120 editrecord ${CLOUDFLARE_DOMAIN} lb.${project}-${alt_state}.${TUTUM_USERNAME}.svc.tutum.io
echo "Awaiting DNS propagation"
#Wait for DNS change over, we use a fixed time here as we have to wait for all cached DNS records to change before continuing
sleep 240
echo "Terminating exisiting ${state} deployment"
tutum stack terminate --sync ${project}-${state}
echo "Shrinking back cluster after deployment"
tutum nodecluster scale --sync ${project} ${cluster_normal_size}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment