Configuring CI/CD pipeline for AWS Lambda functions.

Jul 4, 2022 |
Views: 397 |

Reading Time:

This post is authored by Bishal Sarker, our resident Software Engineer at Astha IT.

Let’s do something cool today! We are going to create an AWS Lambda function and deploy it using CI/CD pipeline. If you have no idea about what I’m referring to, no worries. Here are some basics before you can move on:

AWS Lambda is a serverless computing service provided by Amazon Web Services. The concept of “serverless” computing refers to not needing to maintain your own servers to run these functions. Read more,

A CI/CD pipeline is a process that drives software development through a path of building, testing, and deploying code. Read more,

So, why use a pipeline if we can upload ours to Lambda manually?

We can upload it manually, that’s true. But that is only convenient when our code doesn’t need to be modified frequently and that scenario is very rare in actual software production.

Let’s begin with our code!

Okay! So firstly, let’s create a simple node.js function which will be used for sending emails. This is our send-email.js file:

const nodemailer = require(‘nodemailer’);

const sendEmail = () => {
 const smtp_config = {
   host: ‘smtp_host’,
   port: ‘smtp_port’,
   auth: {
     user: ‘smtp_auth_username’,
     pass: ‘smtp_auth_password’
   }
 };

 const transporter = nodemailer.createTransport(smtp_config);
   const email_request = {
     from: ‘from@abc.com’,
     to: ‘to@abc.com’,
     subject: ‘Test Email’,
     body: ‘Hi, this is a test email’
 };

 transporter.sendMail(email_request, (error, info) => {
   if (error) {
     console.log(error);
   } else {
     console.log(“Email sent to: ” + email_request.to);
   };
 });
};

module.exports = { sendEmail };

We will also need an index.js file with a handler function. It’s a Lambda convention. While triggering, Lambda will look for an index file with a handler function. Here’s is the file:

const { sendEmail } = require(‘./send-email.js’);

exports.handler = (event) => {
 sendEmail();
};

Now, let’s push all the codes in our repository. I’m using Bitbucket.

Configuring pipelines for the repository

After our code is pushed, we need to enable a pipeline for our repository. This step will be different for other code repository hosting platforms (GitHub, Gitlab etc.). For Bitbucket you can:

Go to Your repository Settings > Under the section of the pipeline, click on Settings > Click on the Enable Pipelines Switch to enable pipelines.

We also need to set up a few repository variables that will be required to run the pipeline:

Go to Your repository Settings > Repository variables

And set these variables as key-pair values:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_DEFAULT_REGION

Okay, now we need to add a bitbucket-pipelines.yml file which will be required by Bitbucket to trigger the pipeline. We need to create that file and push it in our repository.

pipelines
 branches:
   deployment:
     - step:
       name: Build and package
         script:
           - apt-get install -y zip
           - npm install
           - mkdir artifacts
           - cp -r ./* ./artifacts
           - cd ./artifacts
           - zip -r code.zip index.js send-email.js node_modules/
           - cd ..
           - cp -r ./artifacts/code.zip ./
         artifacts:
           - code.zip
     - step:
       name: Update Lambda code
         script:
           - pipe: atlassian/aws-lambda-deploy:0.2.1
            variables:
             AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
             AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
             AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
             FUNCTION_NAME: ‘sendEmailFunction’
             COMMAND: ‘update’
             ZIP_FILE: ‘code.zip’
If you want to know more about these pipeline configuration, you can check out this page: https://support.atlassian.com/bitbucket-cloud/docs/configure-bitbucket-pipelinesyml/

We have set a trigger on the deployment branch. If we push any update in that branch we will be doing these two things here:

  • In step #1, we are building our application. In our case, we are resolving our npm packages. When our files are ready we are combining all these files in a compressed zip folder.
  • In step #2, we are deploying our code in lambda. In this step, pipeline will automatically authenticate by using those repository variables and upload our zipped code file to our function.

The branch name can be anything but make sure you mention that branch in bitbucket-pipelines.yml pipeline file.

Creating AWS Lambda Function

Now let’s create a lambda function. Log in to your AWS Management Console and search for Lambda. Open your Lambda dashboard and click “Create function“.

Let’s create our function sendEmailFunction from scratch, select runtime Node.js 16.x (or your preferred version) and hit “Create function“. Our function should be created and ready:

So, we are ready. Now, Let’s create a branch called “deployment” in our repository. After creating/pushing our code to deployment branch you will see that a pipeline has been started like this:

Click that running pipeline and you’ll get a view like this:

Done! Our code is successfully deployed to our sendEmailFunction. From now on, you don’t need to worry about deploying your code to Lambda function all on your own. All you have to do is to update your code and push it to your deployment branch. You can also maintain different environments with different respective branches.

SHARE ON SOCIAL MEDIA