AWS CDK(Python)の導入からLambda+API gatewayの構築までやってみた

## 概要
エンジニア歴1年目がAWS CDK（Python）を使って初めてサーバレスAPIを構築したので、CDKの導入から簡単な利用法について備忘録的にまとめていこうと思います。

## AWS CDKとは？
AWS クラウド開発キット(AWS CDK)はクラウドインフラストラクチャをコードとして定義し、AWS CloudFormationを通じてデプロイするためのソフトウェア開発フレームワークです。
対応している言語はJavaScript、TypeScript、Python、Java、C#が一般公開されており、開発者プレビューではGoも対応しています。

https://aws.amazon.com/jp/cdk/

## CDKの導入
### CDKのインストール
それでは導入から始めていきましょう。
下記のコマンドにてCDKをインストールします。

```
npm install -g aws-cdk
```

### アプリケーションの作成
新しいディレクトリを作成し、その中にサンプルのCDKアプリケーションを作成します。

```
mkdir cdk-project　&& cd cdk-project
cdk init app --language python
```

下記2つのコマンドを実行し、Python virtual environmentをアクティブにし、必要な依存関係をインストールします。

```
source .venv/bin/activate
pip install -r requirements.txt
```
以上でCDKの導入は完了です、では実際のコードを書いていきましょう。

## Lambda関数の作成
まず、プロジェクトのメインディレクトリに`cdk_src/lambda_handler.py`を作成します。
このファイルには実際にLambdaに反映させるコードを記述します。

```python:lambda_handler.py

import json


def handler(event, context):

    body = {'result': True}

    res = {
        'statusCode': 200,
        'body': body
    }

    res['body'] = json.dumps(res['body'], ensure_ascii=False)
    return res

```

## リソースの作成
次に、プロジェクトのメインディレクトリに`cdk_stack/resource.py`を作成します。
ここではリソースの定義を行います。

```python:resource.py

from aws_cdk import Stack
from aws_cdk import aws_apigateway as apigw
from aws_cdk import aws_lambda as _lambda
from aws_cdk import aws_logs as logs
from constructs import Construct


class ResourceStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # CloudWatchLogs
        logs.LogGroup(
            self,
            id='lambda-handler-log',
            log_group_name='/aws/lambda/lambda-handler',
            retention=logs.RetentionDays.INFINITE
        )

        # Lambda
        cdkLambda = _lambda.Function(
            self,
            id='lambda-handler',
            function_name='lambda-handler',
            code=_lambda.Code.from_asset('./cdk_src'),
            handler='lambda_handler.handler',
            runtime=_lambda.Runtime.PYTHON_3_9,
        )

        # ApiGateway
        api = apigw.RestApi(self, id='cdk-api')
        cdk_lambda_api = api.root.add_resource('cdkLambda')
        cdk_lambda_api.add_method('GET', apigw.LambdaIntegration(cdkLambda))
```

_lambda.Functionの下記の部分ですが、ディレクトリを指定しているので複数のLambda関数を作成する場合にはファイルごとにディレクトリを作成してください。
```
code=_lambda.Code.from_asset('./cdk_src'),
```

最後にメインディレクトリに戻り`app.py`を書き換えます。

```python:app.py
import aws_cdk as cdk
from cdk_stack.resource import ResourceStack

app = cdk.App()
ResourceStack(app, "ResourceStack")
app.synth()
```

これでコードは完成です。あとは下記のコマンドでデプロイします。
以上で基礎的なLambda+API gatewayの構築が可能となります。

```
cdk deploy
```

## AWS SAMとの比較
CDKの話題になると、同じようにCloudformationを利用するサーバーレスアプリケーション構築用フレームワークであるAWS SAMが比較対象としてよく挙げられると思います。
使い慣れた言語がある人はYAML特有の書き方を覚える工程をスキップすることができるので、CDKの利用を考えてみるのも良いと思います。
また、その他の差別化点としてSAMがサーバレスのサービスに対応しているのに対して、CDKは全てのAWSサービスに対応しているという点があります。

ここまで聞くとCDKの方に一方的に軍配が上がりそうですが、複数サービスを定義する場合のstackの分割が難しかったり、サービスによっては(今回紹介したApigatewayなども当てはまる)CDKを使うメリットの一つでもある、コード量を抑えることができるという点が活きにくいものもあるので、利用サービスや利用者のスキルに合わせて選択する方が良さそうです。

最後まで見て頂きありがとうございました、初めての記事投稿なので拙い点もありますが、これからも機会を見つけて投稿していこうと思います。今回はここまで。