DEV Community

loading...
Cover image for Localstack + CDK = local AWS development

Localstack + CDK = local AWS development

_mikigraf profile image Miki Graf ・3 min read
Github: https://github.com/mikigraf/CDK-with-Localstack

Motivation

During the development cycle a deployment to the cloud is one of the most time consuming tasks, that the developer has no control over - besides making sure that the template will actually deploy. Once the resources get pushed into the cloud there is not much that can be done and the time gets probably wasted.

There’s also another aspect that gets forgotten when developing for the cloud - there are still areas where internet connection is bad or non-existent at all. So if one decides to live a van life, but still wants to work on a cloud-based project - she’s still able to.

Localstack provides a lower barrier of entry for AWS. It addresses some concerns, that developers may have at first. They often hear horror stories about huge bills and hacked accounts.

Setup

Before we begin there are three things we need to have installed:

There's also AWS CLI, which is required for interacting with the infrastructure. It's actually possible to specify the endpoint URL, so instead of sending the requests to the cloud directly, we will send them to Localstack.
aws --endpoint-url=http://localhost:4566 apigateway get-rest-apis

Project: Api Gateway + Lambda as CDK Template

Project initialization and dependencies

cdk init --language=typescript
Enter fullscreen mode Exit fullscreen mode

Add dependencies to cdk/package.json:

  "dependencies": {
    "aws-cdk": "1.72.0",
    "@aws-cdk/aws-apigateway": "1.72.0",
    "@aws-cdk/aws-lambda": "1.72.0",
    "@aws-cdk/core": "1.72.0",
  }
Enter fullscreen mode Exit fullscreen mode

it’s important to keep the versions of libraries related to CDK on the same version! And Install dependencies:
npm install --save

CDK Template

In the constructor of your stack (for me in cdk/lib/cdk-stack.ts) add:

import * as cdk from '@aws-cdk/core';
import { LambdaIntegration, RestApi} from "@aws-cdk/aws-apigateway";
import {Function, Code, Runtime} from "@aws-cdk/aws-lambda";
import {CfnOutput} from "@aws-cdk/core";

export class CdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const helloWorldLambda = new Function(this, 'helloWorldLambda', {
      runtime: Runtime.NODEJS_12_X,
      code: Code.fromAsset('lib/helloWorldLambda'),
      handler: 'index.handler',
    });

    const api = new RestApi(this, 'myapi', {});
    const helloWorldLambdaIntegration = new LambdaIntegration(helloWorldLambda);
    const helloResource = api.root.addResource('hello')
    helloResource.addMethod("GET", helloWorldLambdaIntegration)
    new CfnOutput(this, "Endpoint", { value: `http://localhost:4566/restapis/${api.restApiId}/prod/_user_request_${helloResource.path}` })
  }
}
Enter fullscreen mode Exit fullscreen mode

We created REST API and added the newly created helloWorldLambda function to it by creating an integration on the resource (path) ‘hello’ with HTTP method GET.
CfnOutput is just a construct, that will output the url of the API.
It’s important to note, that the URL of the API in Localstack differs from the URL of the API in AWS. The Url, that will be outputed to the console by CDK is wrong.

Lambda function

Create new directory for the lambda lib/helloWorldLambda, add index.ts and paste the following:

export const handler: any = async (
  event: any,
  context: any,
  callback: any
): Promise<any> => {
    return {
        statusCode: 200,
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
        body: JSON.stringify("Hello World :)!"),
    };
};
Enter fullscreen mode Exit fullscreen mode

Running

cdk synth
Enter fullscreen mode Exit fullscreen mode

should yield no errors now.

Deploying CDK to Localstack

Head to the terminal and write:

docker-compose up
Enter fullscreen mode Exit fullscreen mode

and wait for the message in the terminal, that will just say:

Ready.
Enter fullscreen mode Exit fullscreen mode

In another terminal window bootstrap the CDK env:

cdklocal bootstrap
Enter fullscreen mode Exit fullscreen mode

and then deploy to it:

cdklocal deploy
Enter fullscreen mode Exit fullscreen mode

The output after the deployment will include something like this:

Outputs:
CdkStack.myapiEndpoint8EB17201 = https://eyjiyd1la4.execute-api.eu-central-1.amazonaws.com/prod/
Enter fullscreen mode Exit fullscreen mode

Usually it would be the correct url to the api, but since we’re deploying to Localstack, we need to get the other output, that we defined.

Use curl to see if everything has worked fine:

curl <the url from the output with /hello at the end of the path
Enter fullscreen mode Exit fullscreen mode

Conclusion

Localstack provides a low barrier of entry for developers not comfortable with direct deployments into the cloud. In my opinion it’s a great tool for creating tests, but also for introducing developers to new AWS services.

Discussion (0)

pic
Editor guide