Cloud purposes are constructed utilizing a number of elements, reminiscent of digital servers, containers, serverless features, storage buckets, and databases. With the ability to provision and configure these sources in a secure, repeatable means is extremely essential to automate your processes and allow you to deal with the distinctive elements of your implementation.

With the AWS Cloud Development Kit, you possibly can leverage the expressive energy of your favourite programming languages to mannequin your purposes. You need to use high-level elements referred to as constructs, preconfigured with “sensible defaults” that you would be able to customise, to shortly construct a brand new utility. The CDK provisions your sources utilizing AWS CloudFormation to get all the advantages of managing your infrastructure as code. One of many causes I just like the CDK, is that you would be able to compose and share your individual customized elements as higher-level constructs.

As you possibly can think about, there are recurring patterns that may be helpful to multiple buyer. For that reason, at the moment we’re launching the AWS Solutions Constructs, an open supply extension library for the CDK that gives well-architected patterns that will help you construct your distinctive options. CDK constructs largely cowl single providers. AWS Options Constructs present multi-service patterns that mix two or extra CDK sources, and implement greatest practices reminiscent of logging and encryption.

Utilizing AWS Options Constructs
To see the ability of a pattern-based strategy, let’s check out how that works when constructing a brand new utility. For instance, I wish to construct an HTTP API to retailer information in a Amazon DynamoDB desk. To maintain the content material of the desk small, I can use DynamoDB Time to Live (TTL) to run out gadgets after just a few days. After the TTL expires, information is deleted from the desk and despatched, through DynamoDB Streams, to a AWS Lambda perform to archive the expired information on Amazon Simple Storage Service (S3).

To construct this utility, I can use just a few elements:

  • An Amazon API Gateway endpoint for the API.
  • A DynamoDB desk to retailer information.
  • A Lambda perform to course of the API requests, and retailer information within the DynamoDB desk.
  • DynamoDB Streams to capture data changes.
  • A Lambda perform processing information modifications to archive the expired information.

Can I make it less complicated? Wanting on the available patterns within the AWS Options Constructs, I discover two that may assist me construct my app:

  • aws-apigateway-lambda, a Assemble that implements an API Gateway REST API related to a Lambda perform. For instance of the “sensible defaults” utilized by AWS Options Constructs, this sample allows CloudWatch logging for the API Gateway.
  • aws-dynamodb-stream-lambda, a Assemble implementing a DynamoDB desk streaming information modifications to a Lambda perform with the least privileged permissions.

To construct the ultimate structure, I merely join these two Constructs collectively:

I’m utilizing TypeScript to outline the CDK stack, and Node.js for the Lambda features. Let’s begin with the CDK stack:

 

import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as apigw from '@aws-cdk/aws-apigateway';
import * as dynamodb from '@aws-cdk/aws-dynamodb';
import { ApiGatewayToLambda } from '@aws-solutions-constructs/aws-apigateway-lambda';
import { DynamoDBStreamToLambda } from '@aws-solutions-constructs/aws-dynamodb-stream-lambda';

export class DemoConstructsStack extends cdk.Stack {
  constructor(scope: cdk.Assemble, id: string, props?: cdk.StackProps) {
    tremendous(scope, id, props);

    const apiGatewayToLambda = new ApiGatewayToLambda(this, 'ApiGatewayToLambda', {
      deployLambda: true,
      lambdaFunctionProps: {
        code: lambda.Code.fromAsset('lambda'),
        runtime: lambda.Runtime.NODEJS_12_X,
        handler: 'restApi.handler'
      },
      apiGatewayProps: {
        defaultMethodOptions: {
          authorizationType: apigw.AuthorizationType.NONE
        }
      }
    });

    const dynamoDBStreamToLambda = new DynamoDBStreamToLambda(this, 'DynamoDBStreamToLambda', {
      deployLambda: true,
      lambdaFunctionProps: {
        code: lambda.Code.fromAsset('lambda'),
        runtime: lambda.Runtime.NODEJS_12_X,
        handler: 'processStream.handler'
      },
      dynamoTableProps: {
        tableName: 'my-table',
        partitionKey: { title: 'id', kind: dynamodb.AttributeType.STRING },
        timeToLiveAttribute: 'ttl'
      }
    });

    const apiFunction = apiGatewayToLambda.lambdaFunction;
    const dynamoTable = dynamoDBStreamToLambda.dynamoTable;

    dynamoTable.grantReadWriteData(apiFunction);
    apiFunction.addEnvironment('TABLE_NAME', dynamoTable.tableName);
  }
}

At first of the stack, I import the usual CDK constructs for the Lambda perform, the API Gateway endpoint, and the DynamoDB desk. Then, I add the 2 patterns from the AWS Options Constructs, ApiGatewayToLambda and DynamoDBStreamToLambda.

