コンテンツにスキップ

AWS Lambda@AWSリソース

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. AWS Lambdaとは

他の AWS リソースのイベントによって駆動する関数を管理できる。

サーバーレスアーキテクチャとは


01-02. セットアップ

コンソール画面の場合

▼ 設定項目と説明

設定項目 説明 補足
ランタイム 関数の実装に使用する言語を設定する。 コンテナイメージの関数では使用できない。
ハンドラ 関数の実行時にコールしたい具体的関数名を設定する。 ・コンテナイメージの関数では使用できない。
・Node.js:index.js というファイル名で exports.handler() 関数を呼び出したい場合、ハンドラ名を index.handler とする
レイヤー 異なる関数の間で、特定の処理を共通化できる。 コンテナイメージの関数では使用できない。
メモリ AWS Lambdaに割り当てるメモリサイズを設定する。 最大10240MBまで増設でき、増設するほど性能が上がる。
- https://www.business-on-it.com/2003-aws-lambda-performance-check/
タイムアウト
実行ロール AWS Lambda内の関数が実行されるときに必要なポリシーを持つロールを設定する。
既存ロール AWS Lambdaにロールを設定する。
トリガー AWS Lambdaにリクエストを送信できるAWSリソースを設定する。 設定されたAWSリソースに応じて、AWS Lambdaのポリシーが自動的に修正される。
アクセス権限 AWS Lambdaの認可スコープを設定する。 トリガーの設定に応じて、AWS Lambdaのポリシーが自動的に修正される。
宛先 AWS LambdaからリクエストできるAWSリソースを設定する。 宛先のAWSリソースのポリシーは自動的に修正されないため、別途、手動で修正する必要がある。
環境変数 AWS Lambdaの関数内に出力する環境変数を設定する。 デフォルトでは、環境変数はAWSマネージド型KMSキーによって暗号化される。
同時実行数 同時実行の予約を設定する。
プロビジョニングされた同時実行設定
モニタリング AWS LambdaをAmazon CloudWatchまたはX-Rayを使用して、メトリクスの元になるデータポイントを収集する。 次の方法がある
・Amazon CloudWatchによって、メトリクスの元になるデータポイントを収集する。
・Amazon CloudWatchのAWS Lambda Insightsによって、性能に関するメトリクスの元になるデータポイントを収集する。
・X-Rayによって、APIに対するリクエスト、AWS Lambdaコール、AWS Lambdaの宛先とのデータ通信をトレースし、これらをスタックトレース化する。


設定のベストプラクティス


AWS Lambdaと関数の関係性

lambda-execution-environment-api-flow

▼ AWS Lambdaサービス

コンソール画面の AWS Lambda に相当する。

▼ 関数の実行環境

AWS Lambda は、API (ランタイム API、ログ API、拡張 API) と実行環境から構成されている。

関数は実行環境に存在し、ランタイム API を経由して、AWS Lambda によって実行される。

実行環境には、3 個のフェーズがある。

lambda-execution-environment-life-cycle

▼ Initフェーズ

AWS Lambda が発火する。

実行環境が作成され、関数を実行するための準備が行われる。

▼ Invokeフェーズ

AWS Lambda は関数を実行する。

実行環境側のランタイムは、API を経由して AWS Lambda から関数に引数を渡す。

また関数の実行後に、API を経由して返却値を AWS Lambda に渡す。

▼ Shutdownフェーズ

一定期間、Invoke フェーズにおける関数実行が行われなかった場合、AWS Lambda はランタイムを完了し、実行環境を削除する。


AWS Lambda関数 on Docker

▼ ベースイメージの準備

▼ RIC:Runtime Interface Clients

通常のランタイムはコンテナ内関数と通信できないため、ランタイムの代わりに RIC を使用してコンテナ内関数と通信する。

言語別に RIC パッケージが用意されている。

▼ RIE:Runtime Interface Emulator

開発環境のコンテナで、擬似的に AWS Lambda 関数を再現する。

すべての言語で共通の RIE パッケージが用意されている。

RIE であっても、稼働させるために AWS の資格情報 (アクセスキーID、シークレットアクセスキー、リージョン) が必要なため、環境変数や資格情報ファイルを使用して、AWS Lambda にこれらの値を出力する。

*参考*

$ docker run \
    --rm \
    `# エミュレーターをエントリーポイントをバインドする。` \
    -v ~/.aws-lambda-rie:/aws-lambda \
    -p 9000:8080 \
    `# エミュレーターをエントリーポイントとして設定する。` \
    --entrypoint /aws-lambda/aws-lambda-rie \
    <コンテナイメージ名>:<バージョンタグ> /go/bin/cmd
# ハンドラー関数の引数に合ったJSON型データを送信する。
$ curl \
    -XPOST "http://127.0.0.1:9000/2015-03-31/functions/function/invocations" \
    -d '{}'

*参考*

version: "3.7"

services:
  lambda:
    build:
      context: .
      dockerfile: ./build/Dockerfile
    container_name: lambda
    # エミュレーターをエントリーポイントとして設定する。
    entrypoint: /aws-lambda/aws-lambda-rie
    env_file:
      - .docker.env
    image: <コンテナイメージ名>:<バージョンタグ>
    ports:
      - 9000:8080
    # エミュレーターをエントリーポイントをバインドする。
    volumes:
      - ~/.aws-lambda-rie:/aws-lambda
docker compose up lambda
$ curl \
    -XPOST "http://127.0.0.1:9000/2015-03-31/functions/function/invocations" \
    -d '{}'


同時実行

▼ 同時実行の予約

