コンテナイメージ版AWS Lambda関数をCloudFormationでデプロイしてみた

2022.01.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

デプロイをCloudFormationテンプレート(IaC)化すると、デプロイパイプラインにスムーズに組み込むことができます。

今回は、コンテナイメージ版LambdaをCloudFormationでデプロイする方法を紹介します。

コンテナLambdaをデプロイするCloudFormation テンプレート

コンテナLambda(非VPC版)をデプロイするには、次のテンプレートを利用します。

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  EcrImageUri:
    Description: ECR image URI
    Type: String
Resources:
  LambdaFunc:
    Type: AWS::Lambda::Function
    Properties:
      Role:
        Fn::GetAtt:
        - LambdaRole
        - Arn
      PackageType: Image
      Code:
        ImageUri: !Ref 'EcrImageUri'
      Architectures:
        - x86_64
      MemorySize: 512
      Timeout: 30
  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

コンテナ Lambda固有の記述について、かいつまんで紹介します。

コンテナ固有のプロパティ

コンテナLambdaの場合、 PackageType プロパティに Image を設定し、 コンテナイメージのURIを Code プロパティで指定します。

Properties:
    ...
    PackageType: Image
    Code:
        ImageUri: ECRのURI
    ...

本テンプレートでは、イメージURIをパラメーター化しています。

不要なプロパティ

コンテナLambdaの場合、以下のプロパティは不要です。

  • Runtime (nodejs14.x など)
  • Handler (index.handler など)

コンテナLambdaをCloudFormationでデプロイしてみる

作成した CloudFormation テンプレートを利用し、コンテナLambdaをデプロしてみます。

ECR の作成

まずは、コンテナレジストリのAmazon Elastic Container Registry (ECR)を作成します。

$ aws ecr create-repository --repository-name test
{
    "repository": {
        "repositoryArn": "arn:aws:ecr:eu-central-1:123:repository/test",
        "registryId": "123",
        "repositoryName": "test",
        "repositoryUri": "123.dkr.ecr.eu-central-1.amazonaws.com/test",
        "createdAt": "2022-01-03T21:06:35+01:00",
        "imageTagMutability": "MUTABLE",
        "imageScanningConfiguration": {
            "scanOnPush": false
        },
        "encryptionConfiguration": {
            "encryptionType": "AES256"
        }
    }
}

アプリケーションの作成

次に動作確認用 Python アプリケーションを作成します。

app.pyDockerfile の2ファイルを作成します。

app.py

app.py

import sys
def handler(event, context):
    return 'Hello from AWS Lambda using Python' + sys.version + '!'

Dockerfile

Dockerfile

FROM public.ecr.aws/lambda/python:3.9
COPY app.py ${LAMBDA_TASK_ROOT}
CMD [ "app.handler" ]

イメージをビルド

このイメージをビルドします。

$ docker build -t test:latest .

ローカルで動作確認します。

# コンテナ起動用ターミナル
$ docker run -p 9000:8080 test:latest

# クライアント用ターミナル
$ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
"Hello from AWS Lambda using Python3.9.8 (main, Dec 10 2021, 06:31:09) \n[GCC 7.3.1 20180712 (Red Hat 7.3.1-13)]!"

実行出来ています。

ECR にイメージをプッシュ

このイメージをECRにプッシュします。

$ aws ecr get-login-password | docker login --username AWS --password-stdin アカウントID.dkr.ecr.リージョン.amazonaws.com
$ docker tag test:latest アカウントID.dkr.ecr.リージョン.amazonaws.com/test:latest
$ docker push アカウントID.dkr.ecr.リージョン.amazonaws.com/test:latest

コンテナ Lambda のデプロイ

CloudFormationテンプレートを使い、コンテナ Lambda をデプロイします。

$ aws cloudformation deploy \
  --stack-name lambda-container-test \
  --template-file ./cfn.yml \
  --parameter-overrides EcrImageUri=アカウントID.dkr.ecr.リージョン.amazonaws.com/test:latest \
  --capabilities CAPABILITY_IAM

--template-body 引数で CloudFormation テンプレートを指定し、--parameters で ECR イメージの URI を指定します。

AWSコンソールからCloudFormationスタックを作成することも出来ます。

コンテナLambdaの動作確認

最後に、Lambda関数を動作確認します。

$ aws lambda invoke \
  --function-name lambda-container-test-LambdaFunc-xxx  \
  --invocation-type RequestResponse  \
  --payload '{}' response.json && cat response.json

{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
"Hello from AWS Lambda using Python3.9.8 (main, Dec 10 2021, 06:31:09) \n[GCC 7.3.1 20180712 (Red Hat 7.3.1-13)]!"

無事実行できました。

AWS SAMでもデプロイ可能

コンテナ Lambdaをデプロイしたい場合、AWS サーバーレスアプリケーションモデル(AWS SAM)を使うアプローチも有力です。

AWSのAPIを逐一呼び出さずに済み、ディベロッパーの開発フローに寄り添ったコマンド体系が提供されています。

詳細は次のドキュメントを参照ください。

コンテナ Lambda を AWS SAM でデプロイしよう ! ~コンテナ利用者に捧げる AWS Lambda の新しい開発方式 ! ~ 第 4 回 - 変化を求めるデベロッパーを応援するウェブマガジン | AWS

それでは。

参考