AWSに戻る

AWS Lambda

AWS Lambdaとは

AWS Lambdaは、サーバーのプロビジョニングや管理を行うことなくコードを実行できるサーバーレスコンピューティングサービスです。必要に応じてコードを実行し、自動的にスケーリングするため、使用したコンピューティング時間に対してのみ料金が発生します。Lambdaを使用することで、ほぼすべてのタイプのアプリケーションやバックエンドサービスのコードを、管理不要で実行できます。コードをアップロードするだけで、高可用性を備えたLambdaが必要なすべてのコンピューティングリソースの実行、スケーリング、管理を行います。

AWS Lambdaの主な特徴

AWS Lambdaの仕組み

AWS Lambdaの基本的な仕組みは以下の通りです:

  1. 開発者がLambda関数としてコードをアップロード
  2. トリガーとなるイベントソースを設定(例:S3バケットへのファイルアップロード、APIリクエスト、スケジュールなど)
  3. イベントが発生すると、Lambdaサービスが自動的に関数を実行
  4. Lambdaは必要なリソースをプロビジョニングし、コードを実行
  5. 実行が完了すると、リソースは解放され、使用した分だけ課金される

Lambda実行モデル

Lambdaは「コールドスタート」と「ウォームスタート」の2つの実行モデルを持ちます:

プロビジョンドコンカレンシーを使用すると、コールドスタートを回避し、常に一定数の実行環境をウォーム状態に保つことができます。

AWS Lambdaの設定オプション

Lambda関数には以下の主要な設定オプションがあります:

設定項目 説明 制限/デフォルト
メモリ 関数に割り当てるメモリ量 128MB〜10,240MB(1MBごとに設定可能)
タイムアウト 関数の最大実行時間 最大900秒(15分)
同時実行数 同時に実行できる関数インスタンスの数 アカウントあたりのデフォルト制限は1,000
環境変数 関数のランタイム環境に設定する変数 最大4KB
IAMロール 関数が他のAWSサービスにアクセスするための権限 実行ロールとして設定
VPC設定 関数をVPC内のリソースにアクセスさせるための設定 サブネットとセキュリティグループを指定
レイヤー ライブラリ、カスタムランタイム、その他の依存関係を含む追加コード 最大5つのレイヤーを追加可能
デッドレターキュー 処理に失敗したイベントの送信先 SQSキューまたはSNSトピックを指定

AWS Lambdaのトリガー

Lambda関数は様々なイベントソースによってトリガーできます:

AWS Lambdaの使用方法

Lambda関数は、AWS Management Console、AWS CLI、AWS SDKs、またはインフラストラクチャ as コード(IaC)ツールを使用して作成および管理できます。

Lambda関数の作成

AWS CLIを使用したLambda関数の作成

# デプロイパッケージの作成
zip function.zip index.js

# Lambda関数の作成
aws lambda create-function \
    --function-name my-function \
    --runtime nodejs14.x \
    --role arn:aws:iam::123456789012:role/lambda-role \
    --handler index.handler \
    --zip-file fileb://function.zip

環境変数を設定したLambda関数の作成

aws lambda create-function \
    --function-name my-function \
    --runtime nodejs14.x \
    --role arn:aws:iam::123456789012:role/lambda-role \
    --handler index.handler \
    --zip-file fileb://function.zip \
    --environment "Variables={DB_HOST=mydb.example.com,DB_USER=admin}"

Lambda関数の呼び出し

AWS CLIを使用したLambda関数の呼び出し

aws lambda invoke \
    --function-name my-function \
    --payload '{"key1": "value1", "key2": "value2"}' \
    response.json

非同期呼び出し

aws lambda invoke \
    --function-name my-function \
    --invocation-type Event \
    --payload '{"key1": "value1", "key2": "value2"}' \
    response.json

Lambda関数の更新

関数コードの更新

# 新しいデプロイパッケージの作成
zip function-updated.zip index.js

# 関数コードの更新
aws lambda update-function-code \
    --function-name my-function \
    --zip-file fileb://function-updated.zip

関数設定の更新

aws lambda update-function-configuration \
    --function-name my-function \
    --timeout 30 \
    --memory-size 256

Lambda関数の例

Node.jsのシンプルなLambda関数

