🤖

RDS(Aurora Serverless v2)にLambdaでアクセスしてみる

2023/12/16に公開

やること

RDS(Aurora Serverless v2)にLambdaでアクセスできるかの検証メモです。

構成図

この構成で検証しました。

    • Cloud9とRDS接続の設定はこの記事では省略
    • VPC Lambdaを作成
    • RDSプロキシ使用せず

手順概要

  • (1)Aurora Servless v2のRDSを作る
  • (2)テーブルを作り、レコードを追加する
    • ※Cloud9環境で実施
    • (2-1)セットアップ
    • (2-2)DBにアクセス
    • (2-3)テーブル作成とレコード登録
    • (2-4)UPDATEできるか確認
    • (2-5)PythonスクリプトでDBアクセス
  • (3)Lambdaレイヤーの作成
    • ※Cloud9環境で実施
    • (3ー1)ファイル構成
    • (3ー2)各ファイルの内容
    • (3ー3)Lambdaレイヤー用のZIPファイル作成
  • (4)Lambda関数(Python3.11)を作る
    • (4ー1)Lambda関数の作成
    • (4ー2)Lambdaレイヤーを付与する
    • (4ー3)RDSデータベース接続する
    • (4ー4)IAMロールのポリシー見直す
    • (4ー5)スクリプトを更新する
  • (5)Lambdaの動作確認

(1)Aurora Servless v2のRDSを作る

以下パラメータで作りました。(作る手順省略)

DB クラスター識別子 aurora-serverless-2
マスターユーザー名 postgres
マスターパスワード 123asdzxc
データベース名 db01
エンドポイント名 aurora-serverless-2.cluster-xxx.ap-northeast-1.rds.amazonaws.com

(2)テーブルを作りレコードを追加

Cloud9(ubuntu)からDBにアクセスし、テーブルの作成と、レコードの追加をします。

(2-1)セットアップ

Cluod9環境にDB(Postgres)アクセスに必要なモジュールをインストールします。

sudo apt update
sudo apt install postgresql postgresql-contrib

(2-2)DBにアクセス

DBにアクセスします。(WARNINGはスルーします)

iamusr0001:~/environment $ psql -h aurora-serverless-2.cluster-xxx.ap-northeast-1.rds.amazonaws.com -U postgres -d db01
Password for user postgres: 
psql (14.10 (Ubuntu 14.10-0ubuntu0.22.04.1), server 15.3)
WARNING: psql major version 14, server major version 15.
         Some psql features might not work.
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

db01=> 

(2-3)テーブル作成とレコード登録

テーブル hoge を作成します。

CREATE TABLE hoge (
    id SERIAL PRIMARY KEY,
    test VARCHAR(255)
);

テーブル hoge にデータを登録します。

INSERT INTO hoge (id, test) VALUES (1, '123');

テーブル作成とデータ登録を確認します。

db01=> select * from hoge;
 id | test 
----+------
  1 | 123
(1 row)

db01=> 

(2-4)UPDATEできるか確認

UPDATEできるか確認します。

UPDATE hoge SET test = '456' WHERE id = 1;

UPDATEして値が更新されたことを確認しました。

db01=> UPDATE hoge SET test = '456' WHERE id = 1;
UPDATE 1
db01=> select * from hoge;
 id | test 
----+------
  1 | 456
(1 row)

db01=> 

(2-5)PythonスクリプトでDBアクセス

Cloud9からPythonスクリプトでDBアクセスしてクエリ実行できるか確認します。
事前に pip install psycopg2-binary で必要モジュールのインストールが必要です。

import psycopg2
# pip install psycopg2-binary
import os

db_name = "db01"
db_user = "postgres"
db_pass = "123asdzxc"
db_host = "aurora-serverless-2.cluster-xxx.ap-northeast-1.rds.amazonaws.com"

