😊

AWS CDK (Python)に入門、サンプルアプリのデプロイとLambda Containerのデプロイを実行してみた

2021/08/06に公開

Container LambdaのデプロイにCDKが使えたらカッコイイかと思って、普段使っているPythonで入門しみました。
結果、下記のことが分かり TypeScriptで書いた方が良いことがわかりました。

  • ネットの情報の圧倒的多数がTypeScript
  • PythonをTypeScriptに変換後、実行したときのエラーメッセージが出力されるが、変換後のコードに対するメッセージのため意味不明

また、CDKのバージョンアップが2,3日に一度ぐらいのペースで行われているので、
デプロイ頻度が月一とかのアプリやリソースには向かなさそうなことが分かりました。
久しぶりにアプリやリソース更新しようとしたら、まず、CDKのアップデートを追ってから実施、とかになってしまうので。

Cloud9を起動させる

(省略)

CDKの導入

CDKのバージョンと更新を確認

admin:~/environment $ cdk --version
1.111.0 (build 556ca93)
admin:~/environment $ npm update -g aws-cdk

Pythonのバージョンを確認

admin:~/environment $ python --version
Python 3.7.10

pipenvの導入

admin:~/environment $ pip install pipenv

プロジェクトディレクトリの作成

mkdir cdk-practice
cd cdk-practice

cdk initの実行

サンプルアプリ付きでcdk initする。ひな形を作成してくれる。

admin:~/environment $ cdk init sample-app --language python

下記のようなメッセージが出力される。

Applying project template sample-app for python

# Welcome to your CDK Python project!

You should explore the contents of this project. It demonstrates a CDK app with an instance of a stack (`environment_stack`)
which contains an Amazon SQS queue that is subscribed to an Amazon SNS topic.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

...

✅ All done!

Pythonのパッケージの導入

サンプルアプリを動かすのに必要なPythonのパッケージをインストールする。
setup.pyのinstall_requiresに書かれているパッケージとバージョンをコピペする。
※インストールされているnpm cdkとpythonのCDKパッケージのバージョンが合っていないといけないらしいので、バージョン指定でインストールする。

admin:~/environment (master) $ pipenv install aws-cdk.core==1.111.0 aws-cdk.aws_iam==1.111.0 aws-cdk.aws_sqs==1.111.0 aws-cdk.aws_sns==1.111.0 aws-cdk.aws_sns_subscriptions==1.111.0 aws-cdk.aws_s3==1.111.0
Creating a virtualenv for this project...
Pipfile: /home/ec2-user/environment/Pipfile
Using /usr/bin/python3 (3.7.10) to create virtualenv...
...
Alternatively, run a command inside the virtualenv with pipenv run.

requirements.txtに書いてあるpytestもインストールしておく。

admin:~/environment (master) $ pipenv install pytest

サンプルアプリの実行

サンプルアプリの確認

cdk_practice(プロジェクトディレクトリ名)の配下にあるcdk_practice_stack.pyをエディタで開いて確認する。

SQSとSNSトピックが作成され、SQSがトピックにサブスクライブされることが分かる。

cdk synthの実行

cdk synthを実行して、サンプルアプリをCloudformationテンプレートに変換、出力させてみる。

admin:~/environment/cdk-practice (master) $ pipenv shell
(.venv) admin:~/environment/cdk-practice (master) $ cdk synth

cdk bootstrapの実行

cdk bootstrapを実行して、cdk deployに必要なS3バケットを作成する。

(.venv) admin:~/environment/cdk-practice (master) $ cdk bootstrap

cdk diffの実行

cdk diffを実行して、cdk deploy時に変更されるリソースを確認する。

(.venv) admin:~/environment/cdk-practice (master) $ cdk diff
Stack cdk-practice
IAM Statement Changes

...

Resources
[+] AWS::SQS::Queue CdkPracticeQueue CdkPracticeQueueE1C8139E 
[+] AWS::SQS::QueuePolicy CdkPracticeQueue/Policy CdkPracticeQueuePolicyEAB70066 
[+] AWS::SNS::Subscription CdkPracticeQueue/cdkpracticeCdkPracticeTopicCA9DE39C CdkPracticeQueuecdkpracticeCdkPracticeTopicCA9DE39C4D3A7647 
[+] AWS::SNS::Topic CdkPracticeTopic CdkPracticeTopic11C6A5DF 

cdk deployの実行

cdk deployを実行して、サンプルアプリのリソースを作成する。途中、IAMを変更してもよいか、確認がでるので「y」を入力する。