// index.js
exports.handler = async (event) => {
    console.log('Event: ', JSON.stringify(event, null, 2));
    
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    
    return response;
};

S3イベントを処理するPython Lambda関数

# lambda_function.py
import json
import boto3
from datetime import datetime

s3_client = boto3.client('s3')

def lambda_handler(event, context):
    # イベントからバケット名とオブジェクトキーを取得
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']
    
    # オブジェクトのメタデータを取得
    try:
        response = s3_client.head_object(Bucket=bucket, Key=key)
        object_size = response['ContentLength']
        last_modified = response['LastModified'].strftime('%Y-%m-%d %H:%M:%S')
        
        print(f"Object {key} was uploaded to {bucket}")
        print(f"Size: {object_size} bytes")
        print(f"Last Modified: {last_modified}")
        
        return {
            'statusCode': 200,
            'body': json.dumps({
                'bucket': bucket,
                'key': key,
                'size': object_size,
                'last_modified': last_modified
            })
        }
    except Exception as e:
        print(f"Error: {str(e)}")
        return {
            'statusCode': 500,
            'body': json.dumps({
                'error': str(e)
            })
        }

AWS Lambdaの高度な機能

レイヤー

Lambdaレイヤーは、ライブラリ、カスタムランタイム、またはその他の依存関係を含む.zipアーカイブです。レイヤーを使用すると、デプロイパッケージのサイズを小さく保ち、コードの共有と分離が可能になります。

レイヤーの作成と使用

# レイヤーの作成
aws lambda publish-layer-version \
    --layer-name my-layer \
    --description "My dependencies layer" \
    --license-info "MIT" \
    --zip-file fileb://layer.zip \
    --compatible-runtimes nodejs14.x

# レイヤーを関数に追加
aws lambda update-function-configuration \
    --function-name my-function \
    --layers arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1

プロビジョンドコンカレンシー

プロビジョンドコンカレンシーは、関数のインスタンスを事前に初期化し、コールドスタートのレイテンシーを排除します。これにより、関数が常に高速に応答できるようになります。

プロビジョンドコンカレンシーの設定

aws lambda put-provisioned-concurrency-config \
    --function-name my-function \
    --qualifier prod \
    --provisioned-concurrent-executions 10

関数URLエンドポイント

関数URLは、Lambda関数に専用のHTTPSエンドポイントを提供します。API Gatewayを使用せずに、HTTPリクエストを直接Lambda関数に送信できます。

関数URLの作成

aws lambda create-function-url-config \
    --function-name my-function \
    --auth-type NONE

Lambda@Edge

Lambda@Edgeを使用すると、CloudFrontのエッジロケーションでLambda関数を実行できます。これにより、ユーザーに近い場所でコードを実行し、レイテンシーを低減できます。

Lambda@Edge関数の例

exports.handler = async (event) => {
    const request = event.Records[0].cf.request;
    
    // リクエストヘッダーにカスタムヘッダーを追加
    request.headers['x-custom-header'] = [{ 
        key: 'X-Custom-Header', 
        value: 'Custom Value' 
    }];
    
    return request;
};

AWS Lambdaのセキュリティ

Lambda関数のセキュリティを確保するためのベストプラクティス:

IAMロールの設定

Lambda実行ロールの作成

# 信頼ポリシーの作成
cat > trust-policy.json << EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

# ロールの作成
aws iam create-role \
    --role-name lambda-s3-role \
    --assume-role-policy-document file://trust-policy.json

# ポリシーのアタッチ
aws iam attach-role-policy \
    --role-name lambda-s3-role \
    --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

# 基本的なLambda実行ポリシーのアタッチ
aws iam attach-role-policy \
    --role-name lambda-s3-role \
    --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

AWS Lambdaのモニタリングと可観測性

Lambda関数のパフォーマンスと動作を監視するためのツール:

Amazon CloudWatch

CloudWatchは、Lambda関数のメトリクス(呼び出し回数、エラー、レイテンシーなど)を収集し、アラームを設定して自動アクションをトリガーすることができます。

CloudWatchアラームの作成

aws cloudwatch put-metric-alarm \
    --alarm-name lambda-errors \
    --comparison-operator GreaterThanThreshold \
    --evaluation-periods 1 \
    --metric-name Errors \
    --namespace AWS/Lambda \
    --period 60 \
    --statistic Sum \
    --threshold 0 \
    --alarm-actions arn:aws:sns:us-east-1:123456789012:my-topic \
    --dimensions "Name=FunctionName,Value=my-function"

