チュートリアル: Lambda 関数を使用して Amazon RDS にアクセスする - Amazon Relational Database Service

チュートリアル: Lambda 関数を使用して Amazon RDS にアクセスする

このチュートリアルでは、Lambda 関数を使用して、Amazon Relational Database Service (Amazon RDS) データベースに RDS プロキシ経由でデータを書き込みます。Lambda 関数は、メッセージが追加されるたびに Amazon Simple Queue Service (Amazon SQS) キューからレコードを読み取り、データベース内のテーブルに新しい項目を書き込みます。この例では、AWS Management Console を使用してキューにメッセージを手動で追加します。次の図は、チュートリアルを完了するために使用する AWS リソースを示しています。


      AWS Management Console のインスタンスは Amazon SQS 標準キューに接続し、このキューは Lambda 関数に接続し、それが RDS for MySQL データベースに RDS プロキシ経由で接続します。

Amazon RDS では、Microsoft SQL Server、MariaDB、MySQL、Oracle Database、PostgreSQL などの一般的なデータベース製品を使用して、マネージドリレーショナルデータベースをクラウドで実行できます。Lambda を使用してデータベースにアクセスすると、ウェブサイトに新規顧客を登録するなどのイベントに応じてデータを読み書きできます。関数、データベースインスタンス、およびプロキシは、需要の高い時期に合わせて自動的にスケーリングされます。

このチュートリアルを完了するには、次のタスクを実行します。

  1. RDS for MySQL データベースインスタンスとプロキシを AWS アカウント のデフォルト VPC で起動します。

  2. データベースに新しいテーブルを作成して、データを書き込む Lambda 関数を作成してテストします。

  3. Amazon SQS キューを作成して、新しいメッセージが追加されるたびに Lambda 関数を呼び出すように設定します。

  4. AWS Management Console を使用してキューにメッセージを追加し、CloudWatch ログで結果をモニタリングすることによって、セットアップ全体をテストします。

これらの手順を実行することで、次のことが理解できます。

  • Amazon RDS を使用してデータベースインスタンスとプロキシを作成し、Lambda 関数をプロキシに接続する方法。

  • Lambda を使用して Amazon RDS データベースでの作成および読み取りオペレーションを実行する方法。

  • Amazon SQS を使用して Lambda 関数を呼び出す方法。

AWS Management Console または AWS Command Line Interface(AWS CLI) を使って、このチュートリアルを完了できます。

前提条件

開始する前に、以下のセクションのステップを完了してください。

Amazon RDS DB インスタンスを作成する


        データベースを作成する段階にあることを示すチュートリアルのワークフロー図。

Amazon RDS DB インスタンスは、AWS クラウド で実行される分離されたデータベース環境です。インスタンスには、ユーザーが作成した 1 つ以上のデータベースを含めることができます。特に指定しない限り、Amazon RDS は、AWS アカウント に含まれるデフォルトの VPC に新しいデータベースインスタンスを作成します。Amazon VPC の詳細については、「Amazon Virtual Private Cloud ユーザーガイド」を参照してください。

このチュートリアルでは、AWS アカウントのデフォルト VPC に新しいインスタンスを作成し、そのインスタンスに ExampleDB という名前のデータベースを作成します。AWS Management Console または AWS CLI のいずれかを使用して、DB インスタンスとデータベースを作成できます。

データベースインスタンスを作成するには
  1. Amazon RDS コンソールを開き、[データベースの作成] を選択します。

  2. [標準作成] オプションを選択したままにし、[エンジンのオプション][MySQL] を選択します。

  3. [テンプレート] で、[無料利用枠] を選択します。

  4. [設定] で、[DB インスタンス識別子]MySQLForLambda を入力します。

  5. 以下を実行して、ユーザー名とパスワードを設定します。

    1. [認証情報の設定] で、[マスターユーザー名] の設定を admin のままにします。

    2. [マスターパスワード] には、データベースにアクセスするためのパスワードを入力して確認します。

  6. 次の操作を実行して、データベース名を指定します。

    • 残りのデフォルトオプションはすべて選択したままにして、[追加設定] セクションまで下にスクロールします。

    • このセクションを展開し、[最初のデータベース名] として ExampleDB を入力します。

  7. 残りのデフォルトオプションはすべて選択したままにして、[データベースの作成] を選択します。

