はじめに
弊社では、案件が始まるとAWSアカウントを3つ作成し、それぞれのアカウントで、社内検証用のdev環境・クライアントチェック用のstage環境・本番用のprod環境を構築する運用としています。
その中で、AWSからの請求額が高く、コストを抑える必要性が出てきています。
サーバーってずっと稼働させる必要ないよね?
dev環境・stage環境のECSサービスのタスクやRDSインスタンスに関しては、本番運用で使うものではないので、夜中に稼働させる必要はありません。
業務時間内のみ稼働させるように仕組み化する事で、コスト削減が可能です。
方法
Step FunctionsとEventBridge Schedulerを使うことで簡単に実現できます。
私は普段CDKでインフラの構成を書くのですが、今回IaCを使ったことがない方でも設定できるよう、AWS管理画面から設定する方法について記載しようと思います。
ECSのタスクを増やす
まずは、「朝の8:00にECSのタスク数を増やす場合」について説明します。
Step Functions
{
"Comment": "ECSのサービスタスク数を増やす",
"StartAt": "UpdateService",
"States": {
"UpdateService": {
"Comment": "ECSのサービスタスク数を増やす",
"Type": "Task",
"Parameters": {
"Cluster": "{{ECSクラスター名}}",
"Service": "{{ECSサービス名}}",
"DesiredCount": {{増やしたいタスク数}}
},
"Resource": "arn:aws:states:::aws-sdk:ecs:updateService",
"End": true
}
}
}
- ロールの設定を表示を押下します
- ステートマシン名の入力
ここで、ステートマシン名を入力します。Step Functions内で管理したい名前を入力してください。
また、実行ロールは、新しいロールを作成、という形にしましょう。
入力・選択が終われば次へ進んでください。
- またまたロールの作成を確認、のダイアログが出ますが、そのまま確認を押下します
まだIAMの権限が足りていませんが、ひとまずStep Functionsのステートマシンの作成が完了です。
- IAM権限を追加するため、インラインポリシーを作成を選択します
私が作業した時はポリシーを作成してからアタッチしましたが、今回手順を少し簡単にするため、インラインポリシーを作成、という形にします
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ecs:UpdateService",
"Resource": "{{ECSのARN}}"
}
]
}
EventBridge Scheduler
ECSのタスク数を0にする
指定時刻にECSのタスク数を増やす場合と同じ手順です。
設定が異なる部分のみ、以下に記載します。
- 「{}コード」をクリックし、以下を記述し、作成を押下します
{
"Comment": "ECSのサービスタスク数を減らす",
"StartAt": "UpdateService",
"States": {
"UpdateService": {
"Comment": "ECSのサービスタスク数を減らす",
"Type": "Task",
"Parameters": {
"Cluster": "{{ECSクラスター名}}",
"Service": "{{ECSサービス名}}",
"DesiredCount": 0
},
"Resource": "arn:aws:states:::aws-sdk:ecs:updateService",
"End": true
}
}
}
- 定期的なスケジュールを選択し、cron式を記述します
タスク数を0にしたい時刻が21:00だとすると、以下のように設定してください。
cron (0, 21, *, *, ?, *)
RDSのインスタンスを停止する
こちらも同じ手順です。
設定が異なる部分のみ、以下に記載します。
- 「{}コード」をクリックし、以下を記述し、作成を押下します
{
"Comment": "RDSインスタンスの停止",
"StartAt": "StopRDSInstance",
"States": {
"StopRDSInstance": {
"Comment": "RDSインスタンスを停止",
"Resource": "arn:aws:states:::aws-sdk:rds:stopDBInstance",
"Type": "Task",
"Parameters": {
"DbInstanceIdentifier": "{{RDSインスタンスのDB 識別子}}"
},
"End": true
}
}
}
- IAMポリシーとして以下記述してください
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:StopDBInstance"
],
"Resource": "{{DBインスタンスARN}}"
}
]
}
RDSのインスタンスを起動する
こちらも同じ手順です。
設定が異なる部分のみ、以下に記載します。
- 「{}コード」をクリックし、以下を記述し、作成を押下します
{
"Comment": "RDSインスタンスの起動",
"StartAt": "StartRDSInstance",
"States": {
"StartRDSInstance": {
"Comment": "RDSインスタンスを起動",
"Resource": "arn:aws:states:::aws-sdk:rds:startDBInstance",
"Type": "Task",
"Parameters": {
"DbInstanceIdentifier": "{{RDSインスタンスのDB 識別子}}"
},
"End": true
}
}
}
- IAMポリシーとして以下記述してください
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:StartDBInstance",
],
"Resource": "{{DBインスタンスARN}}"
}
]
}
さいごに
全てのAWSアカウントに対して設定すれば、ちりつもで結構コスト削減できるのでは??