AWS LambdaでRDSのスナップショットをS3に自動エクスポートする方法

## 導入

**AWS Lambda** を使って、Amazon RDSのスナップショットを自動で作成し、**Amazon S3** にエクスポートする処理を自動化する方法について解説します。

この仕組みを使えば、定期的にバックアップを取り、それをS3に保存することで長期的な保管や分析基盤への連携が可能になります。



## この記事でできること

* 指定のRDSインスタンスの状態を確認
* 手動スナップショットを1日以上前のものだけ自動削除
* 新しいスナップショットを作成
* スナップショットが完了するまで待機
* スナップショットをS3にエクスポート



## 事前準備

1. **S3バケット**の作成（例: `my-rds-backup-bucket`）
2. **KMSキー**の作成（エクスポート時に暗号化が必要）
3. **IAMロール**の作成と適切なポリシー付与（LambdaがRDS・S3・KMSを操作できるようにする）
4. **Lambda関数**の作成（Pythonランタイムを選択）



## Lambda関数のコード

以下のコードを使って、RDSスナップショットの自動バックアップを実装します：

```python
import boto3
from datetime import datetime as dt

def lambda_handler(event, context):
    rds_client = boto3.client('rds')
    
    # 環境変数やIAMのポリシーに合わせて適宜変更してください
    s3_bucket_name = "my-rds-backup-bucket"
    s3_prefix = "rds-snapshots/"
    kms_key_arn = "arn:aws:kms:ap-northeast-1:111122223333:key/your-kms-key-id"
    iam_role_arn = "arn:aws:iam::111122223333:role/lambda-rds-s3-export-role"
    db_instance_identifier = "sample-rds-instance"
    
    snapshot_identifier = f"{db_instance_identifier}-snapshot-{dt.now().strftime('%Y%m%d%H%M%S')}"
    now = dt.now()

    try:
        print("🔍 RDSインスタンスの状態を確認中...")
        instance_info = rds_client.describe_db_instances(DBInstanceIdentifier=db_instance_identifier)
        instance_status = instance_info['DBInstances'][0]['DBInstanceStatus']
        
        if instance_status != 'available':
            print(f"❗ インスタンスが利用可能ではありません: {instance_status}")
            return {
                'statusCode': 400,
                'body': f"Instance is not in available state: {instance_status}"
            }

        print("🧹 古い手動スナップショットを削除中...")
        snapshots = rds_client.describe_db_snapshots(DBInstanceIdentifier=db_instance_identifier)
        for snapshot in snapshots['DBSnapshots']:
            if snapshot['SnapshotType'] == 'manual':
                creation_time = snapshot['SnapshotCreateTime']
                if (now - creation_time.replace(tzinfo=None)).days > 1:
                    snapshot_id = snapshot['DBSnapshotIdentifier']
                    print(f"🗑️ 古いスナップショットを削除: {snapshot_id}")
                    rds_client.delete_db_snapshot(DBSnapshotIdentifier=snapshot_id)

        print(f"📸 新しいスナップショットを作成中: {snapshot_identifier}")
        rds_client.create_db_snapshot(
            DBSnapshotIdentifier=snapshot_identifier,
            DBInstanceIdentifier=db_instance_identifier
        )

        print("⏳ スナップショットの完了を待機中...")
        waiter = rds_client.get_waiter('db_snapshot_available')
        waiter.wait(
            DBSnapshotIdentifier=snapshot_identifier,
            DBInstanceIdentifier=db_instance_identifier
        )
        print(f"✅ スナップショット作成完了: {snapshot_identifier}")

        export_identifier = f"{snapshot_identifier}-export"
        print(f"🚚 S3にスナップショットをエクスポート: {s3_bucket_name}")
        rds_client.start_export_task(
            ExportTaskIdentifier=export_identifier,
            SourceArn=f"arn:aws:rds:ap-northeast-1:111122223333:snapshot:{snapshot_identifier}",
            S3BucketName=s3_bucket_name,
            IamRoleArn=iam_role_arn,
            KmsKeyId=kms_key_arn,
            S3Prefix=s3_prefix
        )

        print("🎉 エクスポート処理を開始しました！")
        return {
            'statusCode': 200,
            'body': f"Snapshot {snapshot_identifier} successfully exported to S3."
        }

    except Exception as e:
        print(f"❌ エラーが発生しました: {str(e)}")
        return {
            'statusCode': 500,
            'body': f"Error: {str(e)}"
        }
```



## 処理の流れ

1. **RDSの状態チェック**
   インスタンスが `available` 状態かどうかを確認します。

2. **古いスナップショットの削除**
   1日以上前の手動スナップショットを削除します（管理の簡略化のため）。

3. **新規スナップショット作成**
   現在時刻を含む識別子でスナップショットを作成。

4. **スナップショットの状態を監視**
   完了するまで `waiter` を使って待機します。

5. **S3へのエクスポート**
   IAMロールとKMSキーを使って暗号化された状態でエクスポートします。


## まとめ

このLambda関数をスケジュール実行（例: 毎日0時）に設定すれば、**完全自動のRDSバックアップ＆S3エクスポート機構**が構築できます。

インフラの信頼性を高めるためにも、ぜひ一度自動化してみてください。


## 参考リンク

* [RDS スナップショットを S3 にエクスポートする方法 (AWS公式)](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ExportSnapshot.html)
* [Lambda IAMロールの設定方法](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)