1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【入門】AWS Lambda から RDS(PostgreSQL)に接続する方法:VPC構成・Layer作成まで解説

Posted at

はじめに

AWS Lambda と RDS(PostgreSQL)を組み合わせると、サーバレスでデータベース操作が可能なバックエンドを構築できます。本記事では、VPC 内のプライベートサブネットに配置した RDS に Lambda から接続し、Node.js を使って SQL を実行するまでの手順を解説します。

特に以下のポイントを重点的に紹介します:

  • VPC、サブネット、NATゲートウェイの設定

  • RDS(PostgreSQL)の作成とサブネットグループ設定

  • Lambda 関数の VPC 配置とセキュリティグループ設定

  • Lambda レイヤーを利用した Node.js モジュールの管理

  • Lambda から RDS への安全な接続方法

開発環境を前提に、テスト用に最小限の構成で動作確認まで行う手順をまとめています。

手順

1.VPCなどの作成

スクリーンショット 2025-11-08 194205.png

VPCなどを選択することで、必要なサブネットなどを自動で作成してくれます。
IPv4 CIDRブロックは他のリソースと競合するのを避けるため、デフォルト(10.0.0.0/16)ではなく、変更しておきましょう。
スクリーンショット 2025-11-08 194343.png

今回、Lambdaがインターネットアクセスできるようにしたいので、NATゲートウェイを作成します。
スクリーンショット 2025-11-08 194429.png

これでしばらく待つと作成されます。

2. DBの作成(RDS)

サブネットグループを作成する
https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_4185481_2e4f98a6-93f1-46ca-830e-29aaeadcdbeb.png

VPCは項1で作成したものを選択する。
サブネットには、項1で作成されたPrivateサブネットを2つ選択する。
https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_4185481_7c0ddc74-2aed-4956-8ad8-0df6162cea69.png

これでサブネットグループの作成は完了。

DBを作成する。
https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_4185481_f3e41993-eb41-4458-a9c0-c94441a37d52.png

エンジンタイプはPostgreSQLにしました。(必要に応じて選択してください)
スクリーンショット 2025-11-08 201759.png

テスト用なので無料利用枠にします。
本番用を選択すると、障害に備えて複数インスタンスを立ててスタンバイを用意するなどして、めちゃくちゃリッチな構成になります。一時間で2$以上の激高になるので気を付けてください。
スクリーンショット 2025-11-08 202004.png

セルフマネージドを選択して、パスワードを設定します。
Secrets Manager を選択すると、DBのユーザ名・パスワードなどを安全に保管・自動ローテーションしてくれます。
スクリーンショット 2025-11-08 202120.png

項1で作成したVPCを選択、サブネットグループは先ほど作成したものを選択する。
セキュリティグループを作成しておく。
https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_4185481_fa98087c-ded8-47d5-ba0a-8182cf664d0e.png

追加設定でDB名を指定して、初期DBを作成しておきましょう。
スクリーンショット 2025-11-08 202422.png

これで作成する。
スクリーンショット 2025-11-08 202539.png

ちょっと待つと利用可能になります。
image.png

補足:
AWS Secrets Manager

目的は「認証情報を安全に管理・自動更新すること」

例えば RDS のユーザー名・パスワードを Secrets Manager に登録しておくと、

  • Lambda や ECS から安全に取得できる(IAM認証ベースでアクセス制御)
  • RDSのパスワードを自動ローテーション(再生成+DB反映)できる
  • 暗号化はKMS連携で自動化
  • アプリ側でパスワードをハードコードせずに済み、セキュリティと運用効率が大幅に向上

3. Lambda関数の作成

まず、Lambdaに適用するセキュリティグループを作成します。
https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_4185481_c26dcba0-3c90-4dec-bc7d-bf2844037329.png

項1で作成したVPCを選択する。
アウトバウンドルールで(0.0.0.0/0)を追加。(インターネットアクセスを許可するため)
また、項2でRDSに割り当てたセキュリティグループも追加する。
https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_4185481_c08cd1a7-094b-4ddd-8111-7c5c9afac678.png

Lambda関数を作成します。
スクリーンショット 2025-10-31 011109.png

関数名を入力して作成
ランタイムはnode.jsにします。バックエンドをpythonにしたければ、pythonを選択してください。
スクリーンショット 2025-11-08 204821.png

その他の構成からVPCを有効化し、項1で作成したVPCを選択する。
サブネットにはPrivateサブネットを2つ選択し、セキュリティグループは先ほど作成したものを選択する。
https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_4185481_50ef47d1-1676-455b-8275-b7df34c52bec.png

これで作成されます。

以下は、中身の説明です。

ディレクトリ構成

testFunction/
├── index.mjs       # Lambdaのエントリーポイント(handler)
└── db.mjs          # DB接続やSQL実行ロジックを定義

