Deploy Automatically to AWS Lambda via Bitbucket Pipelines

[vc_row][vc_column][vc_column_text]

Bitbucket’s Pipelines feature allows you to configure continuous integration and continuous deployment (CI/CD) directly within Bitbucket, without an external CI/CD server such as Jenkins.

In this article, we’ll walk through configuring Bitbucket Pipelines to deploy AWS Lambda functions automatically.

We’ll create a new AWS Lambda function, create a new Bitbucket repository to hold our Lambda source code, and perform all necessary configuration in AWS and Bitbucket to facilitate automatic deployments.

When complete, after pushing changes to your AWS Lambda function to Bitbucket, they will automatically be deployed to AWS.

Prerequisites

This walkthrough assumes that you have an AWS account, as well as a general familiarity with Git and AWS Lambda.

The walkthrough also includes the initial creation of the AWS Lambda function and the corresponding Bitbucket repository. If you are working with an existing Lambda and/or repo, you may be able to skip some steps below.

Create AWS Lambda Function

Login to the AWS Console, navigate to the Lambda section and click Create Function.

On the resulting Create Function page, select Author From Scratch and supply the following values:

  • Name: PipelineTest
  • Runtime: Node.js 6.10
  • Role: Create new role from template(s)
  • Role name: PipelineTestRole
  • Policy templates: Can be left blank

Create AWS IAM User

We need to create an IAM user with permissions to create/update AWS Lambda functions.

    • 1. Navigate to the AWS IAM page, then navigate to Users and then Add User.
    • 2. Supply a username and select Programmatic Access for the access type, then click Next.
    • 3. On the permissions page, select Attach Existing Policies Directly and then select appropriate permissions for your user, then click Review. Note: For this demo, I used the AWSLambdaFullAccess policy, but you may want to consider different policies. As always, use caution when dealing with AWS security.
    • 4. Review the user details and then click Create User.
  • 5. On the resulting page, note the Access Key ID and Secret Access Key, as they will be needed in a following step.

 

Create Bitbucket Repository

Next, we’ll create a Bitbucket repository to store our Lambda source code as well as our deployment configuration.

To create the repository, login to your Bitbucket account and click New -> Repository in the left sidebar. Create a new repository with a name of your choice (the other default values should be fine) and then click Create Repository.

Add Files to Repository

You’ll need to clone your repository locally and add the following 3 files to the root of your repository.

exports.handler = (event, context, callback) => {
    // TODO implement
    callback(null, 'Hello from Lambda');
};

This is the Javascript file for your Lambda function. This can be downloaded or copy/pasted from the Lambda function created earlier.

AWS_ENVIRONMENT=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_PROFILE=
AWS_SESSION_TOKEN=
AWS_ROLE_ARN=
AWS_REGION=
AWS_FUNCTION_NAME=
AWS_HANDLER=index.handler
AWS_MEMORY_SIZE=128
AWS_TIMEOUT=3
AWS_DESCRIPTION=
AWS_RUNTIME=nodejs6.10
AWS_VPC_SUBNETS=
AWS_VPC_SECURITY_GROUPS=
AWS_TRACING_CONFIG=
AWS_LOGS_RETENTION_IN_DAYS=
EXCLUDE_GLOBS=
PACKAGE_DIRECTORY=build

This file is used by the node-lambda utility to load some values. Most values will be supplied directly to node-lambda via CLI flags at runtime, but this file is still required.

image: lambci/lambda:build-nodejs6.10
pipelines:
  default:
    - step:
        deployment: production
        script:
          - npm install
          - npm install node-lambda -g
          - node-lambda deploy -a $AWS_ACCESS_KEY -s $AWS_SECRET_KEY -o $AWS_ROLE -r $AWS_REGION -n $AWS_LAMBDA_FUNCTION_NAME --excludeGlobs "bitbucket-pipelines.yml"
        caches:
          - node

This specifies the steps required to deploy our Lambda function to AWS. (Note that this is a very basic pipeline; more information on configuring Bitbucket Pipelines is available.)

Once you’ve created these three files locally, commit and push to Bitbucket.

Setup Pipeline Environment Variables

In the bitbucket-pipelines.yml file above, you can see that several arguments to our node-lambda deployment utility are being supplied via environment variable. We can configure these via Bitbucket so that we don’t need to keep these configuration values in our code.

First, navigate to Settings -> Pipelines -> Settings and enable Pipelines.

Next, navigate to Settings -> Pipelines -> Environment Variables. From here, we need to add the following five settings. For the AWS keys, be sure to click the lock icon to mark them as secure, so they are masked when displayed.

  • AWS_ACCESS_KEY: For the IAM user created above.
  • AWS_SECRET_KEY: For the IAM user created above.
  • AWS_ROLE: The ARN for the role created above. This can be located in AWS by navigating to IAM -> Roles, selecting the newly created role, and copying the role ARN.
  • AWS_REGION: The name of the region where you created the Lambda.
  • AWS_LAMBDA_FUNCTION_NAME: The name of the Lambda.

Test

Our pipeline configuration should now be set up to deploy our Lambda to AWS on every commit. To test it, let’s modify our index.js file locally to change the log message, and then commit and push to Bitbucket.

This should automatically kick off our Bitbucket Pipeline, which deploys our project to AWS.

Once this changes from In Progress to Successful, go back to the AWS Console and navigate to your Lambda function, where your changes should now be all set.

Future Work

Now that you’ve created a working example of a basic Bitbucket Pipeline to automatically deploy your AWS Lambda function, here are some possible next steps for further development.

  • – Explore further configuration of Bitbucket Pipelines to create more intricate workflows
  • – Use Bitbucket’s new Deployments feature to enable multiple environments for your project
  • – Use node-lambda to perform local testing of your Lambda function
References/Credits

[/vc_column_text][/vc_column][/vc_row]