AWS Lambdaについてのメモ

ryichk
·
公開:2023/12/17

Lambdaの制限

  1. ステートレス

  2. 最大稼働時間は15分

  3. アーカイブサイズは50MB、展開後は250MB

Lambda関数

Lambda関数が受け取る引数はJSON形式を使うのが慣例。

Lambda関数には引数や戻り値の書式、エラーの返し方など、さまざまな規定がある。規定はプログラミング言語によって異なる。

イベントの情報(event引数)

関数に渡される入力データ。

event引数にはイベントに関する情報が格納されて呼び出される。

例えば、「イベントが発生した時刻」「ファイルが置かれたパス」「メールを受信した際の受信メールアドレス」など。

書式や内容はイベントによって異なる。

コンテキストの情報(context引数)

コンテキストの情報は、Lambda実行環境の情報である。

例えば、「割り当てられているメモリ容量」「Lambda関数が配置されているパス名」「一時ディレクトリのパス名」など。

Lambdaの利用に必要な権限

  • Lambda関数の登録権限

    lambda:CreateFunctionという権限が必要。

  • Lambda関数の実行権限

    lambda:InvokeFunctionという権限が必要。

  • Lambda関数の実行ロール

    Lambda関数はログをCloudWatch Logsへ書き込むので、logs:PutLogEvents、logs:CreateLogStream、logs:CreateLogGroupの3つの権限が必要。

    他にもS3やDynamoDBなどのAWSリソースを操作したいときは、それらのリソースへのアクセス権限が必要。

管理ポリシー

IAMユーザには以下のいずれかのポリシーを適用する。

  • AWSLambda_ReadOnlyAccess

    Lambda、DynamoDB、S3などのリソースへの読み取り専用アクセス権限

  • AWSLambdaRole

    Lambda関数の実行権限のみを設定したもの。

  • AWSLambda_FullAccess

    Lambda、DynamoDB、S3などのリソースへのフルアクセス権限。

    Lambda関数を作成・変更・実行・削除できる。

Lambda関数に結びつけるIAMロールには以下のいずれかのポリシーを適用する。

  • AWSLambdaBasicExecutionRole

    CloudWatch Logsへの書き込み権限として3つの権限を付与する。

  • AWSLambdaKinesisExecutionRole

    AWSLambdaBasicExecutionRoleに加えて、Kinesis Streamsアクションへのアクセス権限を付与する。

  • AWSLambdaDynamoDBExecutionRole

    AWSLambdaBasicExecutionRoleに加えて、DynamoDBアクションへのアクセス権限を付与する。

  • AWSLambdaVPCAccessExecutionRole

    AWSLambdaBasicExecutionRoleに加えて、ENI(Elastic Network Interface)を管理するEC2アクションへのアクセス権限を付与する。

    Lambda関数からVPCにアクセスしたい時に用いる。

Lambdaの実行ロールは、Lambda関数を作成・登録する際に一緒に作ることもできる。(IAMユーザにiam:CreateRole権限が必要)

Lambdaのランタイム

Lambdaのランタイムは、隔離されたLinux実行環境(Linuxコンテン環境)である。

「Amazon Linuxベースのもの」と「Amazon Linux2ベースのもの」があり、利用する言語やバージョンによって異なる。

一般的なLinuxと同様に環境変数や一時ディスク領域なども利用できるほか、動的なパブリックIPも割り当てられているためインターネットとの通信も可能。

実行環境に対してやらなければならない3つのこと。

  1. 利用できるメモリ容量を決める

    割り当てたメモリが多いほど単価が高くなる。

    ただし、メモリを割り当てた分だけ処理能力(vCPU)も合わせて向上する。

  2. タイムアウトを決める

    タイムアウトの設定時間の分だけ課金されるわけではない。

    しかし、不具合などでタイムアウト設定値まで動き続ける可能性があるため、適度な時間に設定するのが望ましい。

  3. Lambda関数を実行するIAMロールを決める

ランタイムの情報は、Lambda関数が呼び出される時のcontext引数から取得できる。

context引数は、Contextオブジェクトとして構成されており、Lambda関数名や割り当てられたメモリ、実行可能残時間などの環境情報が含まれている。

同時実行

Lambda関数はイベントの数だけ同時実行される。

しかし、同時実行数には上限があり、1つのAWSアカウントに対して1リージョンあたり1,000個(全Lambda関数)である。

それを超えるとLambda関数の実行は失敗し、CloudWatchのスロットルとして記録される。

失敗と言っても、呼び出しはキューイングされるため、一定時間後に再実行される。

Lambdaは関数ごとに同時実行数を予約できる。

プロビジョニング

Lambda関数は初回実行時にランタイム準備があるのでその分時間がかかる。

ランタイム準備の時間を省き、即座に実行するためにプロビジョニングという機能がある。

プロビジョニングする場合は、Lambda関数を実行していなくてもプロビジョニングしている間、課金が発生する。

