【Severless】AWS CDK ~ 入門編 ~

■ はじめに

https://dk521123.hatenablog.com/entry/2024/05/26/001612

の続き。

今回は、AWS CDK (AWS Cloud Development Kit) を取り上げる。

目次

【1】AWS CDK
 1)サポート言語
【2】環境設定
 1)インストール手順
【3】AWS CDK CLI コマンド
 1)cdk bootstrap
【4】Hello World
 1)CDK プロジェクト作成
 2)Lambda 関数を作成する
 3)コンストラクトを定義する
 4)app.py の修正
 5)アプリケーションをデプロイする
 6)動作確認
 7)アプリケーションを削除する
【5】トラブルシュート
 1)cdk synth/cdk bootstrapを実行した際にエラー「ModuleNotFoundError: No module named 'aws_cdk'」

【1】AWS CDK

* AWS CDK = AWS Cloud Development Kit
* TypeScript及びPythonなどで、AWSリソースを定義し、
 Terraformの様にInfrastructure as Code(IaC)を実現するサービス
 => Lambda だけでなく、様々なAWSリソース(VPC/IAMなど)を作れる
 => Pulumi の AWS版みたいな感じ(コマンドの作りも似ている)

Pulumi ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2021/10/23/025230

 => CDKで、AWS CloudFormationを生成し、デプロイする流れ

https://docs.aws.amazon.com/cdk/api/v2/
https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/home.html
https://aws.amazon.com/jp/blogs/news/lambda-managed-by-cdk/
https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/serverless_example.html
Lambda を C# で実装する場合
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/csharp-package-cdk.html
サンプル集
https://github.com/aws-samples/aws-cdk-examples/tree/main/python
動画 (AWS)
https://www.youtube.com/watch?v=BmCpa44rAXI
https://www.youtube.com/watch?v=aqa2bFFzcjs
https://www.youtube.com/watch?v=z3Mst77p-aU

1)サポート言語

https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/languages.html

* TypeScript
* JavaScript
* Python
* Java
* C#/.Net
* Go

【2】環境設定

* AWS CDK を利用するためには、CDK Toolkit が入っている必要がある
 => 「cdk --version」で確認し、なければ「1)インストール手順」を参照

1)インストール手順

# Step1: npmが入っているか確認(あればStep2へ)
npm --version
# なかったら「Node.js ~ 環境構築編 ~」を参照
#  => 今回は、「10.8.0」
# Step2: CDK Toolkit のインストール
npm install -g aws-cdk

# Step3: 確認
$ cdk --version
2.143.0 (build 9f2bdf7)

Node.js ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2021/11/06/000000

【3】AWS CDK CLI コマンド

* 以下の公式ドキュメントを参照

https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/ref-cli-cmd.html

主なコマンド一覧

CLI Explanations Memo
cdk init テンプレートから新しい CDK プロジェクトを作成 cdk init --language python
cdk synth CloudFormation テンプレートを生成 cdk synthesize でもOK
cdk bootstrap デプロイに必要なロールやリソースを事前準備 後述「[a] cdk bootstrap」に詳細な説明あり
cdk deploy AWS環境へデプロイ
cdk destroy AWS環境の破棄
cdk diff ローカルスタックと差分を表示
cdk list Stack 一覧表示 cdk lsでもOK。cdk list [STACKS..]やcdk list "demo*"みたいな感じでもできる

1)cdk bootstrap

* CDKが利用するECR/IAM/S3/SSMといったリソースを作成する

https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/ref-cli-cmd-bootstrap.html
https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html

# cdk bootstrap aws://ACCOUNT-NUMBER/REGION
cdk bootstrap aws://1234567890123/us-west-2

# どういうことやるか確認できる
cdk bootstrap --show-template > bootstrap.yaml

# テンプレートから実行する
cdk bootstrap --template bootstrap.yml

cdk bootstrap --toolkit-stack-name demoCDKToolkit --qualifier hello
Options Explanations Memo
--trust 信頼できるAWSアカウントID 複数指定可能
--cloudformation-execution-policies デプロイを実行するロールにアタッチする必要があるIAM ARNs(e.g. --cloudformation-execution-policies arn:aws:iam::aws:policy/PowerUserAccess) 複数指定可能
--public-access-block-configuration 作成される Amazon S3 バケットのパブリックアクセス設定を行わない デフォルト「true」
--bootstrap-kms-key-id KMS マスターキー ID
--toolkit-stack-name Bootstrap リソースのスタック名
-b, --bootstrap-bucket-name CDK toolkitのバケット
--qualifier リソースに付与する修飾子/CDKを区別するための識別子 デフォルト「hnb659fds」。10文字以内

