CircleCI private Slack notifications with a Ruby AWS Lambda
Our engineering team is growing every week and as we are quite bullish on TDD with high test coverage (lowest score is 96% amongst our Rails apps) we rely heavily on CircleCI to check our work.
When a build was failing, our previous approach, was to notify everyone in a Slack channel using their default add-on. This strategy worked well with 1 or 2 contributors but started to be very “noisy” with 5+ contributors.
Our new approach notifies only the author on Slack with a direct link to the failing build :
There are many possible approaches to this problem, but as AWS recently announced ruby support for AWS Lambda we wanted to give it a try !
We noticed it was possible to register a webhook for all CircleCI builds of a particular project:
All we needed then was to detect failed payloads and then notify Slack in a private channel. We’ll use a Ruby-based AWS Lambda to identify the person who broke the build and notify them right away!
Building a Ruby serverless function on AWS Lambda
which will create a serverless.yml file that we tweeked a little in order to add a POST trigger on our lambda:
As I said, we are TDD fans so let’s start by adding some basic specs to detect failed builds:
And finally our main code :
Alright, everything is working nicely, we are able to successfully detect CircleCI build failures. Let’s add Slack to the mix to notify the author!
Private Slack notifications
Luckily for us, there is a ruby gem for that: slack-ruby-client. All you have to do is follow their Readme to create a Slack bot.
The first tricky part then is to protect your newly generated Slack token. AWS have their own service for this purpose which is very easy to use with their command line interface:
Storing environment variables on SSM is not a bulletproof strategy as mentioned in this article. But it will be sufficient for the scope of this article.
The next tricky part is that the CircleCI payload contains the Github login but not the Slack login. We created a simple hash to manage the conversion. Here is the final code:
Automatic CircleCI deploys
With the serverless framework you can very easily deploy from your own laptop. But why not let CircleCI do everything for us!? Let’s add some config in order to automatically deploy our master branch in production if our specs are green:
You will need to configure two environment variables on your CircleCI project: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY which correspond to an IAM user with permissions to deploy this lambda.
Bonus point, our lambda consumes itself if a build fails ;)
Here is the final repo with everything you need to setup private Slack notifications when your CircleCI builds are failing : https://github.com/honestica/lambda-circleci-notifications-example
Building this lambda was quite fun as everything worked as advertised. The final code also uses Sentry to monitor errors (apart from setting an environment variable, you pretty much have nothing to configure with their awesome ruby gem raven-ruby).
Is Ruby the best langage for this job? I’m unsure. But when I switch to other langages I am usually a bit weary about the test philosophy and the feeling that they are not first class citizens, which tends to procure a very poor developer experience.