はじめに
みなさんこんにちは!「API Gateway・Lambda・AuroraでAPIを作成してみた」というテーマのもと、作成方法を複数回に分けてご紹介しております。前回こちらの記事では、データベースの認証情報はLambda関数のコード上にハードコーディングされていましたので、今回はSecrets Manager経由で認証情報を取得する方法についてご紹介します。
目次
- 全体編
- VPC・サブネット・セキュリティグループ編
- Aurora編
- CloudShell編
- Lambda編
- Secrets Manager編 << 今回はこちら
- API Gateway編
本記事の対象
全体の構成図に対して、本記事では赤字で記載しているLambda関数からVPCエンドポイントを経由してSecrets Managerの認証情報を取得する部分を作成していきます。
作成の流れ
以下の流れで実施していきます。
- VPCエンドポイント用セキュリティグループの作成
- VPCエンドポイントの作成
- VPCエンドポイントポリシーの更新
- Lambda用セキュリティグループの更新
- Lambda実行ロールの更新
- Lambda関数のコード更新
前提として以下が必要となります。詳細は目次のリンクよりご確認ください。
- VPC・サブネット・セキュリティグループの作成
- Auroraの作成
- Auroraへデータの格納
- Lambda関数の作成
実際に作成してみた
VPCエンドポイント用セキュリティグループの作成
新しくVPCエンドポイント用のセキュリティグループを作成し、インバウンド/アウトバウンドルールの設定を行います。
インバウンド
設定項目 | ルール |
---|---|
タイプ | HTTPS |
プロトコル | TCP |
ポート範囲 | 443 |
リソースタイプ | カスタム |
ソース | Lambda用セキュリティグループ |
アウトバウンド
- ルールなし
VPCエンドポイントの作成
VPCエンドポイントを作成します。詳細は以下スクリーンショットよりご確認ください。
VPCエンドポイントポリシーの更新
VPCエンドポイントの作成ではフルアクセスのポリシーで作成しておりましたので、ポリシーを以下のように設定します。アカウントIDやVPCエンドポイントのリソースIDは適宜修正ください。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EnableSecretsManagerpermissions",
"Effect": "Allow",
"Principal": {
"AWS": [
"アカウントID"
]
},
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "*"
},
{
"Sid": "RestrictGetSecretValueoperation",
"Effect": "Deny",
"Principal": "*",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": "VPCエンドポイントのリソースID"
}
}
}
]
}
Lambda用セキュリティグループの更新
LambdaがVPCエンドポイントと疎通ができるように、Lambda用セキュリティグループのアウトバウンドルールの設定を行います。
アウトバウンド
設定項目 | ルール |
---|---|
タイプ | HTTPS |
プロトコル | TCP |
ポート | 443 |
送信先タイプ | カスタム |
送信先 | VPCエンドポイント用セキュリティグループ |
Lambda実行ロールの更新
Lambda関数がSecrets Managerでシークレットを取得できるようにLambda実行ロールを以下順序で更新します。詳細はスクリーンショットを確認ください。
- [設定]->[アクセス権限]より実行ロールを選択
- 実行ロールの[許可]->[ポリシーをアタッチ]を選択
- 許可ポリシーに「SecretsManagerReadWrite」を追加
Lambda関数のコード更新
更新後のコードは以下になります。「RDS Proxyのエンドポイント」「Secrets Managerの名前」「リージョン名」は適宜修正ください。更新点としては以下になります。
- Secrets Managerからシークレットを取得する「get_secrets()」関数の追加
- 「get_secrets()」関数で使用する変数の追加
- 「get_secrets()」関数の呼び出し
import pymysql
import json
+ import boto3
HOST = "RDS Proxyのエンドポイント"
DB_NAME = "dev"
- DB_USER_NAME = "データベースのユーザ名"
- DB_PASSWORD = "パスワード"
+ SECRET_NAME="Secrets Managerの名前"
+ REGION_NAME="リージョン名"
def lambda_handler(event, context):
+ # データベースの認証情報を取得
+ secrets = get_secrets()
+ DB_USER_NAME = secrets["username"]
+ DB_PASSWORD = secrets["password"]
# データベースへ接続
conn = pymysql.connect(
host=HOST,
user=DB_USER_NAME,
password=DB_PASSWORD,
database=DB_NAME,
cursorclass=pymysql.cursors.DictCursor
)
try:
# SQLクエリ実行・結果取得
with conn.cursor() as cur:
cur.execute('SELECT * FROM book')
results = cur.fetchall()
return {
'statusCode': 200,
'body': results
}
except Exception as e:
# エラーハンドリング
return{
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
finally:
# 接続を閉じる
conn.close()
+ def get_secrets():
+ # Secrets Managerクライアントの作成
+ session = boto3.session.Session()
+ client = session.client(
+ service_name='secretsmanager',
+ region_name=REGION_NAME
+ )
+ try:
+ secrets = client.get_secret_value(SecretId=SECRET_NAME)
+ except Exception as e:
+ raise e
+ return json.loads(secrets["SecretString"])
終わりに
いかがだったでしょうか。今回はLambda関数からVPCエンドポイントを経由してSecrets Managerの認証情報を取得する方法についてご紹介しました。次回はついに最終回であるAPI Gateway編についてご紹介します。是非、次回以降もご覧いただけますと幸いです。もしこの記事がお役に立ちましたら、「いいね」「記事のストック」をお願いします!
- AWS は、米国その他の諸国における Amazon.com, Inc. またはその関連会社の商標です。
- その他、記載されている会社名および商品・製品・サービス名は、各社の商標または登録商標です。