プロビジョニングは、Lambda関数ではなく、エイリアスやバージョニングに対して設定する。

イベントモデル

Lambda関数の呼び出しには、プッシュモデルとストリームベースの2種類ある。

ストリームベースは、「DynamoDBデータストリーム」「Amazon Kinesisデータストリーム」「Amazon MQ」「SQS」など限られたものだけである。

  • プッシュモデル

    イベントソースがLambda関数を呼び出すモデル。

    同期呼び出しと非同期呼び出しの2種類ある。

    • 同期呼び出し

      実行が終わるまで呼び出し元に戻らない。

      実行完了するとLambda関数の戻り値が呼び出し元に渡される。

      同時実行制限を超えた場合は、再試行されずエラーを返す。

    • 非同期呼び出し

      イベントはキューに送信され、実行完了を待たずに呼び出し元に戻る。

      Lambda関数の戻り値は破棄される。

      同時実行制限を超えた場合は、少しずつ実行を遅らせながら最大6時間、再試行される。

      すべての試行に失敗した時、そのイベントは消失する。

      しかし、DLQ(Dead Letter Queue)という仕組みを使えば、すべての試行に失敗した時に、そのイベントをあらかじめ作成しておいた「SQSのキュー」に溜めたり、「SNSトピック」として通知したりできる。

  • ストリームベース

    Lambda関数側がイベントソースを流れるデータ(ストリーム)をポーリング(監視)してデータを拾ってくるモデル。

    処理が失敗した場合は、ストリームの有効期間の間はずっと再試行を続ける。

    エラーが解決するまでストリーム処理はブロックされ、ストリームから新たなデータを受信しない。そうすることでストリームに届いたデータを順に処理するという確実性を確保する。

プッシュモデルでは、イベントソースがLambda関数を実行するので、イベントソース側にLambda関数の実行権限が必要である。

ストリームモデルでは、Lambda関数がDynamoDBやKinesisをポーリングするため、Lambda関数側にDynamoDBやKinesisのアクセス権限が必要である。

バージョニングとエイリアス

関数ARN(Amazon Resource Name)

Lambda関数を登録すると関数ARNという唯一無二の名前が定められる。

arn:aws:lambda:リージョンコード:アカウントID:function:関数名

イベントに対して呼び出すLambda関数を結び付ける場合、この関数ARNを使うのが基本。

バージョニング

関数ARNはバージョニングに対応しており、バージョン付けして切り替えて利用できる。

新しいバージョンを発行すると現在の環境のスナップショットが作られ、スナップショットに対して連番のバージョン番号が付与される。

バージョン付けしたとき、それぞれのバージョンの関数ARNは後ろに「:バージョン番号」を付けたものになる。

バージョンのうち編集可能なものは最新版だけである。

エイリアスARN

エイリアスARNは、特定バージョンの関数ARNへのショートカットである。

arn:aws:lambda:リージョンコード:アカウントID:function:関数名:エイリアス名

イベントとLambda関数を結び付ける際にエイリアスと結び付ければ開発版や本番などを容易に切り替えられる。

加重エイリアス

エイリアスに対して2つのバージョンを割り当て、「片方を90%」「もう片方を10%」のように重み付けして割り当てる方法。

本番リリースの際に更新版を一気に適用するのではなく、呼び出しの一部だけ新しいバージョンにして、様子を見たい場合などに使える。

Lambdaのネットワーク

Lambda関数の実行環境にはパブリックはIPアドレスが割り当てられており、そのままではVPC上のEC2インスタンスやRDSインスタンスと通信することができない。

Lambda関数のネットワーク有効化オプションをオンにし、VPC内と通信できるように設定すればできる。

設定では、どのVPCのどのサブネットと通信するのかを設定する。

また、セキュリティグループを設定することで、どのような通信をできるかも設定できる。

AWSのおいてサブネットは、アベイラビリティゾーンと呼ばれるデータセンターの場所を示す概念と結び付けられている。サブネットを選ぶということは、どのデータセンターで動かすのかを決めることであり、異なるアベイラビリティゾーンに結び付いた複数のサブネットを選ぶことは、冗長性を高める効果がある。

セキュリティグループは、VPC上で各インスタンスが通信するネットワークインターフェース(ENI)に対してパケットフィルタリングを設定する機能である。

Lambda関数のネットワーク有効化オプションをオンにすると、VPC上にENI(Elastic Network Interface)が作られ、Lambda環境上の「VPC to VPC NAT」と呼ばれる装置を経由して通信できるようになる。

ENIは複数のLambda実行環境で共有されるため消費されるIPアドレスは一つだけ。

ENIはVPCに接続する際のNetwork Interfaceであり、EC2インスタンスやRDSインスタンスなどVPCと接続して通信するインスタンスはすべてENIを備えており、このENIに対してIPアドレスが割り当てられている。

参考

AWS Lambda実践ガイド 第2版

@ryichk
wanna be a good hacker.