An Example of Simplifying Local Resource Deployment with AWS CDK and LocalStack

An Example of Simplifying Local Resource Deployment with AWS CDK and LocalStack

Hello everyone, this is Edelweis from the Systems Department.
It has been more than six months since I moved from the Philippines to Japan to join GMO Research. The past six months have been very productive as it helped me improve my technical and even a little bit of Japanese skills.

In the past, I have worked with infrastructure creation and maintenance. It has always been my top priority to make deployment and maintenance as easy as possible. I also want other people to get to know the importance of understanding the infrastructure of a project.

From this, I came across AWS Cloud Development Kit (CDK) and Localstack. AWS CDK works like AWS CloudFormation template, but it does not necessarily need for user to remember complex functions or templates of CloudFormation. This makes management easier. Moreover, if the user has a clear knowledge of a specific programming language it would be easy to deploy resources.

You may refer to AWS CDK and Localstack official page for details of these tools. In this article, I will show how I installed and used the tools.

Using Localstack and AWS CDK I was able to deploy an API which I can use for study or investigation. Below are the steps I took to successfully do this.

Basic Design/Architecture

The design for this report is very simple and straightforward. We will only use API Gateway and Lambda to create a sample REST API.

Environment Construction (Windows)

Localstack

1.     Install localstack using python

python -m pip install localstack

2.     Start localstack

localstack start

3.     Check localstack status

localstack status services

Successful installation and start of localstack will result to the following:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Service                  ┃ Status      ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│ acm                      │ ✔ available │
│ apigateway               │ ✔ available │
│ cloudformation           │ ✔ available │
│ cloudwatch               │ ✔ available │
│ config                   │ ✔ available │
│ dynamodb                 │ ✔ available │
│ dynamodbstreams          │ ✔ available │
│ ec2                      │ ✔ available │
│ es                       │ ✔ available │
│ events                   │ ✔ available │
│ firehose                 │ ✔ available │
│ iam                      │ ✔ available │
│ kinesis                  │ ✔ available │
│ kms                      │ ✔ available │
│ lambda                   │ ✔ available │
│ logs                     │ ✔ available │
│ opensearch               │ ✔ available │
│ redshift                 │ ✔ available │
│ resource-groups          │ ✔ available │
│ resourcegroupstaggingapi │ ✔ available │
│ route53                  │ ✔ available │
│ route53resolver          │ ✔ available │
│ s3                       │ ✔ available │
│ s3control                │ ✔ available │
│ scheduler                │ ✔ available │
│ secretsmanager           │ ✔ available │
│ ses                      │ ✔ available │
│ sns                      │ ✔ available │
│ sqs                      │ ✔ available │
│ sqs-query                │ ✔ available │
│ ssm                      │ ✔ available │
│ stepfunctions            │ ✔ available │
│ sts                      │ ✔ available │
│ support                  │ ✔ available │
│ swf                      │ ✔ available │
│ transcribe               │ ✔ available │
└──────────────────────────┴─────────────┘

AWS CDK

To install and use AWS CDK all we need is to create a new and empty directory and execute the cdk commands.

1.     Create new and empty directory

mkdir cdk-techblog
cd cdk-techblog

2.     Install cdk

npm install -g aws-cdk-local aws-cdk

3.     Initialize cdklocak

cdklocal init --language python

For this article, I used python as my programming language. AWS CDK also supports programming languages like Typescript, Javascript, Java, C#, and Go. This also makes this tool very easy to use for everyone.
The command cdklocal init will initialize the directory where we can start creating our resources.
We will edit one file and create a new file in order to create resources.

Creating AWS Resources (Lambda and API Gateway)

Create the lambda code

Create a new directory and new file for the lambda handler.
For this project, we will deploy a very simple lambda which returns “Hello World!” every time it is executed.

File: src/lamba_handler.py

def handler(event, context):
    response = {
        'statusCode': 200,
        'body': "Hello World!",
        'headers': {
            'Content-Type': 'application/json'
        }
    }
    return response

Update the stack to create the lambda function and integrate the lambda function with the API Gateway.

File: cdk_techblog/cdk_techblog_stack.py

from aws_cdk import (
    aws_lambda as _lambda,
    aws_apigateway as apigw,
    Stack,
)
from constructs import Construct
 
class CdkTechblogStack(Stack):
 
   def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
 
        lambda_func = _lambda.Function(
            self,
            'HelloWorldLambda',
            handler='lambda_handler.handler',
            runtime=_lambda.Runtime.PYTHON_3_7,
            code=_lambda.Code.from_asset('src')
        )
 
        api = apigw.RestApi(self, "HelloWorldApi")
        api_gw_resource = api.root.add_resource("test")
        api_gw_integration = apigw.LambdaIntegration(lambda_func)
        api_gw_resource.add_method("GET", api_gw_integration)

In the above code, we want to create a lambda function in Python named 'HelloWorldLambda' and an API Gateway RestAPI named  HelloWorldApi. The API Gateway also has a resource named test.

