Get started with CI/CD using Buddy
Part 2 of “Comparing CI/CD Tools”. In this introduction to Buddy, we’ll explore how easy it is to build and deploy a simple Python Flask application to AWS Elastic Beanstalk.
Welcome to the second part of a series of articles comparing CI/CD platforms. To help evaluate, compare and contrast the tools currently dominating the market, the goal will be to automate the deployment of a Flask application onto AWS Elastic Beanstalk. A new deployment will need to occur after every push to main branch, and during the series this same requirement will be implemented across several CI/CD tools.
Our first article looked at GitHub Actions, which you can read below.
Get Started With CI/CD Using GitHub Actions
In this introduction to GitHub Actions, we’ll explore how to build and deploy a Python Flask application to AWS Elastic…
Next up, part 2 will focus on Buddy — to be found online at https://buddy.works. I’ll document the steps taken along the way to achieve the goal with Buddy, and there’s a write up of the positives and negatives in a conclusion at the end of this article.
The Flask application
Our Flask application is a simple “Hello World” example, and for the purposes of demonstrating running unit tests within the pipeline, we have included a test case as well.
AWS Elastic Beanstalk
Our Flask application is going to be deployed to AWS Elastic Beanstalk which is a service that automates the deployment and scaling of a web application. It takes in our source code and takes care of all the infrastructure configuration.
Introduction to Buddy
The Buddy homepage boasts some very impressive stats: “87% faster CI/CD adoption time by teams” and “12 seconds of average deployment time”.
It’s not hard to see why — there is a low barrier to adoption and pretty much anyone could get started with Buddy within minutes. What I like straight off the bat is the fact the initial steer for users is to create the pipeline via the GUI, which will be a huge draw for many — with the fallback of configuring as code for your DevOps folks (we do love our yaml).
Once you’re into the nuts and bolts, here are a few core concepts of Buddy.
The core concept of the Buddy platform is the pipeline that allows you to build, test and deploy your application on a single push to a chosen branch.
Pipelines can also be triggered manually or on a timer, and they can be chained (pipeline A > pipeline B > pipeline C).
A pipeline is made up of a series of steps and on Buddy these are called actions. An action will run in a Docker container, and each action consists of a small series of shell commands — such as building and running unit tests for an application, uploading to a server, sending notifications, and so on.
You have access to configuring environment variables for each action, and can configure and integrate with associated services such as a database.
Environment variables can also be configured at the workspace or project level, not just at the pipeline/action level, so your options are powerful there.
An execution is a single run of a pipeline on the Buddy platform. Every run is saved and you can review the execution history to see who or what triggered the pipeline, when was it and for which git revision.
Integrations are third-party services that you can integrate with your Buddy projects, like repository and website hosting services, testing tools and notification apps.
Examples include GitHub, AWS, Heroku, Slack, GitLab, Cloudflare, Firebase, and much more.
Although not technically called an “integration” within the Buddy ecosystem, there are many built-in actions that build out common use-cases for integrating with third party platforms. And while I was writing this article, they added a few more.
These are the steps we will follow to create our CI/CD pipeline.
- Create an empty repository in GitHub.
- Sign up for an account on Buddy.
- Create a project and set up an initial pipeline. Our pipeline will run after every
pushevent on the
- Extend our pipeline to deploy to Elastic Beanstalk.
- Try out the yaml helper and configuration.
Step 1. Create GitHub repository and initial workflow
Create your GitHub repository and upload your initial application code. My demonstration code is a simple “Hello World” Flask application, a test case, and a requirements.txt for defining the dependencies.
If you are following along your initial structure should contain three files:
Alternative. I went with GitHub, but you don’t have to. You can create your repository directly within the Buddy platform; use Bitbucket or GitLab; or bring your own Git hosting.
Step 2. Sign up for a Buddy account
Head over to https://buddy.works and register. I used my GitHub account to register and gave Buddy access to my source code repositories.
You will automatically be put onto a 14-day free trial of their Pro Plan ($75 per month), but there is also a Free Plan which is sufficient for developers, freelancers, and more than enough to get a good look at the platform.
Step 3. Set up our first pipeline
Under the Free Plan you’ll be able to create 5 projects. Once registered and signed in, you’ll find yourself on the workspace dashboard where you can “Create a new project”. Let’s do that now.
Select your repository and Buddy will auto-detect the language as Python and give you the option to set up your pipeline. Keep going through the GUI — it’s the default option and we’ll look at the yaml option later.
We want to trigger our pipeline after every push to the
main branch, so select the “on push” option and ensure that the correct branch is selected — Buddy will pre-populate and it was all correct for me without needing any changes.
After creating your pipeline, the next step is to add an action. You’ll see that Buddy has auto-selected Python and is making a suggestion to use it. Let’s follow that and select Python.
Buddy will pre-populate the out-of-the-box Python action and we’re going to do a few small tweaks.
- Firstly, update the version of Python. The default on Buddy is 3.5, but we’re going to bump this to 3.6.12. You can pick 3.7.x and 3.8.x as well.
- Next let’s change the Action name from “Execute: nosetests” to “Execute: test_application.py”. You see this under the Action tab.
- Finally, update the script commands per that shown below.
pip install -r requirements.txt
At this stage you can save your action. Before you do, check out the other tabs while you are here. For example, you will see that Buddy will automatically create a pip cache to save your dependencies — this is a good feature, one we typically would want anyway, and so by being enabled by default this saves users from having to spend the time to configure it.
On saving, you will see your pipeline has the single primary action we just created.
Once saved, we now want to manually “Run pipeline” which you will find in the top right of the UI screen. In this section, you’ll also notice “Badge” (which you can configure in your README markdown file if you have one) and “Slack handle” options for notifications. Run the pipeline and you should see it run quickly and successfully.
Click through for the logs of the execution.
Well done, at this stage you have successfully linked your source code repository, downloaded (and cached) dependencies, and tested your application works correctly.
Step 4. Deploy Flask application to Elastic Beanstalk
Now that we have a successful “build & test”, we want to deploy the application for testing purposes. We’re going to do this by adding a new action to our existing pipeline which will run after the first action is successful.
Back in the pipeline click the cog underneath our first Action to append a new one. You will notice how you can add pre- and post- actions and chain a workflow together — very nice visualization.
You could scroll down here, but let’s use the “Filter actions…” box and search for “AWS”. Here you will find many targets, one of which is Elastic Beanstalk.
First time through you’ll be asked to create a new “AWS Integration”, so paste in your Access Key ID and Secret Access Key and save.
(remember, AWS security best practice would be to create a dedicated User with programmatic access and having permissions just to deploy to AWS Elastic Beanstalk).
Now we want to configure our options for our AWS Elastic Beanstalk application. Keep the defaults and under Application drop down select “Create an application” — the Buddy platform will direct you to AWS to complete this part — or select an existing Application if you have one.
Here’s my configuration, ready to be saved.
And my complete pipeline now looks like this.
Run the pipeline again, and within a minute you should see your Flask application up and running in AWS Elastic Beanstalk.
Well done, you’ve successfully run a build, test, deploy to Elastic Beanstalk, all thanks to the Buddy platform — it’s probably taken longer to read than do the work; I would estimate getting to this stage for most users would be 2–3 minutes maximum.
Now let’s test the trigger on code push. I’ve made a small edit to my example application to change the message to “Hello World!”.
Within seconds of push, the pipeline was running in Buddy, and less than a minute later it had finished. Refresh our browser and we can see the new message is being displayed.
That’s the end of the demonstration. You should have successfully built and deployed your application to Elastic Beanstalk and been through the cycle of a code change and seen that change reflected in AWS almost immediately.
Did we see YAML?
Yes, there’s a YAML option as well as the UI-generated process. You can build your pipeline from scratch, or in our case, since we already have our pipeline created we can use the option to “Export the current pipelines to YAML”.
If you choose to configure your pipeline using YAML, you have to save this file as
buddy.yml in the root of the source code repository. Let’s do that now.
You’ll also need to toggle from “GUI” to “YML” via the “YAML configuration” tab. By default Buddy is all GUI-driven, but you switch to a “pipelines as code” model very easily.
Before this week, I hadn’t come across Buddy but it’s very much got the feel of a big-player. The ease of use, the feature set, the speed of deployment, the number of integrations — I could go on — it’s got a lot going for it.
Back to their website claims — “87% faster CI/CD adoption time by teams” and “12 seconds of average deployment time” — to be honest, I believe both to be true. Having used many different platforms over the years, Buddy has definitely been one of the quickest to get started with and I’d expect engineers of all disciplines and experience to be up and running within minutes.
Article first written November 2020 and things change over time. At the time of writing, here were my findings…
- Free tier to get started. Not overly generous, but sufficient. You get 500MB of storage and 120 executions per month. Noticeable that Buddy don’t feature “execution minutes” in their pricing model.
- A huge list of ready-made integrations with GitHub, AWS, Heroku, Slack, GitLab, Cloudflare, Firebase, and many more.
- Provides git repository hosting for a fully integrated service. Although not tied — so hosting at GitHub works just as well.
- All the core facets of a pipeline are catered for including my basic “must have” options to trigger on code updates, manual “push button” steps, and a scheduler option to run pipelines on a timer.
- The extensive documentation is awesome — both layman and developer focussed and very well presented. I was amazed at how much content there was and found step-by-step examples for pretty much every scenario I could think of.
- To be honest — the documentation is so good that it makes articles such as this largely redundant — on top of which, the platform is so intuitive the documentation might not even be that necessary in most cases.
- There’s a feature around monitoring pipelines which is more than intriguing, if not a little puzzling. At first this felt out-of-place under the banner of a CI/CD, and I was concerned if this could dilute the platform — since Buddy see it as a means to “monitor your websites and services for downtimes and get notified whenever taking action is required”. On the one hand, there’s power in all-in-one platforms but on the other hand, I also like platforms that do just what they say on the tin where their focus is to do one thing and do it excellently. I also like picking the best tool for the job, so my natural inclination is to avoid the multi-purpose options. In Buddy defence here, their web page title is “The DevOps Automation Platform” so this feature clearly fits into that domain — yet the site shouts “CI/CD” everywhere else — maybe Buddy would do well spinning this off and maturing their service observability, monitoring, and alerting separately. With that written, I then thought about it over the last week and I began to see how you might be able to chain pipelines and use the concept of service monitoring into a workflow — perhaps as a canary or to verify a deployment to trigger a switchover of traffic. Good feature, but makes my neutral list for now while I sit on the fence.
- Once you burned your Free Plan limit of 120 executions in a month there is a big step in terms of pricing — “free” jumps to $75 per month and then $200 per month. Definitely a lot of value in the platform to justify, just feels for me like an intermediary price point is required.
- In my particular use-case, directing me to AWS to manually set up my Elastic Beanstalk Application and Environment felt a touch clunky — given the high expectations of “low touch” set by this stage — so I’m sure a seamless fully-integrated EB experience won’t be too long away.
- I got an error using the yaml that was auto-generated via the yaml helper. Although it worked first time through, I was hoping Buddy would pick it up automatically on a new project pointing at a repository already containing a
buddy.ymlfile. I got the error below with the same repository used throughout the demonstration. At the time of writing, I have pinged the Buddy team to ask why this might be the case.
A note from the author
Thank you for reading this article — I hope you found it useful and please read the remainder of the series as I compare other CI/CD tools.
All source code for this demonstration can be downloaded at GitHub.