Semi-Active Deploy for your Bluemix (Cloud Foundry) app

Bluemix logo

There's a new feature on Bluemix called Active deploy which makes deploying your app really nice to the user by keeping it running while the app is being deployed.

Some Cloud Foundry implementations are missing this feature, others don't include it for whatever reason they have. Here's a quick and dirty working example of how you yourself would be able to make your deployment semi-active, while keeping your app alive while the next build is being spun up and then swapping around the routing.

In a real world example, you're probably be using some CI solution like Chef, Jenkins or Travis, so let's say you already installed one of those and you'd like to use it to deploy your app to Bluemix.

For our example we're going to use Jenkins.
Jenkins

Since Jenkins is automatically giving us some functionality, let's use it to our advantage. Let's create a new Freestyle Project and add in a build step to Execute shell.

Before you write the deployment scripts we will need to understand a couple of things.

Jenkins environment variables

Jenkins provides a number of environment variables that get updated with every build run.
Every build run has a number that can be accessed using the $BUILD_NUMBER environment variable. The current build $WORKSPACE is also available to us. These numbers are related to a single Jenkins Project, but we can pass them along to another one using built in functionality.

In our deployment we will use a combination of a project name and the build number as a unique identifier of the app running in Bluemix, using the prefix myApp_ appending the $BUILD_NUMBER variable at the end.

Below is a simple script that will:

  1. Log in to Bluemix
  2. List out the apps listed in the organization
  3. Take the current *OLD* app name for reference
  4. Set a *NEW* app name using the current build number
  5. Swap out the app names in the manifest.yml file. This way you can keep your environment variables and other settings you set in your app manifest. Also, the route will be set directly in the manifest file.
  6. Un-map the route from the OLD app
  7. Delete the OLD app.
    Note: this will force delete the app without confirmation, so make sure you get this part right.

As a pre-requisite you'll need to install the cf cli tool.


    # Login to bluemix    
    cf api https://api.ng.bluemix.net
    cf login -u $MY_EMAIL -p $MY_PASSWD -o $MY_ORG m -s dev
    
    # Get old app name from apps running in Bluemix
    OLD_APP=$( cf apps | grep '^myApp_' | awk '{print $1}')
    echo $OLD_APP;

    # New app name
    NEW_APP='myApp_'$BUILD_NUMBER
    echo $NEW_APP

    # Change the app name in the manifest.yml file
    sed -i -e 's/name: .*/name: '$NEW_APP'/g'  $WORKSPACE/manifest.yml
    cat manifest.yml

    # Deploy application
    cf push 

    # Unmapping Bluemix app route
    cf unmap-route $OLD_APP mybluemix.net -n myApp

    echo "You-re approaching the Danger zone"
    # Deleting old app
    cf delete $OLD_APP -f

There you have it. You're deployment is now semi-active. It will stay up until the new app is fully deployed and then take down the old one.

Also another note, this is not a fully functional Active deployment. Meaning, this will create a new app every time you deploy the application.

If use services that collect app information that are bound to a specific app number, you may lose some of your data, since every deployment creates a clean new app. If you do care about these things you will need to approach your deployment in another way, like using the real Bluemix Active Deploy

Sitting with a laptop