Lambda SnapStartがPythonをサポートしたのでCDK(Python)を使って試してみた

## Lambda SnapStartとは
すでに有用な記事が多く存在するので詳細は割愛しますが、Lambdaの起動時間を短縮するための仕組みの一つです。
詳細が気になる方は以下公式ガイドを参照ください。
https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html

## Lambda SnapStartとPython
Lambda SnapStartは、AWS re:Invent 2022でJavaでのみ提供することが発表されましたが、それから2年が経ちPythonと.NETにも一般提供を開始することが先日発表されました。

https://aws.amazon.com/jp/blogs/compute/reducing-java-cold-starts-on-aws-lambda-functions-with-snapstart/

https://aws.amazon.com/jp/blogs/news/aws-lambda-snapstart-for-python-and-net-functions-is-now-generally-available/

## さっそく試してみる
### 検証環境
```bash
python --version
Python 3.13.1

cdk --version
2.171.1 (build a95560c)
```

以下のリリースによって表題の機能が使えるようになっているので、CDKのバージョンはこちらより新しいものを利用します

https://github.com/aws/aws-cdk/releases/tag/v2.167.0

該当プルリクはこちら

https://github.com/aws/aws-cdk/pull/32112


### CDKによるスタック定義
必要最低限の実装にしています

```python:app.py
from aws_cdk import (
    App,
    Stack,
    aws_lambda as lambda_,
)
from constructs import Construct

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

        lambda_.Function(
            self,
            "SnapStartHandler",
            code=lambda_.Code.from_asset("lambda"),
            handler="index.handler",
            runtime=lambda_.Runtime.PYTHON_3_13,
            # ↓snap_startのパラメータを指定
            snap_start=lambda_.SnapStartConf.ON_PUBLISHED_VERSIONS,
        )

app = App()
SnapStartPythonStack(app, "LambdaSnapStartPythonStack")
app.synth()

```

### ハンドラーの実装
必要最低限の実装にしています

```python:lambda/index.py
def handler(event: dict, context: dict) -> dict:
    return {
        'statusCode': 200,
        'body': 'Lambda was invoked successfully.'
    }

```

### デプロイ

```bash
$ cdk deploy

[Warning at /LambdaSnapStartPythonStack/SnapStartHandler] SnapStart only support published Lambda versions. Ignore if function already have published versions [ack: @aws-cdk/aws-lambda:snapStartRequirePublish]

✨  Synthesis time: 3.84s

Stack undefined
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

IAM Statement Changes
┌───┬─────────────────────────────────────┬────────┬────────────────┬──────────────────────────────┬───────────┐
│   │ Resource                            │ Effect │ Action         │ Principal                    │ Condition │
├───┼─────────────────────────────────────┼────────┼────────────────┼──────────────────────────────┼───────────┤
│ + │ ${SnapStartHandler/ServiceRole.Arn} │ Allow  │ sts:AssumeRole │ Service:lambda.amazonaws.com │           │
└───┴─────────────────────────────────────┴────────┴────────────────┴──────────────────────────────┴───────────┘
IAM Policy Changes
┌───┬─────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐
│   │ Resource                        │ Managed Policy ARN                                                             │
├───┼─────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${SnapStartHandler/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │
└───┴─────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Do you wish to deploy these changes (y/n)? y
LambdaSnapStartPythonStack: deploying... [1/1]
LambdaSnapStartPythonStack: creating CloudFormation changeset...

 ✅  LambdaSnapStartPythonStack

✨  Deployment time: 39.29s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:123456789000:stack/LambdaSnapStartPythonStack/XXXXXXXXX-XXXXXXXXX-XXXXXXXXX-XXXXXXXXX

✨  Total time: 43.13s
```


## 作成されたハンドラー
以下のキャプチャの通り、SnapStartが有効になっていることが確認できます

![スクリーンショット 2024-12-14 18.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107176/1a52e5e4-66e2-1f78-59c0-4ac1d255060b.png)

## 終わりに
今回はPythonを使った必要最低限の実装でLambda SnapStartを試してみました。
Lambdaを利用する際に課題の一つとなるColdStartに対して有効とされるSnapStartがPythonでも利用できるようになったのは嬉しいですね。