AWS Lambda から Python で RDS (OracleDB) へ接続する (cx_Oracle 編)

AWS Lambda から cx_Oracle という Python モジュールを使用して RDS(OracleDB) へ接続してみたので、その手順をまとめました。

Lambda から Python で RDS (OracleDB) へ接続する (cx_Oracle 編)

Lambda 関数から cx_Oracle を利用するための Lambda レイヤーを作成します。
cx_Oracle のドキュメントでは以下のように記載しています。

Introduction to cx_Oracle — cx_Oracle 8.3.0 documentation

Python programs call cx_Oracle functions. Internally cx_Oracle dynamically loads Oracle Client libraries to access OracleDB.
...
On Linux, the libaio (sometimes called libaio1) package is needed.

上記の記述のように、cx_Oracle は内部的に Oracle Client libraries を動的にロードして、Oracle データベースにアクセスまた、libaio(libaio1) パッケージも必要です。
そのため、Lambda レイヤーには cx_OracleOracle Client librarieslibaio(libaio1) を含める必要があります。

Lambda から Python で RDS (OracleDB) へ cx_Oracle を使って接続する手順

前提条件

  • 動作確認環境
    • Lambda Runtime: Python3.7, Python3.8, Python3.9
    • RDS(OracleDB): Oracle 19.0.0.0.ru-2021-07.rur-2021-07.r1
  • 作業環境
    • EC2 (Amazon Linux2)
      • Python 3.7 と libaio1 がすでにインストールされているためお勧めです。
  • cx_Oracle 8.3
  • Oracle Client libraries 19.13

作業ディレクトリの作成

~
Copied!
mkdir ~/oracle_layer
cd ~/oracle_layer
mkdir python/ lib/

cx_Oracle モジュールのインストール

pip コマンドに -t オプションを指定して python ディレクトリに cx_Oracle モジュールをインストールします。

~/oracle_layer
Copied!
pip install cx_Oracle -t python/

Oracle Client libraries のインストール

Oracle Client libraries をダウンロードして lib ディレクトリに展開します。
Oracle Client libraries はここからダウンロードします。

~/oracle_layer
Copied!
wget https://download.oracle.com/otn_software/linux/instantclient/1913000/instantclient-basic-linux.x64-19.13.0.0.0dbru.zip -O oracle_client_lib.zip
unzip -j oracle_client_lib.zip -d lib/

libaio1 を lib ディレクトリにコピーする

~/oracle_layer
Copied!
cp /lib64/libaio.so.1 lib/libaio.so.1

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

~/oracle_layer
Copied!
zip -r -y layer.zip python/ lib/

lib ディレクトリ内の Oracle Client libraries は一部のファイルがシンボリックリンクです。
シンボリックリンクのまま格納する必要があるため、-y オプションを忘れずに。
-y オプションの替わりに --symlinks オプションでもいいです。

Lambda レイヤーの作成

Lambda レイヤーの作成パターンその 1: デプロイパッケージを S3 にアップロードしてそれを使用する

~/oracle_layer
Copied!
aws s3 cp oracle_layer.zip s3://lambda_layer/oracle_layer.zip
aws lambda publish-layer-version \
    --layer-name cx_Oracle \
    --description "cx_Oracle layer" \
    --content S3Bucket=lambda_layer,S3Key=oracle_layer.zip \
    --compatible-runtimes python3.7 python3.8 python3.9

Lambda レイヤーの作成パターンその 2: ローカルにあるデプロイパッケージを使用する

~/oracle_layer
Copied!
aws lambda publish-layer-version \
    --layer-name cx_Oracle \
    --description "cx_Oracle layer" \
    --zip-file fileb://oracle_layer.zip \
    --compatible-runtimes python3.7 python3.8 python3.9

接続確認

作成した Lambda レイヤーを使用する Lambda 関数を作成し、テスト実行して接続確認してみます。
特にエラーが発生しなければ成功です。

Copied!
import cx_Oracle

def lambda_handler(event, context):
    connection = cx_Oracle.connect(<username>, <password>, <hostname>)

参考文献