AWS X-Ray

X-Rayを使用すると、Lambda関数のトレースデータを収集し、アプリケーションのパフォーマンスの問題を特定できます。

X-Rayトレースの有効化

aws lambda update-function-configuration \
    --function-name my-function \
    --tracing-config Mode=Active

Node.jsでのX-Ray SDKの使用

const AWSXRay = require('aws-xray-sdk-core');
const AWS = AWSXRay.captureAWS(require('aws-sdk'));

exports.handler = async (event) => {
    // X-Rayセグメントの作成
    const segment = AWSXRay.getSegment();
    const subsegment = segment.addNewSubsegment('my-subsegment');
    
    try {
        // 処理を実行
        const s3 = new AWS.S3();
        const result = await s3.listBuckets().promise();
        
        subsegment.addAnnotation('BucketCount', result.Buckets.length);
        subsegment.close();
        
        return {
            statusCode: 200,
            body: JSON.stringify(result)
        };
    } catch (error) {
        subsegment.addError(error);
        subsegment.close();
        throw error;
    }
};

Amazon CloudWatch Logs

Lambda関数のログは自動的にCloudWatch Logsに送信されます。これらのログを分析して、関数の動作を理解し、問題をトラブルシューティングできます。

CloudWatch Logsのクエリ

aws logs start-query \
    --log-group-name /aws/lambda/my-function \
    --start-time 1636329600 \
    --end-time 1636416000 \
    --query-string "fields @timestamp, @message | filter @message like /ERROR/"

AWS Lambdaのユースケース

Lambdaは以下のようなユースケースに適しています:

AWS Lambdaとの統合サービス

Lambdaは他のAWSサービスと統合して、より強力なソリューションを構築できます:

サービス 統合の利点
Amazon API Gateway RESTful APIやWebSocket APIを作成し、Lambda関数をバックエンドとして使用
Amazon S3 オブジェクトの作成、削除などのイベントに応じてLambda関数を実行
Amazon DynamoDB テーブルの更新イベントに応じてLambda関数を実行
Amazon Kinesis ストリーミングデータの処理にLambda関数を使用
Amazon SNS 通知の処理にLambda関数を使用
Amazon SQS キューからのメッセージ処理にLambda関数を使用
Amazon EventBridge スケジュールされたイベントやパターンマッチングイベントに応じてLambda関数を実行
AWS Step Functions 複雑なワークフローの一部としてLambda関数を実行

API Gatewayとの統合例

API GatewayとLambdaの統合

# Lambda関数の作成
aws lambda create-function \
    --function-name api-backend \
    --runtime nodejs14.x \
    --role arn:aws:iam::123456789012:role/lambda-api-role \
    --handler index.handler \
    --zip-file fileb://function.zip

# REST APIの作成
aws apigateway create-rest-api \
    --name my-api

# リソースとメソッドの作成
aws apigateway create-resource \
    --rest-api-id abcdef123 \
    --parent-id root-resource-id \
    --path-part items

aws apigateway put-method \
    --rest-api-id abcdef123 \
    --resource-id resource-id \
    --http-method GET \
    --authorization-type NONE

# Lambda関数との統合
aws apigateway put-integration \
    --rest-api-id abcdef123 \
    --resource-id resource-id \
    --http-method GET \
    --type AWS_PROXY \
    --integration-http-method POST \
    --uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:api-backend/invocations

AWS Lambdaのベストプラクティス

コールドスタートの最適化

コールドスタートを最小限に抑えるためのテクニック:

まとめ

AWS Lambdaは、サーバーのプロビジョニングや管理を行うことなくコードを実行できるサーバーレスコンピューティングサービスです。イベント駆動型のアーキテクチャに最適で、自動スケーリングと従量課金制の特性を持ちます。

Lambdaの主な利点は以下の通りです:

Lambdaを効果的に活用するには、関数の適切な設計、コールドスタートの最適化、適切なモニタリングの設定、セキュリティベストプラクティスの適用が重要です。また、他のAWSサービスと組み合わせることで、スケーラブルで耐障害性のあるサーバーレスアプリケーションを構築することができます。