概要
未認証ユーザーの自動削除を実現するため、AWS Lambda と EventBridge を活用して定期的に RDS データベースから未認証ユーザーを削除する仕組みを構築しました。
この記事では技術スタック、全体の手順、作業の流れを整理し、特につまずいたポイントを詳細に説明します。
とっかかりは下記の記事を参照しています。
技術スタック
- AWS Lambda: サーバーレス環境でコードを実行。
- Amazon RDS: ユーザーデータを格納するデータベース。
- Secrets Manager: データベース認証情報を安全に管理。
- EventBridge: 定期実行をスケジュール。
- VPC & セキュリティグループ: Lambda と RDS 間の安全な通信を実現。
- Node.js: Lambda 関数の実装言語。
作業の流れ
1. Secrets Manager にシークレットを作成
- 手順: RDS の認証情報 (username, password) を保存。
- ポイント: Secrets Manager に保存した ARN をメモしておく。
-
例:
{ "username": "admin", "password": "yourpassword", "host": "your-db-host.amazonaws.com", "dbname": "yourdbname" }
2. Lambda 関数を作成
-
コード例:
const AWS = require('aws-sdk'); const mysql = require('mysql2/promise'); const getDatabaseCredentials = async () => { const secretsManager = new AWS.SecretsManager({ region: 'ap-northeast-1' }); const secretValue = await secretsManager.getSecretValue({ SecretId: 'your-secret-id' }).promise(); return JSON.parse(secretValue.SecretString); }; exports.handler = async () => { try { const credentials = await getDatabaseCredentials(); const { username, password, host, dbname } = credentials; const connection = await mysql.createConnection({ host, user: username, password, database: dbname, port: 3306, }); const query = ` DELETE FROM users WHERE confirmed_at IS NULL AND confirmation_sent_at < NOW() - INTERVAL 1 DAY; `; const [result] = await connection.execute(query); console.log(`${result.affectedRows} unconfirmed users deleted.`); await connection.end(); } catch (err) { console.error('Error:', err); } };
3. Lambda に IAM ロールをアタッチ
-
必要なポリシー:
{ "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:your-secret-id" }
4. VPC とセキュリティグループの設定
- Lambda 関数が VPC 内の RDS にアクセスできるよう、以下を設定。
- VPC エンドポイント: Secrets Manager へのアクセスを可能にする。
-
セキュリティグループ:
- Lambda と RDS 間の通信 (ポート 3306) を許可。
- Lambda 同士の HTTPS 通信 (ポート 443) を許可。
5. EventBridge でスケジュール設定
-
手順: EventBridge ルールを作成して、
cron(0 16 * * ? *)
形式で毎日実行をスケジュール。 - Lambda 関数にトリガーとして EventBridge を紐付け。
6. テスト実行とログ監視
- CloudWatch Logs を活用して、エラーがないことを確認。
つまずいたポイントと解決策
1. Secrets Manager の ARN 問題
-
現象: Lambda 関数が
AccessDeniedException
を出力。シークレット ARN に-V3ptOS
が付与されている場合とそうでない場合で不整合が発生。 - 原因: シークレット ARN を完全指定する必要があることに気付かず、トリミングされた ARN を利用。
-
解決策:
-V3ptOS
を含めた完全な ARN をポリシーに指定。
2. VPC エンドポイントの設定漏れ
- 現象: Lambda から Secrets Manager への接続がタイムアウト。
- 原因: VPC 内の Lambda がパブリックインターネット経由で Secrets Manager にアクセスしようとして失敗。
- 解決策: VPC エンドポイントを作成し、プライベートネットワーク内で通信。
3. セキュリティグループの設定不足
-
現象: RDS への接続エラー (
ECONNREFUSED
)。 - 原因: Lambda に紐付けたセキュリティグループが RDS のセキュリティグループに通信を許可していなかった。
-
解決策:
- Lambda のセキュリティグループに、RDS のセキュリティグループへの MySQL ポート (3306) 通信を許可。
4. トリガーのスケジュール式のミス
-
現象:
Parameter ScheduleExpression is not valid
エラー。 -
原因:
cron
式の形式ミス。 -
解決策: AWS ドキュメントに従い正しい形式 (
cron(0 16 * * ? *)
) を適用。
まとめ
本プロジェクトでは、未認証ユーザーの自動削除という一見シンプルなタスクにおいて、Secrets Manager、VPC エンドポイント、セキュリティグループ、IAM ポリシーといった AWS の複数のサービスを正しく設定する必要がありました。
特に以下の点が重要です:
- Secrets Manager ARN の正確な指定
- VPC エンドポイントを用いたプライベート通信
- セキュリティグループのルール設定の見直し
これらの問題を一つずつ解決し、無事にスケジュールされた Lambda 関数の運用が可能となりました。同様の実装を行う方は、設定の細部を丁寧に確認しながら進めてください。