Lambda 関数とプロキシを作成する


        Lambda 関数の手順で実行ロールを作成しているところを示すチュートリアルのワークフロー図。

RDS コンソールを使用して、データベースと同じ VPC に Lambda 関数とプロキシを作成できます。

注記

これらの関連リソースは、データベースの作成が完了し、[使用可能] ステータスのときにのみ作成できます。

関連する関数とプロキシを作成するには
  1. [データベース] ページから、データベースが [使用可能] ステータスかどうかを確認します。その場合は、次のステップに進みます。そうでない場合は、データベースが使用可能になるまで待ちます。

  2. データベースを選択し、[アクション] から [Lambda 接続をセットアップする] を選択します。

  3. [Lambda 接続をセットアップする] ページで、[新しい関数の作成] を選択します。

    [新しい Lambda 関数名] を LambdaFunctionWithRDS に設定します。

  4. [RDS プロキシ] セクションで、[RDS プロキシを使用して接続] オプションを選択します。さらに、[新しいプロキシの作成] を選択します。

    • [データベース認証情報] として、[データベースのユーザー名とパスワード] を選択します。

    • [ユーザー名] として、admin と指定します。

    • [パスワード] として、データベースインスタンスのために作成したパスワードを入力します。

  5. [セットアップ] を選択して、プロキシと Lambda 関数の作成を完了します。

ウィザードがセットアップを完了し、新しい関数を確認するための Lambda コンソールへのリンクが表示されます。Lambda コンソールに切り替える前に、プロキシエンドポイントをメモしておきます。

関数実行ロールを作成するには


        Lambda 関数の手順で実行ロールを作成しているところを示すチュートリアルのワークフロー図。

Lambda 関数を作成する前に、関数に必要なアクセス権限を与える実行ロールを作成します。このチュートリアルでは、Lambda 二は、データベースインスタンスを含んでいる VPC へのネットワーク接続を管理し、Amazon SQS キューからメッセージをポーリングするためのアクセス許可が必要です。

Lambda 関数に必要なアクセス権限を付与するために、このチュートリアルでは IAM 管理ポリシーを使用します。これらは多くの一般的なユースケースに許可を付与するポリシーであり、AWS アカウントで利用できます。管理ポリシーの使用の詳細については、「ポリシーのベストプラクティス」を参照してください。

Lambda 実行ロールを作成するには
  1. IAM コンソールの [ロール] ページを開いて、[ロールの作成] を選択します。

  2. [信頼されるエンティティタイプ] として、[AWS サービス] を選択し、[ユースケース] として [Lambda] を選択します。

  3. [次へ] をクリックします。

  4. 次の手順を実行して IAM 管理ポリシーを追加します。

    1. 検索ボックスで AWSLambdaSQSQueueExecutionRole を検索します。

    2. 結果リストで、ロールの横にあるチェックボックスを選択し、[フィルターをクリア] を選択します。

    3. 検索ボックスで AWSLambdaVPCAccessExecutionRole を検索します。

    4. 結果リストで、ロールの横にあるチェックボックスをオンにし、[次へ] を選択します。

  5. [ロール名] には、lambda-vpc-sqs-role を入力して [ロールの作成] を選択します。

このチュートリアルの後半で、先ほど作成した実行ロールの Amazon リソースネーム (ARN) が必要になります。

実行ロール ARN を確認するには
  1. IAM コンソールの [ロール] ページを開き、ロール (lambda-vpc-sqs-role) を選択します。

  2. [概要] セクションに表示されている [ARN] をコピーします。

Lambda デプロイパッケージを作成する


        Lambda 関数の手順で、デプロイパッケージを作成しているところを示すチュートリアルのワークフロー図

次の Python コードの例では、PyMySQL パッケージを使用してデータベースへの接続を開始します。関数を初めて呼び出すと、Customer という新しいテーブルも作成されます。このテーブルは次のスキーマを使用しており、ここで CustID はプライマリキーです。

Customer(CustID, Name)

また、この関数は PyMySQL を使用してこのテーブルにレコードを追加します。この関数は、Amazon SQS キューに追加するメッセージで指定された顧客 ID と名前を使用してレコードを追加します。

