In the previous article we discussed creation of aws lambda function written in
kotlin so we can benefit from the next advantages:
aws lambda is super scalable
it is really cheap
kotlin syntax helps to build robust implementation without overhead
aws java api is nicer to use because of the static typing which makes development easier and more productive
I also mentioned aws gradle plugin that was used to package and deploy lambda. The straightforward approach for deployment
is to use aws cli tool so you need to install it, you need to have python 3 and you have to know commands.
That’s why usage of the plugin which simplifies this process seems like a good idea. The plugin helps us to abstract
from aws cli tool, so we don’t need to know the commands and their sequence to deploy application - plugin does it instead of us.
In the current article we will discuss this gradle plugin in details.
Aws lambda deployment process
The whole deployment process of lambda function written in java can be divided in several steps:
Fat jar file creation - copying all the dependencies as archives inside our final jar file. It is crucial for java
lambda function because for now aws lambda function environment does not have way to download dependencies by itself and
they have to be provided packed within jar file.
NOTE: The most obvious indicator of absence of those dependencies is ‘ClassNotFoundException’ which
points to the class from our dependencies.
Packaging - for jar file in order to be used by aws cloudformation it has to be uploaded to s3 bucket and the path
to the file has to be inserted into the cloudformation template as a path to sources.
Deployment - when previous two steps are finished we have ‘FatJar’ and prepared cloudformation template with the source
path pointing to jar file. This artifacts are utilized by deploy command which creates related cloudformation stack in
your aws account.
These operations will be wrapped in our gradle plugin.
Implementation of the aws gradle plugin written in kotlin
Implementation of the plugin is pretty simple and will be done in kotlin as well as gradle configuration for it,
so everything will be implemented in one language.
Entire implementation of such simple plugin can be described in a few steps:
Create plugin class which contains plugin extension registration and creation of the tasks with their configuration.
I consider task as something similar to rest controller - it will react to the user interaction and start all necessary
processes. In our case task picks up plugin configuration and passes it to specific service. Services will just abstract
hard duty functionality from the tasks.
So this is our implementation of aws plugin class:
As you can see there are several operations:
Creation of the extension - this extension allows to configure plugin in gradle build file.
Tasks registration - which enables tasks to be used through gradle
Tasks configuration - this part is needed to organize lifecycle: which tasks are dependent and in which order they
have to be executed.
Next FatJarTask is pretty simple, all we have to do is to extend Jar task from java plugin and configure this task to
copy all dependencies into jar file.
NOTE: in this case configuration has to be done in the constructor, otherwise during invocation of this task an
error will be thrown which indicates that we cannot touch dependencies anymore.
Package and Deploy tasks utilize aws java sdk 2.0. Using this sdk we can do packaging of our source code into s3 bucket
and deploy the whole stack to aws account. All we need to do is to extend DefaultTask, create aws client and use it.
In PackageLambda task we need s3 client to create (if it is needed) s3 bucket, put jar file into it.
In DeployLambda task we are using cloudformation client to validate template, to check does stack with specified name
already exist or not and to create/update stack in aws.
So as you can see there is not a lot of things to be done to utilize aws java sdk and it can save us time during
development of serverless applications.
We are done with the implementation so let’s look at gradle build file.
As you can see there is gradle plugin for plugins. It simplifies plugin creation process:
automatically applies the Java Library plugin
adds the gradleApi dependency to the configuration
enables auto validation of plugin metadata during jar task execution
adds testKit dependencies
Maven publish plugin is important for us because we don’t want to publish this aws plugin in the internet (at least for now)
but still it has to be possible to use it in other projects. To do this all we need is:
properly configure maven publish plugin
build and publish aws plugin locally
import aws plugin in other projects
Configuration of the plugin can be found on the bottom of the build script.
Worth to mention this dependency "software.amazon.awssdk:bom:2.9.18" which is bill of materials file of aws java sdk -
it allows us to specify other aws dependencies without versions and they will always stay compliant to each other.
To use this plugin all we need is to write this lines of code in our build.gradle file: