使わないRDSをできるだけ停止しておきたい～AWSコスト削減

# はじめに
あなたはAWSを使用していますか？
もちろん、使用していますよね。
今や、世の中のWEBサービスを見渡せば、必ずAWSが目に入ってきます。
にもかかわらず、ほんの1年前まで私はAWSが何なのかさえ良く分かっていませんでした。
たぶん業界を一歩離れると、「AWS？名前は知ってるし、ロゴ的にAmazonに関わる何かだということも知ってるけど…」みたいな人も多いのではないかと思います。
そんな超初心者の私も今年IT業界の扉をたたき、AWSの中に入る機会が増えてきたので最近やったことを記事にしてみました。

## 電気料金とAWS請求料金は上がり続けるのか
会社のインフラチームから、「君の使ってるアカウントのAWS料金高すぎぃ！」って怒られました。（多少盛っています）

1か月以上ログインしてないんだけど、どうして！？
あ、停止したはずのRDSが起動してるじゃん！

そういえば停止するときに、「1週間後に再起動するからね！」って言われた気がするけどすっかり忘れていました…

### RDSの料金についておさらい
RDSの料金には、ざっくり以下のタイプがあります。
1. サーバーインスタンスの稼働料金（スペック × 稼働時間）
2. ストレージ使用料金（スペック × 使用容量）
3. 通信料金（通信量）

普通にサーバーを使用していれば、インスタンスは24時間稼働している場合がほとんどだと思いますので、コスト削減のためにできることといえば、インスタンスやストレージのスペックを見直すくらいかと思いますが、AWSを使用していると、テストや開発環境など、本番環境以外のインスタンスを作成する機会もありますよね。
そういったサーバーは使わない時間も長く、起動しておくと一番大きい①のコストが発生してしまうため、使わない時期は忘れずに停止しておきたいところです。

しかし、RDSを止めておいてもデータなどはAWSに保持されているわけで、そう簡単に停止したまま（＝無料）にはさせてはもらえないようになっています。
RDSを停止するときに必ず出てくるアラートにもある通り、停止したRDSインスタンスは **7日後に自動的に起動します。**

たまにしか起動しない実験用サーバーなど、うっかり忘れてしまいかなりの使用料が請求されることもあるでしょう。
私などはただでさえ、金曜日に在宅勤務をすると月曜日は家にパソコンを忘れて出社するくらいなので、一週間前に停止したRDSのことなど覚えていられるわけがありません。
DBを一度削除してしまえばいいかもしれませんが、ちょっと使いたいときにイチから作り直すのも手間だし、何だかんだで再構築時には③の通信料だって掛かってきます。
そこで、1週間たったら自動でRDSを停止する方法はないか調べてみました。

## Amazon EventBridge SchedulerでAWSをスマートホーム化
イベントを指定してAWSサービスの状態を変更することができるサービス、それがAmazon EventBridgeです。
EventBridge自体はAWSサービスを監視して、特定の条件の時にアクションを起こす機能を持つようですが、その中で最近追加されたEventBridge Schedulerは、スケジュールをトリガーにアクションを実行してくれて、例えば「毎週月曜日の9時にこのインスタンスを起動」みたいなことができるみたいです。
素人目線でも、最近自宅で導入し始めたスマートホームとだいたい一緒なのでイメージがつきやすいです。

うちには生き物がいるのですが、Switchbotなどのスマートホームデバイスで温湿度管理を行い、見守りカメラでストーキングすることで安心して出社することができていますが、もしこれらがなければ、とても正気ではいられなかったことと思います。
それはさておき、AWSに例えると、EC2やRDSなどのAWSサービスが見守りカメラやライト、ヒーター、エアコンなどで、EventBridgeがSwitchbotやIFFFTなどのアプリの、温湿度などを監視してオンオフを行う機能、EventBridge Schedulerが毎日朝9時になったら電源をオンにする機能ということになります。ちょっと無理やりすぎました。