After declaring the 2 ApiGatewayToLambda and DynamoDBStreamToLambda constructs, I retailer the Lambda perform, created by the ApiGatewayToLambda constructs, and the DynamoDB desk, created by DynamoDBStreamToLambda, in two variables.

On the finish of the stack, I “connect” the 2 patterns collectively by granting permissions to the Lambda perform to learn/write within the DynamoDB desk, and add the title of the DynamoDB desk to the atmosphere of the Lambda perform, in order that it may be used within the perform code to retailer information within the desk.

The code of the 2 Lambda features is within the lambda folder of the CDK utility. I’m utilizing the Node.js 12 runtime.

The restApi.js perform implements the API and writes information to the DynamoDB desk. The URL path is used as partition key, all of the question string parameters within the URL are saved as attributes. The TTL for the merchandise is computed including a time window of seven days to the present time.

const { DynamoDB } = require("aws-sdk");

const docClient = new DynamoDB.DocumentClient();

const TABLE_NAME = course of.env.TABLE_NAME;
const TTL_WINDOW = 7 * 24 * 60 * 60; // 7 days expressed in seconds

exports.handler = async perform (occasion) {

  const merchandise = occasion.queryStringParameters;
  merchandise.id = occasion.pathParameters.proxy;

  const now = new Date(); 
  merchandise.ttl = Math.spherical(now.getTime() / 1000) + TTL_WINDOW;

  const response = await docClient.put({
    TableName: TABLE_NAME,
    Merchandise: merchandise
  }).promise();

  let statusCode = 204;
  
  if (response.err != null) {
    console.error('request: ', JSON.stringify(occasion, undefined, 2));
    console.error('error: ', response.err);
    statusCode = 500
  }

  return {
    statusCode: statusCode
  };
};

The processStream.js perform is processing information seize information from the DynamoDB Stream, looking for the items deleted by TTL. The archive performance shouldn’t be applied on this pattern code.

exports.handler = async perform (occasion) {
  occasion.Data.forEach((report) => {
    console.log('Stream report: ', JSON.stringify(report, null, 2));
    if (report.userIdentity.kind == "Service" &&
      report.userIdentity.principalId == "dynamodb.amazonaws.com") {

      // Document deleted by DynamoDB Time to Reside (TTL)
      
      // I can archive the report to S3, for instance utilizing Kinesis Information Firehose.
    }
  }
};

Let’s see if this works! First, I want to put in all dependencies. To simplify dependencies, every launch of AWS Options Constructs is linked to the corresponding model of the CDK. I this case, I’m utilizing model 1.46.Zero for each the CDK and the AWS Options Constructs patterns. The primary three instructions are putting in plain CDK constructs. The final two instructions are putting in the AWS Options Constructs patterns I’m utilizing for this utility.

npm set up @aws-cdk/aws-lambda@1.46.0
npm set up @aws-cdk/aws-apigateway@1.46.0
npm set up @aws-cdk/aws-dynamodb@1.46.0
npm set up @aws-solutions-constructs/aws-apigateway-lambda@1.46.0
npm set up @aws-solutions-constructs/aws-dynamodb-stream-lambda@1.46.0

Now, I construct the appliance and use the CDK to deploy the appliance.

In direction of the top of the output of the cdk deploy command, a inexperienced gentle is telling me that the deployment of the stack is accomplished. Simply subsequent, within the Outputs, I discover the endpoint of the API Gateway.

 ✅  DemoConstructsStack

Outputs:
DemoConstructsStack.ApiGatewayToLambdaLambdaRestApiEndpoint9800D4B5 = https://1a2c3c4d.execute-api.eu-west-1.amazonaws.com/prod/

I can now use curl to check the API:

curl "https://1a2c3c4d.execute-api.eu-west-1.amazonaws.com/prod/danilop?title=Danilo&firm=AWS"

Let’s take a look on the DynamoDB desk:

The merchandise is saved, and the TTL is about. After every week, the merchandise can be deleted and despatched through DynamoDB Streams to the processStream.js perform.

After I full my testing, I exploit the CDK once more to shortly delete all sources created for this utility:

Out there Now
The AWS Solutions Constructs can be found now for TypeScript and Python. The AWS Options Builders workforce is working to make these constructs additionally out there when utilizing Java and C# with the CDK, keep tuned. There is no such thing as a value in utilizing the AWS Options Constructs, or the CDK, you solely pay for the sources created when deploying the stack.

On this first launch, 25 patterns are included, masking a number of completely different use instances. Which new patterns and options ought to we focus now? Give use your suggestions within the open supply project repository!

Danilo





Leave a Reply

Your email address will not be published. Required fields are marked *