def lambda_handler():
    conn = psycopg2.connect(
        dbname=db_name,
        user=db_user,
        password=db_pass,
        host=db_host
    )

    # UPDATE実行
    cur = conn.cursor()
    # SELECT文実行
    cur.execute('SELECT * FROM hoge')
    rows = cur.fetchall()

    cur.close()
    conn.close()

    return rows

result = lambda_handler()
print(result)

実行すると、ちゃんとDBの中身が表示されました。

iamusr0001:~/environment $ python aurora-access.py 
[(1, '456')]

(3)Lambdaレイヤーの作成

Lambdaでimport psycopg2をエラーなく実行するためにはモジュールが必要。そのため必要モジュールをLambdaレイヤーで用意します。

Lambdaレイヤーを作るためにDBアクセスのLambda(Python)と同じPythonバージョン 3.11 を用意する必要があります。今回はDockerを使ってCloud9環境にPythonバージョン 3.11 環境を作ります。

(3ー1)ファイル構成

用意したファイルは以下です。workは空のディレクトリです。空ですが必要なので作成必須です。

iamusr0001:~/environment/db-access-test $ tree
.
├── Dockerfile_python311
├── dockerbuild-run.sh
├── dockerstop-imgdell.sh
└── work

1 directory, 3 files

(3ー2)各ファイルの内容

Python 3.11 環境のDockerfileです。(boto3はインストール不要かも)

Dockerfile_python311
ARG python_image_v="python:3.11-buster"
FROM ${python_image_v}

ARG work_dir="/work/"
# コンテナにアクセスした際のデフォルトディレクトリ
WORKDIR ${work_dir}

# pip更新
RUN pip install --upgrade pip

# boto3インストール
RUN pip install boto3

# zipインストール
RUN apt-get update && apt-get install -y zip

Dockerイメージのビルドと実行を行い、更にコンテナに入りカレントディレクトリがworkになるシェルスクリプトです。

dockerbuild-run.sh
#!/bin/bash

# Dockerイメージを作る
docker build -f Dockerfile_python311 -t python311_img .

# Dockerコンテナを作成し起動する
docker run --rm --name python311_env -v $PWD/work/:/work/ -dit python311_img

# Dockerコンテナに入る
docker exec -it python311_env bash

Dokerコンテナの停止とDockerイメージの削除を行うシェルスクリプトです。

dockerstop-imgdell.sh
#!/bin/bash

# Dockerコンテナを停止する
docker stop python311_env

# Dockerイメージを削除する
docker image rm python311_img

(3ー3)Lambdaレイヤー用のZIPファイル作成

Dockerコンテナを実行しLambdaレイヤー用のZIPファイルを作成します。以下は、Lambdaレイヤー用のZIPファイル作成するコマンドだけを抜粋したものです。

mkdir python
pip install psycopg2-binary -t ./python
zip -r psycopg2_layer.zip python

Dockerコンテナを起動しZIPファイルpsycopg2_layer.zipを作成したときの実行ログです。

iamusr0001:~/environment/db-access-test $ ./dockerbuild-run.sh 
[+] Building 0.7s (9/9) FINISHED                                                                                                                                                                        docker:default
 => [internal] load build definition from Dockerfile_python311                                                                                                                                                    0.0s
  <略>
root@1ba9323d160d:/work# python --version
Python 3.11.4
root@1ba9323d160d:/work# mkdir python
root@1ba9323d160d:/work# pip install psycopg2-binary -t ./python
  <略>
root@1ba9323d160d:/work# zip -r psycopg2_layer.zip python
  adding: python/ (stored 0%)
  <略>
root@1ba9323d160d:/work# ls
psycopg2_layer.zip  python

Dockerコンテナを停止し、以下のコマンドでZIPファイルpsycopg2_layer.zipでLambdaレイヤーpython311-psycopg2-layerを作成します。

aws lambda publish-layer-version --layer-name python311-psycopg2-layer --zip-file fileb://python311_psycopg2_layer.zip