# 設定してみる
今回はタイトルの通り、RDSをひたすら停止するスケジュールを作成してみました。
#### 参考文献
[【5分で簡単！】Amazon EventBridge SchedulerでRDSの自動定期停止を実装してみた](https://dev.classmethod.jp/articles/amazon-eventbridge-scheduler-rds-stop/)

実際のところはほぼ上のクラスメソッドさんの記事に従って設定を行ったわけですが、もしなかったら場合を考えて、触りながら分からないときは公式を調べるスタイルで設定していきます。

## EventBridgeでスケジュールを作成
サービスのトップページに入ると、小さいポップアッからでスケジュールを選べるようになっていました。
![start.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2564396/1de7103e-11b2-046e-1e36-eea715ecf717.png)
AWSのこういう仕様は気まぐれに変わりまくるみたいなので今回たまたまかもしれませんが、とにかくスケジュールの作成を選択すると、スケジュールパターンの設定なんかを行う画面が現れます。

最初の画面はこんな感じで設定しました。
![setting1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2564396/60c4e005-ca74-e63f-8dc7-7e8eadc47302.png)
ここでのポイントは、rateベースのスケジュールで**169時間ごと**の実行にしたこと。

cornベースにすると、例えば毎週水曜日の17時に設定した場合、初週はその時間ぴったりに停止コマンドを実行したとしても、次の週17時ピッタリに停止命令を送った瞬間にはRDSがまだ起動していなかったり、AWS側の自動起動コマンドと同時になってしまってうまく停止できない可能性が考えられます。

回避するために毎日1回、17時に実行するとかにしても、RDSが17時15分に起動した場合はほぼ24時間の起動を許すことになってしまいますし、有限であるEventBridgeの命令を月に30回消費してしまうことにもなります（これは大したことないけど）。

たぶんですが、私の予想では毎回速攻で停止した場合でも、RDSの起動時間は毎回少しずつ後ろにズレれていくと思うんですよね。
ということで、7日＝168時間に1時間をプラスした **rate(169 hours)** でスケジューリングすることにしました。実際は30分もずらせば十分だった場合は分単位で **rate(10110 minutes)** とかにしてもいいかもしれません。
あとは初回の開始日時を設定しました。スケジュール名の通り自分で起動するときまでは永久に停止しておきたいため、終了日時は設定していません。

### ターゲットの選択
ここはAmazon RDSを選択してstopとかで検索すればこれだろうなというAPIが見つかります。
![setting2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2564396/1f9c4e0b-b503-a183-f1b6-32aedd912a0c.png)
「StopDBInstance」というやつですね。下のJSONの _"MyData"_ に停止したいDBのインスタンスIDをセットすれば良いようです。
![setting3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2564396/3024a26f-af12-d579-17a9-8ab96183e9f5.png)

### アクセス許可とは
次のページに進むと何やらロールを選ぶみたいですが、AWSなのでIAMロールのことで間違いないでしょう。
![setting4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2564396/91698440-6387-a878-bd97-40d628572eac.png)
このイベント用のIAMロールを作成しなくてはいけないということですね。なぜか「このスケジュールの新しいロールを作成」が選択できないので、「IAMコンソールに移動」して作成していきます。

## IAMロールの作成
AWSといえばまずIAMロールというのが、今年の7月くらいからAWSを触り始めた私の今のところの感想です。ぼんやりとした認識としては「厳密に制限した権限の塊(IAMロール)をAWS内に作成された全ての要素が必ず所有することで、予期しないアクションが実行されることを防止している」みたいなイメージです。

### 信頼されたエンティティを選択？
![iam.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2564396/dbe82ac6-0738-9587-7993-5e1a3041cc0c.png)
はい、初っ端からさっぱりです。
情報をクリックしてサイドメニューを開くと、こんな解説が。
> Trusted entity types
When you create a role, you create two policies: A role trust policy that specifies who can assume the role and a permissions policy that specifies what can be done with the role. You specify the trusted principal who is allowed to assume the role in the role trust policy.

つまり、信頼されたエンティティはまずは誰が（どのサービスが）このロールを使用できるのかを設定するところみたいです。「誰が」と「何に対して」の2つのポリシーを設定するんだということが分かりました。
この通りだと、今回は普通に「AWSのサービス」からEventBridge Schedulerを選択すれば良いのかな？という感じですよね。
だがしかし、残念なことに選択肢にそれっぽいものはありません。唯一存在するEventBridgeの選択肢はSecrets Managerをどうこうするものなのでこれは違う感じです。
しかたなくEventBridgeのドキュメントを探してみるとロールの設定が書かれていました。
[Setting up Amazon EventBridge Scheduler](https://docs.aws.amazon.com/scheduler/latest/UserGuide/setting-up.html)
CLIでの設定として書かれていますが、こちらはコンソールしか使えない雑魚エンジニアなので、ロール設定画面のカスタム信頼ポリシーにドキュメントにあるScheduler-Execution-Role.jsonなどという部分をそのままぶち込むしかないでしょう。
```json:Scheduler-Execution-Role.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "scheduler.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```
### 許可ポリシーの作成
次のページに進むと今度は許可ポリシーの設定になります。
ここもできれば用意されたポリシーから選択したいところですが、やっぱり作成せざるを得ないでしょう。
AmazonRDSFullAccessだとちょっと与えすぎな気もするし、参考までに中を見ても _"rds:*"_ でRDSの操作権限がまとめられているので細かい設定の書き方はわかりません。おそらくAWSをちゃんと理解している人や普段CLIで操作している人には朝飯前なのでしょうが…まぁでもDBを停止させるんだから"rds:StopDBInstance"とかなんだろうなーと予想はつきますね。

嘘です、ごめんなさい。
でもよく考えたらSchedulerのほうのAPI設定でStopDBInstanceを選択してるんだからやっぱりわかる人にはわかるのかも。

[IAM JSON policy reference](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html)
[Amazon RDS and Aurora Documentation - Actions](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_Operations.html)
この辺りを頑張って読み解けばかろうじてたどり着けそうです。

ということで、正解はこちら（もちろん自力でたどり着いたわけではありません）
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "rdsstop",
            "Effect": "Allow",
            "Action": "rds:StopDBInstance",
            "Resource": "*"
        }
    ]
}
```
ポリシー名はわかりやすくそのままRDSStopDBInstanceみたいな名前に設定しました。
次に進んであとはEventScheduler-RDSStopみたいなわかりやすいロール名と説明を添えて完成です！

## やっと帰ってきたScheduler
ただいま～
さっそく作ってきたIAMロールを適用してあげれば、スケジュールを作成できます。
以上、あとはスケジュールが実行されるのを待つのみです。

# うまく停止できたかな？
さて現在、初回実行をわくわくして待ち、目論見通りRDSを停止できたことに喜び、設定したことも忘れたころにこの記事を書いています。
Cost Explorerで見てみると、現在のRDSの使用量はこんな感じ。
![hours.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2564396/c49f710d-31b4-f7c2-9229-f6de8b8a3569.png)
11月の9日に手動停止した翌週の16日からスケジュールを開始した様子が良くわかります笑
良い感じに停止できているようで嬉しいですね。
時間を見ると毎週40分くらい起動しているようなので、レートを7日と30分にしてみてもいいかもしれませんが、何らかの原因で起動にいつも以上の時間がかかる場合もあるかもしれないのでこのままにしています。

# おわりに
長くなってしまいましたが、最後まで読んでいただきありがとうございました。
実際は[参考記事](https://dev.classmethod.jp/articles/amazon-eventbridge-scheduler-new-way-to-launch-tasks/?utm_source=go.pardot.com&utm_medium=mail&utm_content=blog&utm_campaign=2212_mailmagazine)のおかげで結構サクッと設定できましたが、今回この記事を書くのにあたり、なぜそうするのかをいろいろ調べたりしてAWSレベルがちょっとだけ上がりました。
ITエンジニアになった2022年は間もなく終わりますが、来年はCLIでAWSをカチャカチャできるようになりたいものです。

今回初めてQiitaに投稿しましたが、記事を書くのってとても大変ですね。
いつも参考になる記事を投稿してくれる先人たちには感謝の限りです。

私は普段、株式会社オープントーンでkintoneやBacklogの開発支援を行っています。
会社のブログに投稿したりすることもありますのでkintoneやBacklogに興味がある方は覗いていただけると嬉しいです。