AWS CDKとPythonでサーバーレスAPIを作成してみた。

2022.02.07

AWS CDKとは?

AWS Cloud Development Kit (CDK)は、コードでクラウドインフラストラクチャを定義し、AWSCloudFormationを介してプロビジョニングするためのフレームワークです。AWS CDKを使用してプログラミング言語でクラウドにアプリケーションを構築することができます。

AWSCDKでサポートされているプログラミング言語 : TypeScript, JavaScript, Python, Java, C#/.Net, and Go。

この記事では、AWS CDKとPythonを使用してDynamoDBでAPIを作成してみました。

 

 

やってみた

CDKをインストールする

  • 次のコマンドを使用してCDKをインストールしておきます。
  • AWS CDKにはCDKツールキットとAWS Construct Libraryが含まれています。メインのCDKパッケージは aws-cdk-lib です
python -m pip install aws-cdk-lib

 

CDKアプリの作成

  • 新しいディレクトリを作成しておきます。
  • CDKは、プロジェクトディレクトリの名前に基づいてソースファイルとクラスに名前を付けます。
#create new directory
mkdir api
cd api

 

  • cdk initコマンドを使用してアプリを初期化しておきます。
cdk init --language python

 

  • 次の2つのコマンドを実行して、アプリのPython virtual environmentをアクティブ化し、CDK core dependenciesをインストールしておきます。
source .venv/bin/activate
pip install -r requirements.txt

 

Lambda関数の作成

  • プロジェクトのメインディレクトリにresourcesディレクトリを作成しておきます。
mkdir resources

 

  • resourcesディレクトリに次のPythonファイルを作成しておきます。[resources/lambda_handler]
  • 以下のコードは、DynamoDBテーブルのすべての項目を一覧表示します。

 

import json
import os
import boto3
from botocore.exceptions import ClientError

dynamodb = boto3.resource('dynamodb')
TABLE_NAME = os.environ['TABLE_NAME']

def handler(event, context):
    table = dynamodb.Table(TABLE_NAME)
    statusCode = 200
    try:
        result = table.scan()
        body = json.dumps(result)
    except ClientError as e:
        statusCode = 400
        body = str(e)
    response = {
        'statusCode': statusCode,
        'body': body,
        'headers': {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin': '*'
             }
    }
    return response

 

サービスの作成

  • 新しいファイル [app/aws_services.py] を作成して、作成する必要のあるAWSサービスを定義しておきます。

 

import os
import aws_cdk as cdk
from constructs import Construct
from aws_cdk import (
    App, Stack,
    aws_lambda as _lambda,
    aws_apigateway as apigateway,
    aws_dynamodb as dynamodb
)
from aws_cdk.aws_apigateway import (
    RestApi,
    LambdaIntegration
) 

class AWSService(Construct):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

         # create dynamo table
        table = dynamodb.Table(
            self, "usertable",
            table_name= 'Users',
            partition_key=dynamodb.Attribute(
                name="id",
                type=dynamodb.AttributeType.STRING
            )
        )

        #create Lambda Function
        getAllLambda = _lambda.Function(self, 'ApiLambda',
            handler='lambda_handler.handler',
            function_name='usersFunction',
            runtime=_lambda.Runtime.PYTHON_3_7,
            code=_lambda.Code.from_asset('resources'))

        getAllLambda.add_environment("TABLE_NAME", table.table_name)
        
        #Grant Permission to Lambda function
        table.grant_read_write_data(getAllLambda)

        #create API Gateway
        api = apigateway.RestApi(self, "users-api")
        
        users = api.root.add_resource("users")
        get_users_integration = apigateway.LambdaIntegration(getAllLambda)
        users.add_method("GET", get_users_integration)

 

  • 上記のコードは、次のAWSサービスを作成します:
    • DynamoDBテーブル  :   パーティションキーを持つDynamoDBテーブル。
    • Lambda関数 : 環境変数とPythonランタイムを備えたLambda関数。
      • 環境変数にはテーブル名が含まれています。
      • コードは、DynamoDBにアクセスするための読み取りおよび書き込み権限をラムダに付与します。
    • API Gateway - GETメソッドのAPI。

 

アプリにサービスを追加する

  • /api/api_stack.py ファイルに次のコードを追加しておきます。

 

#Import the Service file created in the previou step
from . import aws_services

#service_file.constructor
aws_services.AWSService(self, "Services")

 

CDK Bootstrap

  • CDK Bootstrapは、AWS CDKがスタックをデプロイするために使用するS3バケットを作成します。
  • 次のコマンドを実行して、AWS環境をブートストラップしておきます。
cdk bootstrap

 

 

CDK Deploy

  • 次のコマンドを使用してCDKを展開しておきます。
cdk deploy

 

  • コンソールでは、CloudFormationスタックが作成されていることを見ることができます。サービスが作成されたことも見ることができます。

 

Lambda関数

 

DynamoDBテーブル

 

API Gateway

 

  • このコマンドを使用してCDKを破棄します。
cdk destroy

 

APIをテストする

  • DynamoDBテーブルにデータを追加しておきます。
  • curlコマンドを使用してAPIをテストすることができます。
  • テストするために、API Invoke URLでcurlコマンドを使用します。

 

curl -IX GET https://id.execute-api.us-east-1.amazonaws.com/prod/users

 

  • 200 Responseは、API Gatewayが正しく構成されていることを示します。

 

まとめ

AWS CDKとPythonを使用してDynamoDBでAPIを作成してみました。

Reference :