コンテンツにスキップ

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 が発火する。

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"]