このコードは、ハンドラー関数の外部でデータベースへの接続を作成します。初期化コードで接続を作成すると、その後の関数の呼び出しで接続を再利用できるようになり、パフォーマンスが向上します。本番アプリケーションでは、プロビジョニングされた同時実行性を使用して、要求された数のデータベース接続を初期化することもできます。関数が呼び出されると、これらの接続はすぐに利用できます。

import sys import logging import pymysql import json import os # rds settings user_name = os.environ['USER_NAME'] password = os.environ['PASSWORD'] rds_proxy_host = os.environ['RDS_PROXY_HOST'] db_name = os.environ['DB_NAME'] logger = logging.getLogger() logger.setLevel(logging.INFO) # create the database connection outside of the handler to allow connections to be # re-used by subsequent function invocations. try: conn = pymysql.connect(host=rds_proxy_host, user=user_name, passwd=password, db=db_name, connect_timeout=5) except pymysql.MySQLError as e: logger.error("ERROR: Unexpected error: Could not connect to MySQL instance.") logger.error(e) sys.exit(1) logger.info("SUCCESS: Connection to RDS for MySQL instance succeeded") def lambda_handler(event, context): """ This function creates a new RDS database table and writes records to it """ message = event['Records'][0]['body'] data = json.loads(message) CustID = data['CustID'] Name = data['Name'] item_count = 0 sql_string = f"insert into Customer (CustID, Name) values({CustID}, '{Name}')" with conn.cursor() as cur: cur.execute("create table if not exists Customer ( CustID int NOT NULL, Name varchar(255) NOT NULL, PRIMARY KEY (CustID))") cur.execute(sql_string) conn.commit() cur.execute("select * from Customer") logger.info("The following items have been added to the database:") for row in cur: item_count += 1 logger.info(row) conn.commit() return "Added %d items to RDS for MySQL table" %(item_count)
注記

この例では、データベースアクセス認証情報は環境変数として保存されます。本番アプリケーションでは、より安全なオプションとして AWS Secrets Manager を使用することをお勧めします。Lambda 関数が VPC にある場合、Secrets Manager に接続するには VPC エンドポイントを作成する必要があります。詳細については、「仮想プライベートクラウド内で Secrets Manager サービスに接続する方法」を参照してください。

PyMySQL の依存関係を関数コードに含めるには、.zip デプロイパッケージを作成します。次のコマンドは、Linux、macOS、または Unix で動作します。

.zip デプロイパッケージを作成するには
  1. サンプルコードをファイル名 lambda_function.py で保存します。

  2. lambda_function.py ファイルを作成したのと同じディレクトリに、package という名前の新しいディレクトリを作成し、PyMySQL ライブラリをインストールします。

    mkdir package pip install --target package pymysql
  3. アプリケーションコードと PyMySQL ライブラリを含む zip ファイルを作成します。Linux または MacOS では、次の CLI コマンドを実行します。Windows では、任意の zip ツールを使用して、lambda_function.zip ファイルを作成します。lambda_function.py ソースコードファイルと依存関係を含むフォルダは、.zip ファイルのルートにインストールする必要があります。

    cd package zip -r ../lambda_function.zip . cd .. zip lambda_function.zip lambda_function.py

    また、Python 仮想環境を使用してデプロイパッケージを作成することもできます。「.zip ファイルアーカイブで Python Lambda 関数をデプロイする」を参照してください。

Lambda 関数を更新する

作成した.zip パッケージを使用して、Lambda コンソールで Lambda 関数を更新します。関数がデータベースにアクセスできるようにするには、アクセス認証情報を使用して環境変数を設定する必要もあります。

Lambda 関数を更新するには
  1. Lambda コンソールの [関数] ページを開き、関数 LambdaFunctionWithRDS を選択します。

  2. [ランタイム設定] タブで、[編集] を選択し、関数の [ランタイム][Python 3.10] に変更します。

  3. [ハンドラー] を lambda_function.lambda_handler に変更します。

  4. [コード] タブで、[アップロード元][.zip ファイル] の順に選択します。

  5. 前の段階で作成した lambda_function.zip ファイルを選択してから、[保存] を選択します。

