0
0

CDKでLambdaをイメージとしてデプロイする

Last updated at Posted at 2023-12-16

まとめ

まとめを先に書きます。

CDKを用いたIaCプロジェクトから、コンテナイメージとしてLambdaをデプロイする事ができます。実際に試すことができるミニマムなコードを紹介します。

AWS LambdaにおけるCDKとコンテナの位置づけ

本記事のサンプルが狙うポイントの紹介ですが、既にご存じの方は次セクションへスキップしてください。

コンテナを利用する利点
カスタマイズ性が高いLambdaを開発できることと、イメージサイズの上限が高いことが挙げられます。Zipパッケージでは250MBが上限であるところ、イメージでは10GB1まで利用できます。大きめのpythonパッケージ2を使う場合には250MBは厳しい制約ですが、10GBであればOSレイヤーのサイズも含むとはいえ十分な自由度が得られます。

CDKを利用する利点
AWSのサービスを用いたワークロードのIaC3が上手にできるツールです。著名なプログラミング言語(TypescriptやPythonなど)でワークロード全体 (アプリケーションやインフラなど) を記述し、コードの実行によりデプロイや更新できます4。つまり、Python言語でLambdaそのものとLambda上で実行されるプログラムの両方を記述し、git上で一様に管理することができます。これにより、一例としてプログラムはきちんと変更管理をしているのに、実際にデプロイされたLambdaの設定変更は管理されていなかった…といった分断が予防されます。

利点の用例

次のようなケースをまるっとコードで取り扱えます。

開発環境

当記事の作成環境です。

cdkコマンドをインストール

$ npm install -g aws-cdk
$ cdk --version
2.114.1 (build 02bbb1d)
$

AWS Cliのプロファイル作成などの前提は下記デベロッパーガイドをご覧ください。

プロジェクト作成

CDKのサンプルアプリを新規作成します。ミニマムな例を示したいので、サンプルコードを改変する流れで紹介していきます。

$ cdk init sample-app --language=python
...
✅ All done!
$

初期状態では、以下のようファイル一式が作成されます。

$ ls
README.md  cdk.json              requirements-dev.txt  sample
app.py     requirements.txt      tests                 source.bat
$ 

Poetryを使う

当記事はPoetryを利用した状況での説明内容になっていますので、requirementsをPoetry経由でインストールします。

$ poetry init
$ poetry add $( cat requirements.txt )
$ poetry add --dev $( cat requirements-dev.txt )

今回、requirementsは使いませんので削除しておきます。

$ rm requirements.txt
$ rm requirements-dev.txt

Python仮想環境に入る

pythonパッケージをインストールし、仮想環境に入ります。aws-cdk-libがインストールされている事も確認しておきます。

$ poetry install
$ poetry shell
$ poetry show aws-cdk-lib
 name         : aws-cdk-lib                                        
 version      : 2.110.0    
...
$

Dockerfileを書く

Lambda のベースコンテナイメージが Amazon ECR リポジトリで公開されていますので利用します。ほかにも多数のバージョンや開発言語向けのイメージがありますので、ご興味がある方は次のドキュメントをご覧ください。

Dockerfile
FROM public.ecr.aws/lambda/python:3.11
# Install poetry
RUN curl -sSL https://install.python-poetry.org \
    | POETRY_HOME=/opt/poetry python \
    && cd /usr/local/bin \
    && ln -s /opt/poetry/bin/poetry \
    && poetry config virtualenvs.create false
COPY src/ ${LAMBDA_TASK_ROOT}/
COPY pyproject.toml poetry.lock ${LAMBDA_TASK_ROOT}/
# Install python packages without dev pkgs
RUN poetry install --no-root --no-dev
# CMD [ "sample.handler" ] # ★1

★1の CMD はコンテナイメージが起動対象とするLambdaのモジュールと関数名を指定する行ですが、次セクションでCDKのStack定義から指定しますので、Dockerfile内では無指定でOKです。

Lambdaのコード

処理は本記事の主題ではないのでこんにちは世界。

src/sample.py
def handler(event, context):
    return {"message": "Hello World!"}

Stack定義を書く

一つのLambda関数リソースだけを定義したシンプルなCDKスタック定義です。

