Building Serverless Services with AWS CDK
Create serverless services in a reliable and reproducible manner using AWS CDK and Python.

Serverless computing alleviates operational overhead for developers by allowing cloud providers to handle infrastructure management tasks such as capacity provisioning. Developers can focus on their requirements and business goals, while only paying for the compute resources they use.
AWS Lambda and AWS Fargate are prime examples of serverless services with features like automatic scaling, built-in high availability, and a pay-for-value billing model. These services increase agility, reduce cost, and time to market for the solutions we create.
An efficient way to build and deploy serverless services is through Infrastructure as Code (IaC). IaC can be defined as the process of provisioning and managing your cloud resources programmatically. AWS CloudFormation is a perfect example of tools that enable users to provision resources through IaC.
In this article, we are going to explore how to build and deploy serverless services on AWS using infrastructure as code. We will deploy services such as: AWS API Gateway, AWS Lambda, and AWS Fargate. To deliver infrastructure as code through CloudFormation, we will be using the AWS Cloud Development Kit (AWS CDK) as our framework.
AWS CDK
In simple terms, AWS CDK is a software development framework to define your cloud application resources using familiar programming languages. It provides high-level components called constructs that preconfigure cloud resources with proven defaults. Enabling the provision of resources in a safe, reproducible way through AWS CloudFormation.
A concept such as reproducibility is important. Reproducibility can be described as “the extent to which consistent results are obtained when an experiment is repeated”.
AWS CDK enables reproducibility of infrastructure and services, providing developers with the ability to easily encapsulate and share best practices in infrastructure definition along with their solutions.
AWS Services

A description of each AWS cloud resource used during this article can be found below:
AWS API Gateway: a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale.
AWS Lambda: a serverless compute service that lets you run code without provisioning or managing servers, creating workload-aware cluster scaling logic, maintaining event integrations, or managing runtimes.
AWS Elastic Container Service (ECS): a fully managed container orchestration service.
AWS Elastic Container Registry (ECR): a fully managed container registry that makes it easy to store, manage, share, and deploy your container images and artifacts anywhere.
Amazon CloudWatch: a monitoring service that collects operational data in the form of logs, metrics, and events, providing you with a unified view of AWS resources.
Prerequisites
Important: This article will not go through the details of configuring AWS accounts or installing the necessary software applications to enable running AWS CDK. Please refer to AWS CDK Prerequisites for all necessary steps before using AWS CDK.
To work with the AWS CDK, you must have an AWS account and credentials. Additionally, you need to install Node.js and the AWS CDK Toolkit.
Python AWS CDK applications require Python 3.6 or later. If you don’t already have it installed, download a compatible version.
The Python package installer, pip, and virtual environment manager, virtualenv, are also required.
Constructs

A construct represents a “cloud component” and encapsulates everything AWS CloudFormation needs to create the component.
AWS CDK creates resources using Constructs. As stated on the AWS website, they are the basic building blocks of AWS CDK apps. A construct represents a “cloud component” and encapsulates everything AWS CloudFormation needs to create the component.
A construct can represent a single resource, such as AWS Lambda function, or it can represent a higher-level component consisting of multiple AWS resources.
Apps and Stacks
A CDK application is commonly called an app, which is represented by the AWS CDK class App. For our CDK application, we will use an example of a data product being delivered using AWS Services. Let’s start by creating our folder structure. Create a directory called “dataproduct”.
mkdir dataproduct
We will use this folder as our main directory:
cd dataproductImportant: Please keep in mind that you need an empty directory in order to initialize AWS CDK.
Now initialize the project using the “cdk init” command, specifying the desired template (“app”) and programming language.
cdk init app --language pythonThe previous command generates several files and folders inside the dataproduct directory to help you organize the source code for your AWS CDK application.
After initializing the project, activate the project’s virtual environment. This allows the project’s dependencies to be installed locally in the project folder, instead of globally.
source .venv/bin/activateInstall the app’s standard dependencies:
python -m pip install -r requirements.txtWe can verify there are no issues by listing the stacks in our app with the command below:
cdk lsYou should be able to see on the screen the current stack called dataproduct.
A stack defines a unit of deployment in AWS CDK. As you will see in this article, you can incorporate many resources within a stack and they will be provisioned as a single unit.
Manage AWS Construct Library modules
With CDK, we can use the Python package installer (pip) to install and update AWS Construct Library modules. AWS Construct Library modules are named aws-cdk.SERVICE-NAME.
We will be working with API gateway, Lambda, ECR, and ECS. Let’s proceed to install these libraries using pip:
python -m pip install aws-cdk.aws-lambda aws-cdk.aws-iam aws-cdk.aws-ecr aws-cdk.aws-ecs aws-cdk.aws-apigateway Exploring the App
Before creating our stack, we should take a look at some components currently present in our application, such as the App Construct.
The App Construct is used to define a stack within the scope of an application. It's the only construct that can be used as a root for the construct tree.
This construct has been initially created for us when we first executed cdk init and it can be found in the app.py file of the project.
from aws_cdk import core
from dataproduct.dataproduct_stack import DataproductStack
app = core.App()
DataproductStack(app, "dataproduct")
app.synth()To successfully create some of the components needed in our stack, it is necessary to include an environment. As stated by AWS, an environment is the target AWS account and region into which the stack is intended to be deployed.
Each stack is explicitly or implicitly associated with an AWS account and region.
env = core.Environment(account="yourawsaccount", region="yourawsregion")Once created, the environment can be provided to the stack.
DataproductStack(app, "dataproduct", env=env)After the recent changes, the content of dataproduct/app.py file should like the code below:
Important: Provide your own AWS account and region.
from aws_cdk import core
from dataproduct.dataproduct_stack import DataproductStack
app = core.App()env = core.Environment(account="yourawsaccount", region="yourawsregion")
DataproductStack(app, "dataproduct", env=env)
app.synth()Creating additional directories
We will need 2 additional directories to be created under the dataproduct folder: function and product.
· The function directory will contain the Lambda code.
· The product directory will contain our Dockerfile for the data product.
Let’s create both of them under the main dataproduct directory.
mkdir function productLambda Function Code
Create a python file dataproduct-lambda.py under the function directory and include the code below.