(4)Lambda関数(Python3.11)を作る

(4ー1)Lambda関数の作成

Lambda関数を作ります。VPCやDB接続などは作成後にやっていくので、まずは以下でLambdaを作ります。

一から作成
関数名 aurora-access-test
ランタイム Python 3.11
アクセス権 基本的な Lambda アクセス権限で新しいロールを作成
アーキテクチャ x86_64

※タイムアウト3秒が短ければ見直します。

(4ー2)Lambdaレイヤーを付与する

作成したLambdaaurora-access-testにLambdaレイヤーを設定します。

(4ー3)RDSデータベース接続する

LambdaをRDS(Aurora Serverless v2)に接続します。
Lambdaaurora-access-test設定タブのRDSデータベースRDSデータベースに接続ボタンでDB接続します。

今回は、RDSプロキシを使いませんでした。

DBの接続ができました。

(4ー4)IAMロールのポリシー見直す

Lambda作成時に作られたIAMロールには必要な権限が足りてないので足します。今回は横着してAdmin権限を追加しました。

(4ー5)スクリプトを更新する

以下のDBアクセスのスクリプトです。これは、Cloud9で実行したPythonスクリプトとほぼ同じです。セキュリティを考えて、DB情報(db_nameなど)は、環境変数にした方が良さそうです。

Lambda関数
import psycopg2
import os

db_name = "db01"
db_user = "postgres"
db_pass = "123asdzxc"
db_host = "aurora-serverless-2.cluster-xxx.ap-northeast-1.rds.amazonaws.com"

def lambda_handler(event, context):
    conn = psycopg2.connect(
        dbname=db_name,
        user=db_user,
        password=db_pass,
        host=db_host
    )

    # UPDATE実行
    cur = conn.cursor()
    # SELECT文実行
    cur.execute('SELECT * FROM hoge')
    result = cur.fetchall()
    
    print(result)

    cur.close()
    conn.close()

    return result

(5)Lambdaの動作確認

Lambda実行結果、テーブルhogeのレコード[(1, '456')]が表示されました(期待した挙動)

Test Event Name
test

Response
[
  [
    1,
    "456"
  ]
]

Function Logs
START RequestId: 00000000-3580-47d2-9c9e-999999999999 Version: $LATEST
[(1, '456')]
END RequestId: 00000000-3580-47d2-9c9e-999999999999
REPORT RequestId: 00000000-3580-47d2-9c9e-999999999999	Duration: 431.03 ms	Billed Duration: 432 ms	Memory Size: 128 MB	Max Memory Used: 48 MB	Init Duration: 159.99 ms

Request ID
00000000-3580-47d2-9c9e-999999999999

Cloud9からDB接続しレコード情報を変更UPDATE hoge SET test = '999' WHERE id = 1した後に、Lambdaを実行すると、テーブルhogeのレコード[(1, '999')]が表示されました(期待した挙動)

Test Event Name
test

Response
[
  [
    1,
    "999"
  ]
]

Function Logs
START RequestId: 11111111-a348-4019-bf39-999999999999 Version: $LATEST
[(1, '999')]
END RequestId: 11111111-a348-4019-bf39-999999999999
REPORT RequestId: 11111111-a348-4019-bf39-999999999999	Duration: 423.70 ms	Billed Duration: 424 ms	Memory Size: 128 MB	Max Memory Used: 49 MB	Init Duration: 164.33 ms

Request ID
11111111-a348-4019-bf39-999999999999

※テスト実行後のLambdaの画面はこんな感じです。


とりあえずDBアクセスまではできました。

UPDATEについて

検証してないかけどSELECTでなくUPDATEを実行する場合は以下のようにするといけるかも(?)

# UPDATEクエリの実行
update_query = "UPDATE your_table SET your_column = 'new_value' WHERE condition"
cur.execute(update_query)

# 変更をコミット
conn.commit()

Discussion