【AWS】同一VPN内のLambdaからRDSへ接続を行う

# はじめに
Lambda関数からRDSデータベースへ接続を行う機会があり、
その際に実装を行った方法について、備忘録として記載します。

前提
　・RDSデータベースの作成・設定済みとする。
　・本記事では、下記の赤矢印①〜②の実装方法について記載する。
![lambda_rds_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1255237/a9374b91-aae1-77fd-6445-06bd8dffc75f.png)

# 目次
[1. Lambda関数の作成](https://qiita.com/drafts/d8bb6608d1343770b099/edit#1-lambda%E9%96%A2%E6%95%B0%E3%81%AE%E4%BD%9C%E6%88%90)
[2. Lambda関数のソースコード実装](https://qiita.com/drafts/d8bb6608d1343770b099/edit#2-lambda%E9%96%A2%E6%95%B0%E3%81%AE%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E5%AE%9F%E8%A3%85)
[3. IAMロールの設定](https://qiita.com/drafts/d8bb6608d1343770b099/edit#3-iam%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A)
[4. Lambda関数のVPC設定](https://qiita.com/drafts/d8bb6608d1343770b099/edit#3-lambda%E9%96%A2%E6%95%B0%E3%81%AEvpc%E8%A8%AD%E5%AE%9A)
[(おまけ)Lambda関数のテスト実行](https://qiita.com/drafts/d8bb6608d1343770b099/edit#%E3%81%8A%E3%81%BE%E3%81%91lambda%E9%96%A2%E6%95%B0%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E5%AE%9F%E8%A1%8C)

# 1. Lambda関数の作成
Lambda（関数）のコンソール画面から下記の設定値でLambda関数を作成する。

|設定項目|設定値|
|:---|:---|
|以下のいずれかのオプションを選択して、関数を作成します。|一から作成|
|関数名|任意の値|
|ランタイム|Python 3.8|
|アーキテクチャ|x86_64|
|実行ロール|基本的な Lambda アクセス権限で新しいロールを作成 ※|

※「3. IAMロールの設定」にて、自動作成されるIAMロールの設定を変更するため、ロール名をメモしておく。
![lambda_rds_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1255237/585ebece-207e-09d5-49aa-1d00f49479d6.png)

# 2. Lambda関数のソースコード実装
### 2-1. PyMySQLライブラリのインストール
※PyMySQL：データベース接続に使用するライブラリ
※PyMySQLライブラリのインストール手順は、下記のサイトを参考にしている。
https://teratail.com/questions/269811

ローカルPCのコマンドラインにて、下記の手順でLambda関数へアップロードするzipファイルを作成する。

```
# 作業用フォルダを作成
mkdir lambda
cd lambda

# 作業用フォルダ内にpymysqlをインストール
pip3 install pymysql -t .

# 空のlambda_function.pyを作成
vi lambda_function.py

# Lambda関数へアップロードするzipファイルを作成
zip -r app.zip *
```

### 2-2. zipファイル（PyMySQLライブラリ）のアップロード
1にて作成したLambda関数のコンソール画面にて、「アップロード元」プルダウンから2-1で作成したzipファイルをアップロードする。
![lambda_rds_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1255237/a9e93241-f3bf-6622-d2cf-f2d453d89374.png)

### 2-3. ソースコード実装
1にて作成したLambda関数のコンソール画面にて、下記の内容を参考にデータベース接続処理を実装する。

```python:lambda_function.py
import pymysql

def lambda_handler(event, context):
	try:
		# パラメータ設定
		rds_host = [接続するRDSのエンドポイント]
		db_name = [接続するデータベースのデータベース名]
		db_username = [接続するデータベースのユーザー名]
		db_password = [接続するデータベースのパスワード]
		
		# RDSデータベースへ接続
		conn = pymysql.connect(
	    	host = rds_host, 
	    	user = db_username, 
	    	passwd = db_password, 
	    	db = db_name, 
	    	connect_timeout = 5,
	    	cursorclass = pymysql.cursors.DictCursor)
	    
		with conn.cursor() as cur:
			# クエリ文作成
			sql_select = "select item"
			sql_from = " from " + db_name + ".t_table"
			sql_where = ""
			query = sql_select + sql_from + sql_where
			# クエリ文実行
			cur.execute(query)
			data = cur.fetchall()
			
		# 取得結果を返却
		return data
	    
	except Exception as e:
		# エラー
		print(e)
```

# 3. IAMロールの設定
デフォルトのIAMロールでは、VPCの設定権限がないため、権限設定を行う。

IAM（ロール）のコンソール画面にて、1で自動作成されたロールを選択する。
「ポリシーをアタッチします」ボタンを押下し、「**AWSLambdaVPCAccessExecutionRole**」ポリシーを追加する。

# 4. Lambda関数のVPC設定
1にて作成したLambda関数のコンソール画面にて、下記の設定値でVPCの設定を行う。
※保存ボタン押下後、VPCの設定変更に少し時間がかかる。
![lambda_rds_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1255237/189c58f0-0742-f8c8-18e2-99088a60fc93.png)

|設定項目|設定値|
|:---|:---|
|VPC|接続するRDSに設定しているVPC|
|サブネット|接続するRDSに設定しているサブネット|
|セキュリティグループ|接続するRDSに設定しているセキュリティグループ|

# (おまけ)Lambda関数のテスト実行
1にて作成したLambda関数のコンソール画面にて、正常にデータベース接続ができているかテスト実行することができる。

「テスト」タブにて、適当な名前を入力し、「変更を保存」→「テスト」ボタン押下でテスト実行する。
また、実行時にリクエストパラメータが必要な場合は、下部のテキスト入力欄に　キーと値をJSON形式で入力することで設定することができる。
![lambda_rds_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1255237/8c786595-2197-c1f7-c397-8a149e97a3b1.png)

# 参考
[AWSのlambdaからRDS（Aurora Mysql）に接続したい](https://teratail.com/questions/269811)
[RDS インスタンスに接続するように Lambda 関数を設定する方法を教えてください。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/connect-lambda-to-an-rds-instance/)
[チュートリアル: Amazon VPC の Amazon RDS にアクセスする Lambda 関数の設定](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/services-rds-tutorial.html)
[Lambda から RDS にアクセスする方法 (python)](https://qiita.com/aidy91614/items/92987d547c318e0483f5)