sample_stack.py
class SampleStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        # コンテナイメージを定義
        image_asset = aws_lambda.DockerImageCode.from_image_asset(
            cmd=["sample.handler"],
            directory=".",
        )
        # コンテナイメージ方式のLambda関数を定義し、利用イメージを指定
        aws_lambda.DockerImageFunction(
            scope=self, id="SampleFunction", code=image_asset
        )

aws_lambda.DockerImageCode.from_image_asset メソッドでは、どのLambdaで使うコンテナイメージのAsset一式を指定します。directory パラメータに与える値は、docker buildコマンドのPATHを指定することに対応します。cmd パラメータに与える値は、Dockerfileにおける CMD の指定に対応しており、先のDockerfile内でCOPYした src/ 配下の sample.py handler 関数が実行対象プログラムであることを示します。docker run コマンドの COMMAND オプション を指定することに対応します。

aws_lambda.DockerImageFunction メソッドでは、AWS上にプロビジョニングするLambdaリソースを定義しています。先のコンテナイメージを利用させる指定をしていますが、LambdaのTimeoutやメモリサイズなどLambdaリソースへのセッティングができます。

いずれのメソッドも、指定可能なパラメータ数が豊富ですね。

これは私感ですが、CDKの仕様からは、AWSサービスを広くモデリングして、AWSでできること全体をCDKでもIaCできるようにしようという意思を感じます。実際、CDKはそのカバー範囲の広さがAPIドキュメントからよく分かりますし、更新頻度やコントリビューションの活発さもあって頼もしいツールです。

Bootstraping Stackの作成

予め、bootstrap コマンドを一度だけ実行しておきます。

$ cdk bootstrap
 ✅  Environment aws://ACCOUNT_NO/REGION bootstrapped.
$

CDKを介してインフラやアプリケーションをAWS環境にデプロイするには、ブートストラッピングスタックと呼ばれる、リソースプロビジョニングを行ってくれる仕組みが介在します。デプロイ先リージョンのCloudformationスタックとして一度作成しておく操作が bootstrap コマンドです。

デプロイ

いよいよ、Lambda関数をCDK経由でデプロイします。

$ cdk deploy
...
✨  Synthesis time: 4.1s

SampleStack:  start: Building 
...
Step 1/4 : FROM public.ecr.aws/lambda/python:3.11
 ---> be5c629c78a6
...
1:21:11 AM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack | SampleStack
...
✨  Total time: 70.32s

$

デプロイ結果の確認

Cloudformation Stacks

Cloudformation Stack Sample Stack としてデプロイされました。

image.png

ECR

ECR リソースが、 CDKToolkit スタックのリソースとして作られ、デプロイ対象のLambdaイメージの管理に利用されています。

image.png

LambdaのコンテナイメージはローカルPC上のDocker Serverでビルドされ、ECRにpushされてからLambda関数としてデプロイされているわけですが、CDKのAPIが一連のプロビジョニングからデプロイまでのプロセスを、Stack定義の記述だけで済ませられるようラップしてくれている点がGoodです。

Lambda

イメージデプロイされたLambdaが存在する事も確認できました。
image.png

テストも通りますね。
image.png

以後、DockerfileやStack定義を育てる過程で、前述の利点を享受し続けることになります。

余談&紹介

本記事は、私が所属しているAWSサービスプロバイダーの社内Slackで、アドベントカレンダーやろうぜ!と募集があり楽しげでしたので参加する形で執筆しました。カレンダーにはAWS関連の記事が主に投稿されていますので、ご興味がありましたらぜひ覗いてみてください。

余談まで読んでくださりありがとうございます。良い年末をお過ごしください。

  1. ただしZipパッケージとは異なり、イメージの場合はOSやミドルウェアレイヤーのサイズを含む上限です。Lambdaのクォータに関する仕様 - https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-limits.html

  2. たとえばNumPyやSciPyのパッケージサイズは250MBを超えます - https://avilpage.com/2020/02/reduce-python-package-footprint.html

  3. IaCに関するAWSのホワイトペーパー https://aws.amazon.com/jp/what-is/iac/

  4. デベロッパーガイドの冒頭 https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/home.html

  5. 環境要件にOracle Instant Clientのインストールが要求されるので、イメージデプロイが向いている

  6. extraモジュール独自の分類器もインストールして使いたい場合なども、イメージデプロイが向いている

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0