今回の課題
下記の記事を参考にしながら、EC2にてRDSを連携させたRailsのアプリを動かすことができたため、
今回は、AWS Lambdaを使用して、RDS内のデータのスナップショットをS3に定期的にエクスポートする機能を作る。
S3にエクスポートしたデータは、今後Snowflakeにしたいと考えている。
RDSスナップショットをS3にエクスポートする機能を実装していく
実装手順
1)S3にてバケットを作成
RDSのスナップショットをエクスポートするためのS3バケットを作成しておく。
2)RDSのスナップショットを作成
DBスナップショットの取得
ページの、
DBインスタンス
でスナップショットを取得したいRDS内のDBを指定し、
スナップショット名
でDBスナップショットの識別子を指定しておく。
※DBスナップショットの識別子は、スナップショットを復元する時などに使用するもので、今回の記事では使用しない。
3)RDSスナップショットをS3にエクスポートするために必要なポリシー&ロールの作成
3)-1.ポリシーの作成
RDSがエクスポート先のS3にアクセスしてエクスポートできるようにするためのポリシーを作成しておく。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:PutObject*",
"s3:GetObject*",
"s3:DeleteObject*"
],
"Resource": [
"arn:aws:s3:::[エクスポート先のバケット名]",
"arn:aws:s3:::[エクスポート先のバケット名]/*"
]
}
]
}
3)-2.ロールの作成
ロールの作成画面にて、
信頼されたエンティティタイプをAWSのサービス
に指定し、
ユースケースはRDS - Add Role to Database
に指定して次へ
をクリック。
次のページで3)-1で作成したポリシーを選択して、ロールの作成を完了する。
3)-3.作成したロールの信頼関係
を書き換える
ロールの編集画面に飛び、信頼関係の編集
タブをクリックし、
信頼ポリシーを編集
をクリックして下記に書き換える。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "export.rds.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
これで、RDSスナップショットをS3にエクスポートするための権限の準備が完了した。
4)KMSの作成
KMSのページのカスタマー管理型のキー
を選択し、デフォルトの設定でKMSを作成する。
ここで作成したキーは、Lambdaを作成後に使用する。
5)Lambdaの作成
5)-1.関数の作成を行う
Lambdaのページから関数の作成
をクリックして下記のページに飛び、
ランタイムはPython 3.9
を選択し、
実行ロールは基本的なLambdaアクセス権限で新しいロールを作成
を選択して関数の作成を実施する。
5)-2.ポリシーとロールを作成
5)-1で基本的なLambdaアクセス権限で新しいロールを作成
を選択したので、
AWSLambdaBasicExecutionRole-********-****-****-****-************
というポリシー名を所持した[関数名]role-********
というロール名で、新しいロールが作成されている。
そこで、下記のポリシーを別途作成し、
上記のLambda作成時に同時に作成した[関数名]role-********
というロールにアタッチする。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:PassRole",
"rds:StartExportTask"
],
"Resource": "*"
}
]
}
5)-3.Lambdaコードを作成
RDSスナップショットをS3にエクスポートするためのコードを作成する。
import json
import boto3
from datetime import datetime
SOURCE_ARN="arn:aws:rds:ca-central-1:************:snapshot:rails-ec2-rds" # エクスポート対象とするRDSスナップショットのARN
S3_BUCKET_NAME="snowflake-data-practice" # 出力先のS3バケット名
IAM_ROLE_ARN="arn:aws:iam::************:role/RDSToS3_export" # S3にエクスポートする際に使用するロールのARN
KMS_KEY_ID="arn:aws:kms:ca:central-1:************:key/********-****-****-****-**********" # 作成したKMSキーのARN
client = boto3.client('rds')
def lambda_handler(event, context):
export_task_identifier="mysnapshot" + datetime.now().strftime("%Y%m%d%H%M%S")
response = client.start_export_task(
ExportTaskIdentifier=export_task_identifier,
SourceArn=SOURCE_ARN,
S3BucketName=S3_BUCKET_NAME,
IamRoleArn=IAM_ROLE_ARN,
KmsKeyId=KMS_KEY_ID,
)
6)KMSのキーユーザーにLambdaのロールを追加
5)-2で作成したLambdaのロールを、4)で作成したKMSのキーユーザー
に追加する。
※Lambda実行時にAn error occurred (KMSKeyNotAccessibleFault)
というエラーが発生するのを防ぐため
7)定期実行されるように設定する
ここまでで、Lambdaを実行することでRDSスナップショットがS3にエクスポートされる仕組みを実装することができた。
最後に、RDSスナップショットがS3に定期的にエクスポートされるように設定を行う。
まずは、5)で作成したLambdaの関数のページに進み、トリガーを追加
をクリックする。
トリガーにEventBridge(CloudWatch Events)
を選択して、
スケジュール式を選択すれば、指定した時間おきにRDSスナップショットがS3にエクスポートされるようになる。
参考記事
まとめ
以上のように進めることで、
RDSのスナップショットをLambdaを使ってS3に定期的にエクスポートする仕組みを構築することができた。
おまけ
LambdaのPythonコードを理解する
Lambdaで実行したPythonコードに、どういったことが書かれているかしっかり理解するために調べてみた。
特に下記の部分が理解不足だった。
client = boto3.client('rds')
def lambda_handler(event, context):
export_task_identifier="mysnapshot" + datetime.now().strftime("%Y%m%d%H%M%S")
response = client.start_export_task(
ExportTaskIdentifier=export_task_identifier,
SourceArn=SOURCE_ARN,
S3BucketName=S3_BUCKET_NAME,
IamRoleArn=IAM_ROLE_ARN,
KmsKeyId=KMS_KEY_ID,
)
1)RDSにアクセスできるようにする
client = boto3.client('rds')
2)S3にエクスポートされた際のファイル名を設定しておく
export_task_identifier="mysnapshot" + datetime.now().strftime("%Y%m%d%H%M%S")
この場合、mysnapshot[現在日時]
と命名される。
3)Lambdaが実行されたときに呼び出すコードを設定しておく
Lambdaが実行されたときに、下記の関数が呼び出される。
def lambda_handler(event, context):
4)RDSスナップショットをS3にエクスポートするための設定を行う
start_export_task
内で、エクスポート元やエクスポート先やエクスポート字のファイル名などを設定する。
response = client.start_export_task(
ExportTaskIdentifier=export_task_identifier, # S3にエクスポート時のファイル名を指定
SourceArn=SOURCE_ARN, # RDSスナップショットを指定
S3BucketName=S3_BUCKET_NAME, # エクスポート先のS3バケット名を指定
IamRoleArn=IAM_ROLE_ARN, # S3をエクスポートするために使用するロールを指定
KmsKeyId=KMS_KEY_ID, # KMSキーを指定
)