ここで、以前に作成した実行ロールで関数を設定します。これにより、データベースインスタンスにアクセスして Amazon SQS キューをポーリングするために必要なアクセス権限が関数に付与されます。

関数の実行ロールを設定するには
  1. Lambda コンソールの [関数] ページで、[設定][アクセス権限] の順に選択します。

  2. [実行ロール] で、[編集] を選択します。

  3. [既存のロール] で、実行ロール (lambda-vpc-sqs-role) を選択します。

  4. [保存] を選択します。

関数の環境変数を設定するには
  1. Lambda コンソールの「関数」ページで、[Configuration] タブ、[Environment variables] の順に選択します。

  2. [Edit] (編集) を選択します。

  3. データベースアクセス認証情報を追加するには、以下を実行してください。

    1. [Add environment variable] を選択し、[Key] には USER_NAME[Value] には admin を入力します。

    2. [Add environment variable] を選択し、[Key] には DB_NAME[Value] には ExampleDB を入力します。

    3. [Add environment variable] を選択し、[Key] には PASSWORD[Value] にはデータベースの作成時に選択したパスワードを入力します。

    4. [環境変数の追加] を選択し、[キー] として RDS_PROXY_HOST を入力し、[値] として、先程メモした RDS プロキシのエンドポイントを入力します。

    5. [保存] を選択します。

コンソールで Lambda 関数をテストする


        Lambda 関数の手順で、関数をテストしていることを示すチュートリアルのワークフロー図

Lambda コンソールを使用して関数をテストできるようになりました。チュートリアルの最終段階で Amazon SQS を使用して関数を呼び出したときに、関数が受け取るデータを模倣するテストイベントを作成します。テストイベントには、関数が作成する Customer テーブルに追加する顧客 ID と顧客名を指定する JSON オブジェクトが含まれています。