参考文献
https://dev.classmethod.jp/articles/customize-bootstrap/
https://dev.classmethod.jp/articles/changing-the-aws-cdk-bootstrap-environment-from-the-default-qualifier-hnb659fds/
https://engineering.mobalab.net/2023/09/12/rethinking-of-aws-cdk-permissions/

【4】Hello World

* 以下を見ながらやるといいかも

https://cdkworkshop.com/30-python.html
https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/serverless_example.html

* 言語は、Pythonで。

1)CDK プロジェクト作成

# mkdir <ProjectName> && cd <ProjectName>
$ mkdir cdk-hello-world && cd cdk-hello-world

# Python の場合
$ cdk init --language python

# venv を有効にする
$ source .venv/bin/activate
# On Windows
# .\venv\Scripts\activate

# 依存関係をインストール
(.venv)$ python3 -m pip install -r requirements.txt

フォルダ構成

cdk-hello-world
├── .git
├── .gitignore
├── .venv
├── README.md
├── app.py
├── cdk.json
├── cdk_hello_world
│   ├── __init__.py
│   └── cdk_hello_world_stack.py
├── requirements-dev.txt
├── requirements.txt
├── source.bat
└── tests

2)Lambda 関数を作成する

# プロジェクトのルートから、以下を実行
mkdir lambda && cd lambda

# ここは、公式のHands-onとは異なる
touch hello.py

hello.py

import json

def handler(event, context):
    print('request: {}'.format(json.dumps(event)))
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'text/plain'
        },
        'body': 'Hello, World! You have hit {}\n'.format(event['path'])
    }

3)コンストラクトを定義する

vi cdk_hello_world/cdk_hello_world_stack.py

cdk_hello_world/cdk_hello_world_stack.py

from aws_cdk import (
    Stack,
    # Import Lambda L2 construct
    aws_lambda as _lambda,
)
from constructs import Construct

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

        # Define the Lambda function resource
        hello_world_function = _lambda.Function(
            self,
            "HelloWorldFunction",
            runtime = _lambda.Runtime.PYTHON_3_12,
            code = _lambda.Code.from_asset("lambda"), # Points to the lambda directory
            handler = "hello.handler", # Points to the 'hello' file in the lambda directory
        )

4)app.py の修正

app.py

#!/usr/bin/env python3
import os

import aws_cdk as cdk

from cdk_hello_world.cdk_hello_world_stack import CdkHelloWorldStack


app = cdk.App()
CdkHelloWorldStack(app, "CdkHelloWorldStack",
    # If you don't specify 'env', this stack will be environment-agnostic.
    # Account/Region-dependent features and context lookups will not work,
    # but a single synthesized template can be deployed anywhere.

    # Uncomment the next line to specialize this stack for the AWS Account
    # and Region that are implied by the current CLI configuration.

    #env=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')),

    # Uncomment the next line if you know exactly what Account and Region you
    # want to deploy the stack to. */

    #env=cdk.Environment(account='123456789012', region='us-east-1'),
    # ★ここを修正(env=cdk.Environment(account='【AWS Account ID】', region='【AWS Region】'))
    env=cdk.Environment(account='123456789012', region='us-west-2'),

    # For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html
    )

app.synth()

5)アプリケーションをデプロイする

# AWS 環境の 1 回限りのブートストラップを実行する必要がある
# cdk bootstrap aws://ACCOUNT-NUMBER/REGION
$ cdk bootstrap aws://1234567890123/us-west-2 --toolkit-stack-name demo --qualifier hello

$ cdk deploy

6)動作確認

curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/hello

7)アプリケーションを削除する

$ cdk destroy

【5】トラブルシュート

1)cdk synth/cdk bootstrapを実行した際にエラー「ModuleNotFoundError: No module named 'aws_cdk'」

 cdk synth/cdk bootstrapを実行した際に
エラー「ModuleNotFoundError: No module named 'aws_cdk'」が表示される

原因

* aws_cdk モジュールがインストールされていないため

解決案

pip3 install -r requirements.txt
で、pipインストールする

参考文献

https://qiita.com/Brutus/items/6c8d9bfaab7af53d154a
https://zenn.dev/collabostyle/articles/2596792d6075e7
動画 (その他)
https://www.youtube.com/watch?v=EpiGUb50bIE

関連記事

AWS Chalice ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2024/05/27/000808
Serverless Framework以外のフレームワーク
https://dk521123.hatenablog.com/entry/2024/05/26/001612
Node.js ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2021/11/06/000000
Node.js ~ 基本編 / npm ~
https://dk521123.hatenablog.com/entry/2018/06/13/234315
Lambda ~ Python / S3トリガー ~
https://dk521123.hatenablog.com/entry/2024/05/23/162229
Lambda のトラブルシュート
https://dk521123.hatenablog.com/entry/2017/12/16/231714
Pulumi ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2021/10/23/025230