はじめに
メトリクスを制する者はAWSを制する
特に意味はないです、それっぽいこと書いてみただけです...
改めまして、システム基盤開発室という部署に所属してる社員番号666です。
以前、検証用に準備したAWS環境で使用していないリソースをバシバシ停止させるLambdaコードを書いていました。ググれば似たようなことをされている方が多かったので積極的に公開はしていませんでしたがRDSの自動停止は余り似たような記事を見かけなかったので載せておきます。
使うものとか前提
- CloudWatchとRDSを操作可能なロール
Lambdaではお決まりのアレ AmazonCloudWatch, AmazonRDS
まぁーいつも通りお作法に法って初期化しといてくださいCloudWatch Events
rate(1 hour)とかで起動するのを前提にします
Lambdaコード
public Object handleRequest(ScheduledEvent event, Context context) { Date endDate = event.getTime().toDate(); Date startDate = new Date(endDate.getTime() - (1000 * 10800)); // 60seconds * 60 minutes * 3hours amazonRDS.describeDBInstances().getDBInstances().stream().filter(rds -> "available".equals(rds.getDBInstanceStatus())).forEach(new Consumer<DBInstance>() { @Override public void accept(DBInstance db) { GetMetricStatisticsResult getMetricStatisticsResult = amazonCloudWatch.getMetricStatistics(new GetMetricStatisticsRequest().withNamespace("AWS/RDS").withMetricName("DatabaseConnections").withDimensions(Arrays.asList(new Dimension().withName("DBInstanceIdentifier").withValue(db.getDBInstanceIdentifier()))).withStartTime(startDate).withEndTime(endDate).withPeriod(10800).withStatistics(Arrays.asList("Maximum")).withUnit("Count")); if (getMetricStatisticsResult.getDatapoints().size() >= 1 && getMetricStatisticsResult.getDatapoints().get(0).getMaximum().intValue() <= 0) { amazonRDS.stopDBInstance(new StopDBInstanceRequest().withDBInstanceIdentifier(db.getDBInstanceIdentifier())); } } }); // snip }
解説とか
Javaです。
MySQLとMariaDBで試した限り、特に問題なくRDSインスタンスが停止していいました。他のは試してないですが多分大丈夫かと。
マルチ AZ とかそういうオシャレ機能には対応してないです。 試したことも無いです。
Amazon RDS にはDatabaseConnectionsメトリクス があります。今回はこれを使います。
直近、3時間の使用中のデータベース接続の数を取得して0件だった場合、RDSの停止を試みます。
参考: Amazon RDS のモニタリングの概要 - Amazon Relational Database Service