Deploy from Slack to Jenkins and Opsworks

OpsWorks can manage the life cycle of an application. But most of the time we find it useful to orchestrate OpsWorks deployments through Jenkins events because Jenkins easily integrates with many current workflows for most of the clients. Let’s talk about some of the challenges this workflow addresses and some steps use to implement deployment thru Slack.

The challenge

  • Although Amazon OpsWorks can manage deployments, we still need ability to unit test before the deployment
  • Every time you make changes to cookbooks, OpsWorks requires to run “update custom cookbook” command for your changes to be uploaded to the servers. If necessary, this workflow allows users the ability to run update custom cookbook as part of the deployment
  • OpsWorks doesn’t allow to one to associate an APP with a set of servers – or I should say an OpsWorks Layer, in particular. Thus, sometimes people end up triggering deployment on unnecessary servers. In this a Jenkins job, we can look up which instances are running in a OpsWorks Layer and deploy to those alone.
  • Jenkins already has good slack integration, it can posts build related information to a selected Slack team and channel. And one can easily trigger builds right from Slack. This saves time and provides more visibility in Slack directly and in other dashboards and workflow integration tracking points.

Integration with Jenkins

First off, let’s start with the code to trigger Opsworks deployments from Jenkins. It’s easy to trigger deployment from command line using aws-cli with create-deployment option, but this commands exists with a deployment-id and it’s hard to tell if the deployment was successful or not. Below is the code which checks to make sure Opsworks deployment was a success. You will need the Layer ID to look up running instances in a OpsWorks layer, as well as the APP ID and STACK ID.

Add boolean parameter for allowing users ability to run Update custom cookbooks as part of the deployment.

Screen Shot 2015-04-01 at 3.09.14 AM

#!/bin/bash
sudo apt-get install -y jq
export AWS_DEFAULT_REGION=us-east-1
LAYER=YOUR_LAYER_ID
STACK=YOUR_STACK_ID
APP_ID=YOUR_APP_ID
INSTANCES=$(sudo /home/ubuntu/.local/bin/aws opsworks describe-instances --layer-id $LAYER  | jq -r '.Instances[].InstanceId' | tr "n" " ")
export INSTANCES

if [ "$Update_custom_cookbook" = "true" ]; then
UPDATE_COOKBOOK_ID=$(sudo /home/ubuntu/.local/bin/aws opsworks create-deployment --stack-id "$STACK" --command "{\"Name\":\"update_custom_cookbooks\"}" --layer-id "$LAYER" | jq -r '.DeploymentId')
echo "$deployment_id"

UPDATE_STATUS=$(sudo /home/ubuntu/.local/bin/aws opsworks describe-deployments --deployment-id "$UPDATE_COOKBOOK_ID" | jq -r '.Deployments[0].Status')
while [ "$UPDATE_STATUS" = "running" ]
do
 echo update custom cokobook is "$UPDATE_STATUS"
 sleep 7
 UPDATE_STATUS=$(sudo /home/ubuntu/.local/bin/aws opsworks describe-deployments --deployment-id "$UPDATE_COOKBOOK_ID" | jq -r '.Deployments[0].Status')
done

if [ "$UPDATE_STATUS" = "failed" ]
then
 echo "build failed"
 exit 1
fi
fi

DEPLOY_ID=$(sudo /home/ubuntu/.local/bin/aws opsworks create-deployment --stack-id $STACK --app-id "$APP_ID" --command "{\"Name\":\"deploy\"}" --layer-id "$LAYER" | jq -r '.DeploymentId')
echo "$deployment_id"
DEPLOY_STATUS=$(sudo /home/ubuntu/.local/bin/aws opsworks describe-deployments --deployment-id "$DEPLOY_ID" | jq -r '.Deployments[0].Status')
while [ "$DEPLOY_STATUS" = "running" ]
do
  echo "$DEPLOY_STATUS"
  sleep 5
  DEPLOY_STATUS=$(sudo /home/ubuntu/.local/bin/aws opsworks describe-deployments --deployment-id "$DEPLOY_ID" | jq -r '.Deployments[0].Status')
done
if [ "$DEPLOY_STATUS" = "failed" ]
then
  echo "build failed"
  exit 1
fi

Post back Jenkins job status on Slack

Slack has well documented integration for Jenkins. If you go to configure integration in Slack and select Jenkins, it walks you through on how to configure Jenkins.

  • Click on configure integrations
  • Select Jenkins CI

  • Select the channel you want notifications posted too
  • Now logon to your Jenkins server and go to “Manage Jenkins”

  • Click on Manage Plugins and search for Slack in the Available tab. Click the checkbox and install the plugin.

  • Follow the instructions in your Slack Account from here on to add your token etc. The URL will be of the form: https://YOUR_COMPANY_NAME_HERE.slack.com/services/new

Trigger Build from Slack

Here are the steps if you want to trigger build right from Slack. You need to Install build Authorization Token Root Plugin.


Now, select Trigger builds remotely (e.g., from scripts) from the Job. Slack auto generates a random token, see screenshot below. You can use that token, or generate random one.


Go to Slack integration. Select Slash Commands.  For the URL, use this format: http://{server_IP}:8080/buildByToken/build/?job={name_of_the_job}&token={AUTH_TOKEN}. Make sure to select “autocomplete”. That way when you type “/deploy”, it will automatically give you suggestions.

And that’s it, you can trigger OpsWorks deployment right from Slack and have the deployment post back the status in the channel you choose – perhaps a dedicated “Jenkins room”.

  • terryj_at

    Ok….now can I disqus this with you?

  • b3dfintech

    Thankyou so much for this script!!!!!!

Subscribe to Our Newsletter

Join our community of DevOps enthusiast - Get free tips, advice, and insights from our industry leading team of AWS experts.