AWS Lambda は、関数の実行中に再びリクエストを受信すると、関数のインスタンスを新しく作成する。

そして、各関数インスタンスを使用して、並行的にリクエストに応じる。

デフォルトでは、関数の種類がいくつあっても、AWS アカウント当たり、合計で 1000 個までしかスケーリングして同時実行できない。

関数ごとに同時実行数の使用枠を割り当てるためには、同時実行の予約を設定する必要がある。

同時実行の予約数を 0 個とした場合、AWS Lambda がスケーリングしなくなる。

lambda_concurrency-model


Amazon VPC外/Amazon VPC内

▼ Amazon VPC外への配置

AWS Lambda はデフォルトでは Amazon VPC 外に配置される。

この場合、AWS Lambda に ENI が紐付けられ、ENI に割り当てられた IP アドレスが AWS Lambda に適用される。

AWS Lambda の実行時に ENI は再作成されるため、実行ごとに IP アドレスは変化するが、一定時間内の再実行であれば ENI は再利用されるため、前回の実行時と同じ IP アドレスになることもある。

▼ Amazon VPC内への配置

AWS Lambda を Amazon VPC 内に配置するように設定する。

Amazon VPC 内に配置した AWS Lambda にはパブリック IP アドレスが割り当てられないため、アウトバウンド通信するためには、NAT Gateway を配置する必要がある。


ポリシー

▼ 実行のための最低限のポリシー

AWS Lambda を実行するためには、デプロイされた関数を使用する認可スコープが必要である。

そのため、関数を取得するためのステートメントを設定する。

{
  "Version": "2012-10-17",
  "Statement":
    [
      {
        "Effect": "Allow",
        "Action": "lambda:InvokeFunction",
        "Resource": "arn:aws:lambda:ap-northeast-1:<AWSアカウントID>:function:<関数名>*",
      },
    ],
}


データベース

  • AWS DynamoDB
  • Amazon RDS プロキシと Amazon RDS


デプロイ

▼ 直接的に修正

デプロイを行わずに、関数のコードを直接的に修正し、『Deploy』ボタンでデプロイする。

▼ Amazon S3における .zip ファイル

ビルド後のコードを .zip ファイルにしてアップロードする。

ローカルマシンまたは S3 からアップロードできる。

▼ Amazon ECRにおけるイメージ

コンテナイメージの関数のみで有効である。

ビルド後のコードをコンテナイメージしてアップロードする。

Amazon ECR からアップロードできる。


02. AWS Lambda@Edge

AWS Lambda@Edgeとは

Amazon CloudFront に統合された AWS Lambda を、特別に AWS Lambda@Edge という。


02-02. セットアップ

コンソール画面の場合

▼ トリガーの種類

lambda-edge

Amazon CloudFront のビューワーリクエスト、オリジンリクエスト、オリジンレスポンス、ビューワーレスポンスをトリガーとする。

エッジロケーションの Amazon CloudFront に、AWS Lambda のレプリカを作成する。

トリガーの種類 発火のタイミング
ビューワーリクエスト Amazon CloudFrontが、ビューワーからリクエストを受信した後 (キャッシュを確認する前) 。
オリジンリクエスト Amazon CloudFrontが、リクエストをオリジンサーバーにフォワーディングする前 (キャッシュを確認した後) 。
オリジンレスポンス Amazon CloudFrontが、オリジンからレスポンスを受信した後 (キャッシュを確認する前) 。
ビューワーレスポンス Amazon CloudFrontが、ビューワーにレスポンスをフォワーディングする前 (キャッシュを確認した後) 。

▼ 各トリガーのeventオブジェクトへのマッピング

各トリガーの event オブジェクトへのマッピングは、リンクを参考にせよ。


ポリシー

▼ 実行のための最低限のポリシー

AWS Lambda@Edge を実行するためには、最低限、以下の認可スコープが必要である。

{
  "Version": "2012-10-17",
  "Statement":
    [
      {
        "Effect": "Allow",
        "Action": ["iam:CreateServiceLinkedRole"],
        "Resource": "*",
      },
      {
        "Effect": "Allow",
        "Action": ["lambda:GetFunction", "lambda:EnableReplication*"],
        "Resource": "arn:aws:lambda:ap-northeast-1:<AWSアカウントID>:function:<関数名>:<バージョン>",
      },
      {
        "Effect": "Allow",
        "Action": ["cloudfront:UpdateDistribution"],
        "Resource": "arn:aws:cloudfront::<AWSアカウントID>:distribution/<DistributionID>",
      },
    ],
}


03. AWS Lambda Web Adapter

AWS Lambda Web Adapterとは

AWS Lambda の拡張機能である。

通常の AWS Lambda では動かせないフレームワーク (例:Express.js、Next.js、SprintBoot、ASP.NET、Laravel など) のアプリを動かせるようにする。

アプリケーションのプロセスの前段でリクエストを変換し、アプリケーションがリクエストを処理できるようにする。

lambda-web-adapter


Dockerfile

▼ Next.jsの場合

FROM node:20.12.2-bullseye-slim AS builder
WORKDIR /build
COPY package.json yarn.lock ./
RUN yarn install && yarn next telemetry disable
COPY . .
RUN yarn build

FROM amazon/aws-lambda-nodejs:20.2024.04.24.10
WORKDIR /usr/local/statuspage
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.3 /lambda-adapter /opt/extensions/lambda-adapter
COPY --from=builder /build/next.config.mjs /build/public /build/.next/static /build/.next/standalone ./
RUN ln -s /tmp/cache ./.next/cache
EXPOSE 3000
ENV PORT=3000
ENTRYPOINT ["node", "server.js"]