Once the code for the resources is completed, we are ready to deploy.

Deploying Resources to Localstack

 1.     Run cdk bootstrap

cdklocal bootstrap

This command will create an AWS S3 Bucket which AWS CDK will use to deploy the stack. This command is done only once or first time deployment.
To verify that the bucket is successfully created, run the following localstack to check.

aws s3 ls --endpoint-url=http://localhost:4566

This should output the S3 Bucket created like

2023-11-13 20:40:12 cdk-hnb659fds-assets-000000000000-ap-northeast-1

2.     Deploy Command

cdklocal deploy 

Successful deployment will show the stacks created as well as confirmation that deployment was successful.

✅  CdkTechblogStack
✨  Deployment time: 10.39s
Outputs:
CdkTechblogStack.HelloWorldApiEndpointAD496187 = https://7u9zuost7i.execute-api.localhost.localstack.cloud:4566/prod/
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:000000000000:stack/CdkTechblogStack/9e5b2cf2

That’s it. Using just a few commands, we were able to deploy our AWS Resources in Localstack. However, we still want to check whether the resources work like how we want them to be. So let’s test it.

Testing of Deployed Resources

In order to verify that the resources are deployed. We will use the curl command.

curl http://localhost:4566/restapis/<rest_api_id>/<stage_name>/_user_request_/<resource_name>

Using the aws cli we will get the values in order to complete the URL.

1.     <rest_api_id>

aws apigateway get-rest-apis --endpoint-url=http://localhost:4566
$ aws apigateway get-rest-apis --endpoint-url=http://localhost:4566
{
    "items": [
        {
            "id": "7u9zuost7i",
            "name": "HelloWorldApi",
            "createdDate": "2023-11-13T20:45:01+09:00",
            "apiKeySource": "HEADER",
            "endpointConfiguration": {
                "types": [
                    "EDGE"
                ]
            },
            "tags": {
                "aws:cloudformation:logical-id": "HelloWorldApi9E278160",
                "aws:cloudformation:stack-name": "CdkTechblogStack",
                "aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:000000000000:stack/CdkTechblogStack/9e5b2cf2"
            },
            "disableExecuteApiEndpoint": false
        }
    ]
}

From the output above, we can retrieve

  "id": "7u9zuost7i",

This value will then be used in succeeding commands.

2.     <stage_name>

aws apigateway get-stages --rest-api-id 7u9zuost7i --endpoint-url=http://localhost:4566
{
    "item": [
        {
            "deploymentId": "snr2rt92wl",
            "stageName": "prod",
            "cacheClusterEnabled": false,
            "cacheClusterStatus": "NOT_AVAILABLE",
            "methodSettings": {},
            "tracingEnabled": false
        }
    ]
}

From output above we can use

"stageName": "prod",

3.     <resource_name>

aws apigateway get-resources --rest-api-id 7u9zuost7i --endpoint-url=http://localhost:4566
{
    "items": [
        {
            "id": "3fihy4az23",
            "path": "/"
        },
        {
            "id": "thhe71dqtz",
            "parentId": "3fihy4az23",
            "pathPart": "test",
            "path": "/test",
            "resourceMethods": {
                "GET": {
                    "httpMethod": "GET",
                    "authorizationType": "NONE",
                    "apiKeyRequired": false,
                    "requestParameters": {},
                    "requestModels": {},
                    "methodResponses": {},
                    "methodIntegration": {
                        "type": "AWS_PROXY",
                        "httpMethod": "POST",
                        "uri": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:000000000000:function:CdkTechblogStack-HelloWorldLambda5A02458E-770e5667/invocations",
                        "requestParameters": {},
                        "requestTemplates": {},
                        "passthroughBehavior": "WHEN_NO_MATCH",
                        "timeoutInMillis": 29000,
                        "cacheNamespace": "thhe71dqtz",
                        "cacheKeyParameters": []
                    }
                }
            }
        }
    ]
}

From output above we can use

       "pathPart": "test",

Now that we have all the values to complete the URL. We will execute the curl command.

curl http://localhost:4566/restapis/7u9zuost7i/prod/_user_request_/test 

Successful response displays “Hello World” on the screen.

curl http://localhost:4566/restapis/7u9zuost7i/prod/_user_request_/test
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    12  100    12    0     0    139      0 --:--:-- --:--:-- --:--:--   139
Hello World!

That’s it! We were able to confirm that the resources are deployed and connected.

Conclusion

With the increased demand for cloud technologies nowadays it is ideal for us developers to understand how we can use, deploy, and maintain infrastructure. In this article, I showed how to use two of the easiest and well-known tools for deployment that are AWS CDK and Localstack. From this, we can explore more of the advanced and new tools that are coming out. With the help of these simple tools I hope everyone can have a wider understanding of how important knowledge of infrastructure is for a project.

That is all, thank you! 😀

【References】

  1. What is the AWS CDK?
  2. localstack.cloud
  3. apigatewayーAWS CLI Command Reference
前の記事
«
次の記事
»

技術カテゴリの最新記事