Defining CDK constructs for application components – Programmatic Approach to IaC with AWS CDK

Note

The steps in this section have already been completed for you, inside the chapter-6/ directory, so you may just skim through them for your understanding.

In its current state, the project directory provides a bare-bones structure that does not deploy any resources as such. Let’s go ahead and add relevant construct definitions referenced in the workflow diagram. All the changes we will make here are supposed to be added to lib/chapter-6-stack. ts, which hosts our stack definition.

All stable constructs are currently mapped to the aws-cdk-lib module, which is version 2 of the AWS CDK library.

Note

Version 1 of the AWS CDK library reached end-of-support in June 2023. Given that there are a lot of resources on the internet that still refer to the v1 code, please exercise extra caution when using them.

For our requirements, we will add three AWS resource types – a Lambda function handler, an S3 bucket to host the images, and a DynamoDB table for persisting the results from Amazon Rekognition. Before we can use these constructs, we will have to import the respective libraries that expose the required TypeScript classes:

If you’ve worked with object-oriented programming languages in the past, the structure in this file might look similar. You’ll notice that CDK has added a class definition that extends cdk.Stack and exposes a constructor to initialize all the resources within this stack. We can extend this constructor definition to add constructs that we need:

The three objects that we initialize in the code will correspond to CloudFormation resources in the stack. We will see this in action soon after we synthesize our CDK stack.

Of course, there are a few other aspects of this solution that are still pending. As you might have noticed, we didn’t assign any permissions to our application orchestrator – the Lambda function. Furthermore, we need to add event notifications for the S3 bucket so that all subsequent image uploads are automatically sent to the Lambda image handler function:

This completes our constructdefinitions. Before we move ahead with synthesizing our template, let’s add the code for our Lambda function. The imageHandler construct definition has a mandatory argument called code:, where we define the location of our Lambda function code. The lambda. Code.fromAsset(‘resources/lambda’) value requires this function to be present in asubfolder called resources/lambda. So, let’s go ahead and create it.

Defining Lambda code for orchestrating the application workflow

Note

The steps in this section have already been completed for you, inside the chapter-6/ directory, so you may just skim through them for your understanding.

Let’s create a new file called image.py that will host our Python code for the Lambda function:

aws-devops-simplified:~/environment/chapter-6 $ mkdir -p resources/ lambda

aws-devops-simplified:~/environment/chapter-6 $ cd resources/lambda aws-devops-simplified:~/environment/chapter-6 $ touch image.py

If you remember the workflow diagram that we discussed a while back, the two main responsibilities of the Lambda image handler are as follows:

  • Extract the S3 bucket and key information from the event payload and pass it on to the Amazon Rekognition service
  • Persist the results of the image labeling process in the DynamoDB table

Before proceeding with the deployment, we can synthesize the CloudFormation template, which includes all the resources we defined previously. Template synthesis is an activity that should ideally be included in your CI/CD pipelines as a review/approval mechanism before any real changes are deployed in the cloud.

Leave a Comment