以下、サンプルコードです。

Lambda 関数のメイン処理

index.mjs
import { query } from "./db.mjs"

export const handler = async (event) => {
  try {
    // テストイベントで SQL を指定
    const sql = event.sql || "SELECT NOW()";
    const params = event.params || [];

    // RDS にクエリ実行
    const res = await query(sql, params);

    return {
      statusCode: 200,
      body: JSON.stringify(res.rows),
    };
  } catch (err) {
    console.error(err);
    return {
      statusCode: 500,
      body: JSON.stringify({ error: err.message }),
    };
  }
};

DB接続ロジック

db.mjs
import { createRequire } from "module";
const require = createRequire(import.meta.url);

const pg = require("pg");
const { Pool } = pg;

const pool = new Pool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  port: process.env.DB_PORT || 5432,
  ssl: { rejectUnauthorized: false },
});

export async function query(text, params) {
  const client = await pool.connect();
  try {
    const res = await client.query(text, params);
    return res;
  } finally {
    client.release();
  }
}

ssl: { rejectUnauthorized: false } は RDS の証明書を信頼するための設定です(開発環境では安全です)。
本番では ACM 証明書を利用した HTTPS 経由で安全に接続します。

Lambda環境変数の設定

スクリーンショット 2025-10-31 014140.png

DBの接続情報を設定します。
スクリーンショット 2025-11-08 211342.png

DB_HOST: エンドポイントを設定(RDSの接続とセキュリティから確認できます)
DB_PORT: ポート番号を設定(RDSの接続とセキュリティから確認できます)
DB_USER: 項2でRDS作成時に指定した名称(デフォルト postgres)
DB_PASSWORD: 項2でRDS作成時に指定したパスワード
DB_NAME: 項2の追加設定で決めた任意のDB名

Lambdaレイヤーの作成

下記、ローカル作業

mkdir pg-layer

Dockerfileを作成
pg-layer配下に配置

# Lambda公式 Node.js 22 実行環境イメージ
FROM public.ecr.aws/lambda/nodejs:22

# zip コマンドをインストール
RUN microdnf install -y zip && microdnf clean all

# Layerフォルダ作成
RUN mkdir -p /opt/nodejs
WORKDIR /opt/nodejs

# pg ライブラリをインストール
RUN npm init -y && npm install pg

# ZIP化
WORKDIR /opt
RUN zip -r /layer.zip nodejs
cd pg-layer
wsl  
## コンテナのビルド
sudo docker build -t lambda-layer .
## コンテナ内で作成された Lambda Layer(/layer.zip)をローカル環境にコピー
sudo docker run --rm -v $(pwd):/out --entrypoint /bin/bash lambda-layer -c "cp /layer.zip /out/"

コマンドの補足:

  • --entrypoint /bin/bash の役割
    Lambda の公式 Node.js イメージ(public.ecr.aws/lambda/nodejs:22)には、
    デフォルトで Lambda 実行用のエントリーポイントが設定されています。
    つまり、何も指定せずにコンテナを実行すると、
    Node.js の Lambda ランタイムとして起動してしまい、
    シェル操作や cp コマンドが使えません。
    そのため、上記のように --entrypoint /bin/bash を指定し、一時的にエントリーポイントを Bash に差し替えています。

ホスト側にzipファイルが作成されるので、これを基にLambda Layerを作成する。

スクリーンショット 2025-11-09 050709.png

こうして作成したLambda Layerを作成したLambda関数に追加する。
コードタブの一番下にある
スクリーンショット 2025-11-09 050847.png

何回か失敗してしまったので、画像はバージョン6を選択していますが、1しかないと思います。
スクリーンショット 2025-11-09 050925.png

4. RDSのインバウンドルール設定

https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_4185481_30537698-c54f-4110-b7ba-68bb1be6f21e.png

Lambdaに割り当てているセキュリティグループを選択します。
これで、RDSがLambdaからの通信を受け取れるようになります。

ちなみに伏せている部分は自分のグローバルIPアドレスです。
RDS作成時デフォルトで自身のIPアドレスからのアクセス許可が設定されます。
しかし、今回はPrivateサブネットに配置しているため、自身のIPアドレスからも直接接続することはできません。
https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_4185481_f2a0a8cc-fe0b-47ec-a3a5-fe60384bfc1f.png

5. 動作確認

スクリーンショット 2025-11-09 051549.png
イベントJSON

{
  "sql": "SELECT NOW()"
}

レスポンス
image.png

このように現在時刻が返ってきたら成功です。
おつかれさまでした!

最後に

本記事では、AWS 上で Lambda からプライベートサブネット内の RDS(PostgreSQL)に接続する方法を紹介しました。
操作が多くて結構内容が散らかってしまった気がします。もっと色々書きたい内容ありましたが、今回はやめておきます。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?