Serverless deployment with GitHub and Lambda

January 9, 2020

Serverless deployment with GitHub and Lambda

In this article, we'll show how easy it is to get a Java application running in AWS Lambda by using Buddy for your Continuous Integration and Continuous Deployment. In 15 minutes time, you're going to be running your software in the cloud.

AWS Lambda has become a powerhouse of software deployment. It encourages simple, self-contained, stateless functions that run themselves and eliminate a large portion of the traditional operational overhead that is associated with running software. Alas, many CI/CD tools have a lot of catching up to do before they're even close to the kind of ease that AWS Lambda offers.

Buddy aims to be break this mould. No need to run Jenkins servers, no need to wonder why your build isn't starting or the logs aren't appearing. Just a clear, simple user interface that makes deploying your application as easy as running in.

Prerequisites

This tutorial is going to be simple and straightforward. You'll need a couple of things before we get started…

  • An AWS account that you can use to spin up infrastructure. You will also need the secret and access key for your IAM user or root account
  • An account on Buddy
  • A GitHub account that is integrated with Buddy
  • A tolerance (or love if you're so inclined) of Java
  • About 15 minutes of glorious, free time

First, wire up your app

You could put together your own application using the AWS Docs, or you can find a ready made example here. If you do decide to make your own application, be mindful that I'm making the assumption you're using Maven and Java 8. It doesn't make much difference though: Buddy supports Gradle and later versions of Java too.

The important thing here is that your repository is pushed up to your GitHub account, whether it's a fork of our premade repository or your own marvelous creation.

Create your AWS Lambda

Sign into the AWS console and navigate to the Lambda section. You're going to do what every developer loves to do. Make something new and shiny.

  1. Create a new function with the glossy orange button:

Create AWS LambdaCreate AWS Lambda

  1. Give it a function name and select the Java 8 runtime environment. These are the only bits of required information that your Lambda needs to exist.

Lambda basic infoLambda basic info

There is also a permissions section. However, for the point of this tutorial, don't worry about it.
  1. When you create your Lambda, there is only one field that you'll need to change. Lambda needs to know what file and function it should invoke when it is triggered:

HandlerHandler Ain't nobody calling their app "example" – change this to match your package name, class name and function. If you're using my example, you should update this field so that it contains the following:

com.chris.buddy.LambdaHander::handleRequest

Set up your Buddy pipeline

Okay. Head on over to Buddy and click on that lovely New Project tile (another new thing, this must be developer heaven!). Once you click it, you'll need to select your Git provicer and the repository to use.

  1. Choose your Lambda example that you'd like to build:

Create new Buddy projectCreate new Buddy project

  1. Buddy automatically knows that it's a Java application, so click Add a new pipeline on the next page. Name your pipeline and configure it how you like. As a sensible default, I prefer to go for something like this:

Add new pipelineAdd new pipeline

This way the pipeline will be triggered whenever I push a commit to the master branch.

  1. Select the Maven tile, since it has already been kindly highlighted for you by Buddy. Just look for that red Detected sash on the top left of the tile:

Maven selectionMaven selection

  1. On the next page, you'll see that it has already filled in some sensible Maven commands. For my example, this will work perfectly. If it isn't what you want, feel free to amend, but mvn clean install tends to cover most bases.

Maven detailsMaven details

  1. Once the acton is added, you should run your pipeline. This will write your .jar file to your target folder. This is important for the next step. Check that everything passes okay when you've ran.

Now for the Lambda

The last step is to add the Lambda action. To do this, you'll need to click the + symbol just below your Maven step in the Primary Actions section:

Primary actionsPrimary actions

This will open up the menu, from which you can choose your Lambda deploy action. You can either enter "lambda" in the search input, or scroll down a little bit until you arrive at the Amazon Web Services section which contains a wealth of preconfigured actions for you to make use of. Select the Lambda Deploy tile:

AWS action rosterAWS action roster

At this point, you'll be faced with a prompt, asking for your new AWS Integration. If you've not done this before, you'll simply need to paste in your secret and access key from your AWS account. Once you've done this, you'll just need to wire up the action.

The reason you needed to run your pipeline in step #5 was so that Buddy is aware of the output in your target directory. When you're configuring your Lambda action, click on the Browse button next to the path to your Lambda code. Here you can view the contents of the pipeline filesystem:

lambda-browselambda-browse

The filesystem is the pipeline's cache. It contains a clone of the repository in the newest revision + files generated and modified by build actions (artifacts).

In my example, the output artifact is named buddy.jar:

Browse pipeline filesystemBrowse pipeline filesystem

Click on buddy.jar and select the blue button to use it as the source path for the deployment (you should see the path has now updated in your configuration). The rest is simple. Select the region that your Lambda exists in. For me, it was eu-west-1 so I selected EU (Ireland). Buddy has automatically created a dropdown list of your lambda functions. Select the lambda function you just made from this list, then select Save this action.

And give it a whirl!

Click on Run pipeline, give it a funky comment, and watch the magic happen. Both steps should go green and you'll see that your code has now been deployed to your AWS Lambda. If you're using my example, from the AWS console you can create a test function that looks like this (the key bit is you simply pass in a raw number):

Configure test eventConfigure test event

From there, save this event and click the Test button to see the output! You should see the string version of your number played back to you, with a nice little message:

Execution succeededExecution succeeded

Cheers! You've done it! 🍾🙌

How could we take this to the next level?

Buddy supports YAML configuration too, so if we wanted to we could have invoked all of these actions from a buddy.yml instead of manually clicking about. So how would you do this?

In Buddy, look for this button on the right hand side:

YAML config switchYAML config switch

Click it, click it, click it. This will bring up a dialog with a switch. Click that switch, too (obviously) and it will change the pipeline mode from GUI to YAML. This means your pipeline is now expecting a buddy.yml configuration file in the root of your repository.

If you're using my example repository, you already know it exists in the repository because it automatically creates the pipeline upon adding the project. If you aren't, the following documentation on YAML should be clear and easy to follow, but if you want to generate one for yourself, you can see the YAML version of your pipeline here:

Show YAML for pipelineShow YAML for pipeline

When you click this, you'll see the YAML definition of a Buddy pipeline. This YAML is easy to read and understand on its own. For example, here is the YAML taken from the premade sample repository:

- pipeline: "my-lambda-pipeline"
  trigger_mode: "ON_EVERY_PUSH"
  ref_name: "master"
  ref_type: "BRANCH"
  trigger_condition: "ALWAYS"
  actions:
  - action: "Execute: mvn clean install"
    type: "BUILD"
    working_directory: "/buddy/buddy-lambda-example-1"
    docker_image_name: "library/maven"
    docker_image_tag: "3.3.3"
    execute_commands:
    - "mvn clean install"
    cached_dirs:
    - "/root/.m2/repository"
    mount_filesystem_path: "/buddy/buddy-lambda-example-1"
    shell: "BASH"
    trigger_condition: "ALWAYS"
  - action: "Deploy function buddy-lambda"
    type: "AWS_LAMBDA_DEPLOY"
    local_path: "target/buddy.jar"
    region: "eu-west-1"
    function_name: "buddy-lambda"
    trigger_condition: "ALWAYS"
    integration_id: 58538

Overview

So there you have it. Somewhere in the depths of an AWS datacentre, on a blade server in the middle of a rack, your code is executing and returning a response to your UI. The code was put there by Buddy and its great range of integrations.

This process is made easy by technologies that focus on productivity, simplicity and reliability. By allowing people to focus on these values, businesses can more rapidly achieve their outcomes and software engineers can focus their efforts on the things that matter most to them.

And this is what Buddy is all about.

Share:

Chris Cooney

Chris Cooney

Full-Stack Developer

Chris has been a software engineer for five years, working across multiple industries and with various technologies. His recent focus has been on automation and developer experience.