Build Serverless Applications using CDK and SAM

AWS recently announced the public preview of Serverless Application Model (SAM) support for CDK. SAM is an open-source framework that can be used to build, test and deploy serverless applications on AWS. It provides a Lambda-like execution environment …


This content originally appeared on DEV Community and was authored by Lorenz Vanthillo

AWS recently announced the public preview of Serverless Application Model (SAM) support for CDK. SAM is an open-source framework that can be used to build, test and deploy serverless applications on AWS. It provides a Lambda-like execution environment that lets you locally build, test, and debug applications. Previously this could only be defined by SAM templates but now it is also possible through the AWS Cloud Development Kit (CDK)!

alt text

I will guide you through a small demo project to demonstrate how to build a serverless application with AWS CDK and test it locally with AWS SAM.

We will build a simple REST API which shows the current bid or ask price of a certain cryptocurrency on Binance (exchange), expressed in the value of Bitcoin.

The API expects two query parameters:

  • coin: (ETH, DOG, LINK, DOT, ...)
  • price: (bid or ask)

Example of the API call:

$ curl "http://127.0.0.1:3000/crypto?type=ask&coin=ETH"
{"coin": "ETH", "price": 0.066225}

The setup in AWS will also be pretty straight forward.
We will set up a Lambda proxy integration in API Gateway

alt text

To get started, we need to install the AWS CDK CLI and create a new CDK project. I use Python as client language.

$ npm install -g aws-cdk
$ cdk init app --language python

The project structure looks like this:

.
├── README.md
├── app.py
├── cdk.json
├── requirements.txt
├── sam_cdk_demo
│   ├── __init__.py
│   └── sam_cdk_demo_stack.py
└── setup.py

The file sam_cdk_demo/sam_cdk_demo_stack.py should contain our code to define the AWS cloud resources we need but first let's start with writing our Lambda.

Create a folder inside the root of the project called "lambda" and add a handler.py. The ccxt library is used by our Lambda to interact with the Binance API. The Lambda itself is very basic on purpose.

import ccxt
import json


# use CCXT library to connect with Binance API
exchange = getattr(ccxt, 'binance')({
    'timeout': 3000,
    'enableRateLimit': True
})

def get_current_price(coin_name, price_type):
    # fetch latest ticker data for coin pair xxx/BTC
    ticker = exchange.fetch_ticker('{}/BTC'.format(coin_name))
    # get ask/bid price from ticket data
    current_price = ticker[price_type]
    return current_price

def lambda_handler(event, context):
    # get values from query string parameters
    coin = event['queryStringParameters']['coin']
    price = event['queryStringParameters']['type']

    # CCXT exchange expects coin in uppercase
    valid_coin = coin.upper()

    # get current price based on coin name and price type (ask/bid)
    current_price = get_current_price(valid_coin, price)

    return {
        'statusCode': 200,
        'headers': { 
            'Content-Type': 'application/json'
        },
        'body': json.dumps({
            'coin': valid_coin,
            'price': current_price,
        })
    }

Don't forget to add a requirements.txt inside the folder to make the ccxt library available to the Lambda.

ccxt==1.50.13

The Lambda is ready! Now we will use AWS CDK to define our AWS infrastructure. We need to deploy the Lambda and create an API Gateway in front of it. Update the file demo/demo_stack.py. We keep the code pretty basic again.

from aws_cdk import (
    aws_lambda as _lambda,
    aws_apigateway as apigw,
    core,
)

class CdkLambdaSamStack(core.Stack):

    def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # creating Lambda function that will be triggered by the API Gateway
        get_price_handler = _lambda.Function(self,'CryptoFunction',
            handler='handler.lambda_handler',
            runtime=_lambda.Runtime.PYTHON_3_8,
            code=_lambda.Code.asset('lambda'),
            timeout=core.Duration.seconds(30),
        )

        # create REST API
        api = apigw.RestApi(self, 'crypto-api')

        # add resource /crypto
        resource = api.root.add_resource('crypto')

        # create Lambda integration 
        get_crypto_integration = apigw.LambdaIntegration(get_price_handler)

        # add method which requires two query string parameteres (coin and type)    
        resource.add_method(
            http_method='GET',
            integration=get_crypto_integration,
            request_parameters={
                'method.request.querystring.coin': True,
                'method.request.querystring.type': True
            },
            request_validator_options=apigw.RequestValidatorOptions(validate_request_parameters=True)
        )

Update the requirements.txt in the project root with the necessary modules.

aws-cdk.core
aws-cdk.aws_lambda
aws-cdk.aws_apigateway

Start the Python virtual environment which is created by CDK and install the modules.

$ source .venv/bin/activate
(.venv)$ pip3 install -r requirements.txt

We will use AWS SAM to test our setup locally. It's important to mention that you need to have Docker installed. We will use Docker to build our code. The Lambda will also run inside as a Lambda-like Docker container.

Prepare the deployment artifact.

(.venv)$ sam-beta-cdk build --use-container

Start the local API Gateway.

$ sam-beta-cdk local start-api
...
* Running on http://127.0.0.1:3000/

We can use a tool like Postman (or curl or just your browser) to perform calls against our API.

alt text

It takes a few seconds to execute the function because AWS SAM is spinning up a Docker container to execute our code. After the execution the container is destroyed.

When everything looks fine we can deploy it to AWS.

(.venv)$ cdk bootstrap
(.venv)$ cdk deploy -a .aws-sam/build

Now test against the deployed API.
alt text

alt text

We were able to test our API and Lambda using the new Serverless Application Model integration with CDK! You can find all code on my GitHub. Be aware that this feature is in preview. Feel free to do more extensive testing. You can report bugs and submit feature requests to the SAM opensource repository.


This content originally appeared on DEV Community and was authored by Lorenz Vanthillo


Print Share Comment Cite Upload Translate Updates
APA

Lorenz Vanthillo | Sciencx (2021-05-21T15:56:56+00:00) Build Serverless Applications using CDK and SAM. Retrieved from https://www.scien.cx/2021/05/21/build-serverless-applications-using-cdk-and-sam/

MLA
" » Build Serverless Applications using CDK and SAM." Lorenz Vanthillo | Sciencx - Friday May 21, 2021, https://www.scien.cx/2021/05/21/build-serverless-applications-using-cdk-and-sam/
HARVARD
Lorenz Vanthillo | Sciencx Friday May 21, 2021 » Build Serverless Applications using CDK and SAM., viewed ,<https://www.scien.cx/2021/05/21/build-serverless-applications-using-cdk-and-sam/>
VANCOUVER
Lorenz Vanthillo | Sciencx - » Build Serverless Applications using CDK and SAM. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/05/21/build-serverless-applications-using-cdk-and-sam/
CHICAGO
" » Build Serverless Applications using CDK and SAM." Lorenz Vanthillo | Sciencx - Accessed . https://www.scien.cx/2021/05/21/build-serverless-applications-using-cdk-and-sam/
IEEE
" » Build Serverless Applications using CDK and SAM." Lorenz Vanthillo | Sciencx [Online]. Available: https://www.scien.cx/2021/05/21/build-serverless-applications-using-cdk-and-sam/. [Accessed: ]
rf:citation
» Build Serverless Applications using CDK and SAM | Lorenz Vanthillo | Sciencx | https://www.scien.cx/2021/05/21/build-serverless-applications-using-cdk-and-sam/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.