(.venv) admin:~/environment/cdk-practice (master) $ cdk deploy

Cloudformationスタックの確認

(省略)

サンプルアプリの中身削除

cdk_practice_stack.pyの編集

下記のようにすっきりさせる

from aws_cdk import (
    core
)


class CdkPracticeStack(core.Stack):

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

cdk diffの実行

(.venv) admin:~/environment/cdk-practice (master) $ cdk diff
Stack cdk-practice
IAM Statement Changes
...
Resources
[-] AWS::SQS::Queue CdkPracticeQueueE1C8139E destroy
[-] AWS::SQS::QueuePolicy CdkPracticeQueuePolicyEAB70066 destroy
[-] AWS::SNS::Subscription CdkPracticeQueuecdkpracticeCdkPracticeTopicCA9DE39C4D3A7647 destroy
[-] AWS::SNS::Topic CdkPracticeTopic11C6A5DF destroy

cdk deployの実行

削除を反映させる。

(.venv) admin:~/environment/cdk-practice (master) $ cdk deploy

Cloudformationスタックの確認

(省略)

Container Lambdaの作成

hello.pyの作成

Lambda関数のコード hello.pyを作成する。cdk_practiceディレクトリ配下にhello.pyを作成して、下記のようにする。

def lambda_handler(event, context):

    print("Hello Lambda Container")

    return event

Dockerfileの準備

Dockerfileを準備する。cdk_practiceディレクトリ配下にDockerfileを作成して、下記のようにする。
※CMDには、Lambda関数のコードを記載したファイル名(.pyなし)、ファイル内の実行する関数を指定する。

FROM public.ecr.aws/lambda/python:3.8

COPY hello.py requirements.txt ./ 
RUN python3.8 -m pip install -r requirements.txt -t .

CMD ["hello.lambda_handler"]

requirements.txtの準備

requirements.txtを準備する。cdk_practiceディレクトリ配下にrequirements.txtを作成して、下記のようにする。
※テスト的にrequirementsモジュールを導入する(コードの中では利用なし)。

requests

cdk_practice_stack.pyの編集

from aws_cdk import (
    aws_lambda as _lambda,
    core,
)
import os


class CdkPracticeStack(core.Stack):

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

        _ = _lambda.Function(
            self,
            id="container_function",
            code=_lambda.EcrImageCode.from_asset_image(
                directory=os.path.join(os.getcwd(), "cdk_practice")
            ),
            handler = _lambda.Handler.FROM_IMAGE,
            runtime = _lambda.Runtime.FROM_IMAGE,
        )

cdk diffの実行

(.venv) admin:~/environment/cdk-practice (master) $ cdk diff
Stack cdk-practice
IAM Statement Changes

...

Resources
[+] AWS::IAM::Role container_function/ServiceRole containerfunctionServiceRoleF7A13B74 
[+] AWS::Lambda::Function container_function containerfunctionD03053C2 

cdk deployの実行

ECR aws-cdk/assetリポジトリを自動で作って、イメージをpushしてくれる。

(.venv) admin:~/environment/cdk-practice (master) $ cdk deploy

Cloudformationスタックの確認

(省略)

Lambda関数の実行

Lambda関数名を調べる。

(.venv) admin:~/environment/cdk-practice (master) $ aws lambda list-functions | grep practice

Lambda関数を実行する。

(.venv) admin:~/environment/cdk-practice (master) $ aws lambda invoke --function-name cdk-practice-containerfunctionD03053C2-ZEazzhfyaGdl out --log-type Tail --query 'LogResult' --output text |  base64 -d
START RequestId: 2ac91c75-9463-41aa-9384-4ce567d1d9d5 Version: $LATEST
Hello Lambda Container
END RequestId: 2ac91c75-9463-41aa-9384-4ce567d1d9d5
REPORT RequestId: 2ac91c75-9463-41aa-9384-4ce567d1d9d5  Duration: 1.02 ms       Billed Duration: 2 ms     Memory Size: 128 MB     Max Memory Used: 50 MB

後片付け

cdk destroyの実行

cdk destroyを実行して、リソースを削除する。
途中、本当に消すか確認が出るので「y」を押す。

(.venv) admin:~/environment/cdk-practice (master) $ cdk destroy

ECRリポジトリの削除

ECR aws-cdk/assetリポジトリを手動で削除する(詳細省略)。

Cloud9環境の削除

Cloud9の環境を削除する(詳細省略)。

参考資料

Discussion