Lambda 関数をテストする
  1. Lambda コンソールの [関数] ページを開き、関数を選択します。

  2. [テスト] セクションを選択します。

  3. [新しいイベントを作成] を選択し、イベント名として myTestEvent と入力します。

  4. 次のコードを [イベント JSON] にコピーし、[保存] を選択します。

    { "Records": [ { "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "body": "{\n \"CustID\": 1021,\n \"Name\": \"Martha Rivera\"\n}", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1545082649183", "SenderId": "AIDAIENQZJOLO23YVJ4VO", "ApproximateFirstReceiveTimestamp": "1545082649185" }, "messageAttributes": {}, "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "eventSource": "aws:sqs", "eventSourceARN": "arn:aws:sqs:us-west-2:123456789012:my-queue", "awsRegion": "us-west-2" } ] }
  5. [テスト] を選択します。

[実行結果] タブに、次の [関数ログ] に表示されているのと同様の結果が表示されます。

[INFO] 2023-02-14T19:31:35.149Z bdd06682-00c7-4d6f-9abb-89f4bbb4a27f The following items have been added to the database: [INFO] 2023-02-14T19:31:35.149Z bdd06682-00c7-4d6f-9abb-89f4bbb4a27f (1021, 'Martha Rivera')

Amazon SQS キュー を作成する


        メッセージキューの手順でキューを作成しているところを示すチュートリアルのワークフロー図。

Lambda 関数と Amazon RDS データベースインスタンスの統合が正常にテストされました。ここで、チュートリアルの最終段階で Lambda 関数を呼び出すために使用する Amazon SQS キューを作成します。

Amazon SQS を作成するには (コンソール)
  1. Amazon SQS コンソールの [キュー] ページを開き、[キューの作成] を選択します。

  2. [タイプ][標準] のままにし、キューの名前に LambdaRDSQueue と入力します。

  3. デフォルトオプションはすべて選択したままにして、[キューの作成] を選択します。

Lambda 関数を呼び出すためのイベントソースマッピングを作成する


        メッセージキューの手順でイベントソースマッピングを作成しているところを示すチュートリアルのワークフロー図。

イベントソースマッピングは、ストリームまたはキューからアイテムを読み取り、Lambda 関数を呼び出す Lambda リソースです。イベントソースマッピングを設定するときに、ストリームまたはキューからのレコードが 1 つのペイロードにまとめられるようにバッチサイズを指定できます。この例では、キューにメッセージを送信するたびに Lambda 関数が呼び出されるように、バッチサイズを 1 に設定します。イベントソースマッピングは、AWS CLI または Lambda コンソールを使用して設定できます。

イベントソースマッピングを作成するには (コンソール)
  1. Lambda コンソールの [関数] ページを開き、(LambdaFunctionWithRDS) 関数を選択します。

  2. [関数の概要] セクションで、[トリガーを追加] を選択します。

  3. ソースとして [Amazon SQS] を選択し、キューの名前 (LambdaRDSQueue) を選択します。

  4. [バッチサイズ] に、1 を入力します。

  5. 他のオプションはすべてデフォルト値のままにして、[追加] を選択します。

これで Amazon SQS キューにメッセージを追加して、セットアップ全体をテストする準備ができました。

セットアップのテストとモニタリング


        テストとモニタリングの段階にあることを示すチュートリアルのワークフロー図。

セットアップ全体をテストするには、コンソールを使用して Amazon SQS キューにメッセージを追加します。次に、CloudWatch Logs を使用して、Lambda 関数が予想どおりにレコードをデータベースに書き込んでいることを確認します。

セットアップをテストおよびモニタリングするには
  1. Amazon SQS コンソールの [キュー] ページを開き、キュー (LambdaRDSQueue) を選択します。

  2. [メッセージを送受信] を選択し、[メッセージの送信] セクションの [メッセージ本文] に次の JSON を貼り付けます。

    { "CustID": 1054, "Name": "Richard Roe" }
  3. [メッセージの送信] を選択します。

    メッセージをキューに送信すると、Lambda はイベントソースマッピングを通じて関数を呼び出します。Lambda が予想どおりに関数を呼び出したことを確認するには、CloudWatch Logs を使用して、関数が顧客名と ID をデータベーステーブルに書き込んだことを確認します。

  4. CloudWatch コンソールの [ロググループ] ページを開き、関数のロググループ (/aws/lambda/LambdaFunctionWithRDS) を選択します。

  5. [ログストリーム] セクションで、最新のログストリームを選択します。

    テーブルには、関数の呼び出しごとに 1 つずつ、合計 2 つの顧客レコードが含まれている必要があります。ログストリームには、次に似たメッセージが表示されます。

    [INFO] 2023-02-14T19:06:43.873Z 45368126-3eee-47f7-88ca-3086ae6d3a77 The following items have been added to the database: [INFO] 2023-02-14T19:06:43.873Z 45368126-3eee-47f7-88ca-3086ae6d3a77 (1021, 'Martha Rivera') [INFO] 2023-02-14T19:06:43.873Z 45368126-3eee-47f7-88ca-3086ae6d3a77 (1054, 'Richard Roe')

リソースのクリーンアップ

このチュートリアル用に作成したリソースは、保持しない場合は削除できます。使用しなくなった AWS リソースを削除することで、AWS アカウントに請求される料金が発生しないようにできます。

Lambda 関数を削除するには
  1. Lambda コンソールの関数ページを開きます。

  2. 作成した関数を選択します。

  3. [ Actions] で、[Delete ] を選択します。

  4. [削除] を選択します。

実行ロールを削除するには
  1. IAM コンソールのロールページを開きます。

  2. 作成した実行ロールを選択します。

  3. [ロールの削除] を選択します。

  4. [はい、削除します] を選択します。

MySQL DB インスタンスを削除するには
  1. Amazon RDS コンソールの [Databases] (データベース) ページを開きます。

  2. 作成したデータベースを選択します。

  3. [ Actions] で、[Delete ] を選択します。

  4. [Create final snapshot] (最終スナップショットの作成) のチェックボックスをオフにします。

  5. テキストボックスに「delete me」と入力します。

  6. [削除] を選択します。

Amazon SQS キューを削除するには
  1. AWS Management Console にサインインし、Amazon SQS コンソール (https://console.aws.amazon.com/sqs/) を開きます。

  2. 作成したキューを選択します。

  3. [削除] を選択します。

  4. テキストボックスに「delete」と入力します。

  5. [削除] を選択します。