サーバコストダウン!AWS EC2 を cron & php で自動停止

f:id:tkhttty:20190318170859p:plain

はじめに

こんにちは! インフラチームの高畑です。

新卒で入社して早くも 2 年目に突入しそうで時間の流れが最近早く感じています。

今回、弊社で運用している標準開発環境(※)について、自動起動・停止するようにしてインフラコストダウンを計ってみたお話しをします!

※ ウィルゲートの開発室でエンジニアに割り当てられる、個々人が自由に使うことができるAWSのEC2上の開発環境のこと。詳しくは下記の記事をご覧ください tech.willgate.co.jp

これまでの運用

これまで標準開発環境は曜日時間問わず基本的にはずっと起動したままで運用を行っていました。

弊社のエンジニアは現在約 40 人ほど在籍しており、標準開発環境も人数分起動しています。

標準開発環境は現在全てのインスタンスAWS オレゴンリージョンの t3.medium インスタンスなのですが、大体月あたり $1,200 ほど( EBS、EIP をの除く)コストがかかっている状態でした。

f:id:tkhttty:20190318132831p:plain

そこで、今回はこのコストをなるべく減らすため、標準開発環境インスタンスを平日夜 22:00 、土日(全日)に自動停止をするようにしてみました。

自動停止させるために行ったこと

自動停止をするにあたり、まず PHP で起動、停止ができるスクリプトを用意しました。

この時の起動するしないのステータスは EC2 インスタンスのタグで管理しており、 activeinactive かで切り替えを行っています。

SDK を使えという声が聞こえてきますが試作品なのでということにしておきます)

<?php

if ($argc < 2)
{
    exit("Please specify an argument. Valid arguments are 'start', 'stop' or 'show'.\n");
}

$today = date('Ymd');
$dayOfTheWeek = date('w');

$startHoliday = date('Y1229');
$endHoliday = date('Y0103', strtotime('1 year'));

$instances = json_decode(shell_exec("aws ec2 describe-instances --query 'Reservations[].Instances[].[InstanceId,Tags[?Key==`State`].Value|[0]]' --profile aws_profile"), true);

switch ($argv[1])
{
    case 'start':
        foreach ($instances as $instance)
        {
            // ステータスがアクティブかつ、土日・年末年始期間でなければ起動
            if ($instance[1] === 'active' && ($dayOfTheWeek != 0 && $dayOfTheWeek != 6) && ($today <= $startHoliday || $today >= $endHoliday))
            {
                shell_exec('aws ec2 start-instances --profile aws_profile --instance-ids ' . $instance[0]);
            }
        }
        break;

    case 'stop':
        foreach ($instances as $instance)
        {
            shell_exec('aws ec2 stop-instances --profile aws_profile --instance-ids ' . $instance[0]);
        }
        break;

    case 'show':
        foreach ($instances as $instance)
        {
            var_dump($instance);
        }
        echo $dayOfTheWeek;
        break;

    default:
        exit("Invalid arguments.\nPlease specify an argument. Valid arguments are 'start', 'stop' or 'show'.\n");
        break;
}

あとはこれを cron などで定時実行させることで自動起動・停止が実現できます。

また、初期状態では全てのインスタンスが自動停止はしても自動起動はしないという状態となっており、これだと定時バッチを標準開発環境で起動しているといった人などが困ってしまうため、標準開発環境ダッシュボードというものを作成しました。

f:id:tkhttty:20190318140826p:plain
標準開発環境ダッシュボード

上記画面より、インスタンスの再起動、停止、起動が行えるほか、自動起動するしないを設定することができるようになっています。

運用方法を変えてみて

月半ばにこのような変更を行ったため、具体的にどれほどコストが下がったかは現状出ていませんが、約半数ほどのインスタンスが 1 日起動しないことがほとんどとなったため、コスト的には半額くらいにはなりそうな雰囲気を醸し出しています。

また、AWS EC2 を利用しているインスタンスについては応用ができると思いますので、夜などは利用しないテスト環境などにもうまく利用ができればと思っています。

同じようなことでお悩みの方がいらっしゃいましたら、参考にしていただけると幸いです!