Help us understand the problem. What is going on with this article?

Railsが動いている検証用サーバ(EC2)を、AWSLambdaで指定の時間だけ起動して、コストを削減する

More than 3 years have passed since last update.

はじめに

サービスを運用していると必ず課題になってくる「インフラコスト」。出来ればなるべくお金を掛けたくないところですよね。
今回はRailsが動いてる検証用サーバをAWSLambdaを使って必要な時だけ起動するようにしました。

今回お世話になった参考サイト

AWSLambdaの設定
http://dev.classmethod.jp/cloud/scheduled_to_start_instance_from_lambda/

unicorn自動起動
http://blog.mmmcorp.co.jp/blog/2015/10/23/unicorn-auto-start/

delayed_job自動起動
http://blog.champierre.com/1037

大変参考になりました。有難うございます。

注意事項

今回インスタンスIDを指定して、サーバの自動起動・停止をおこないますが、インスタンスIDを指定する際は検証用サーバであることを確認してください。

環境

環境 バージョン
ubuntu 14.04
Ruby 2.1.2
Rails 4.0.2
capistrano 3.2.1
delayed_job 4.0.6

今回は上記構成のサーバを対象に検証しています。
また、Rubyのインストールにはrbenvを使用しています。

AWSLambdaの設定

AWSにログインしたら下記図のようにLambdaを選択してください。

AWS_マネジメントコンソール.png

サーバ自動起動スクリプトの作成

Create aLambda functionの選択

Lambda_Management_Console 3.png

スクリプトテンプレートに「hello-world-python」を選択

Lambda_Management_Console.png

Lambda function codeにスクリプトを記述

Lambda_Management_Console.png

起動スクリプト
import boto3

def lambda_handler(event, context):
    client = boto3.client('ec2')
    response = client.start_instances(
        InstanceIds=[
            'インスタンスID',
        ]
    )
    print response

Roleの作成

ページ中央辺りに「Role」の項目があるので、下記図のように選択

 Lambda_Management_Console 2.png

選択が終わると別タブが開くので下記図を参考に入力

IAM_Management_Console.png

ロールスクリプト
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "ec2:StartInstances",
        "ec2:StopInstances"
      ],
      "Resource": [
        "arn:aws:logs:*:*:*",
        "arn:aws:ec2:*:*:*"
      ]
    }
  ]
}

作成が終わったら元のタブに戻り、もう一度「Role」を選択し、先ほど作成したロールを選択。
以上が終わったらNextを押下して確認画面へ

Lambda_Management_Console.png

起動時間の設定

Fucntionが出来たら、起動時間の設定をします。
上部のタブから「Event sources」 => 「Add event source」を選択すると下記図のようになります。

スクリーンショット 2016-04-21 12.38.55.jpg

ここで「CloudWatch Events - Schedule」を選択します。

すると、下記図のようになります。今回は月曜日から金曜日の9時に起動するように設定します。
*cronの設定はUTCなので注意してください。

Lambda_Management_Console 5.png

これで完了です。

サーバ自動停止スクリプトの作成

基本的には起動と同じ手順なのですが一部スクリプトを書き換えます。

停止スクリプト
import boto3

def lambda_handler(event, context):
    client = boto3.client('ec2')
    response = client.stop_instances(
        InstanceIds=[
            'インスタンスID',
        ]
    )
    print response

Lambda_Management_Console 6.png

これでLamda側は完了です。

検証用サーバ

サーバ起動時にunicornとdelayed_jobを自動起動するようにします。

自動起動ツールのインストール

ubuntuの場合、chkconfigが使えないのでsysv-rc-confをインストールします。

インストール
sudo apt-get install sysv-rc-conf

unicornの自動起動

unicorn起動スクリプトの作成

etc/init.d/配下にunicornファイルを作成

etc/init.d/
sudo touch unicorn

unicornファイルの権限を755に変更

権限変更
sudo chmod 755 unicorn

unicornファイルに下記を記述

etc/init.d/unicorn
#!/bin/sh

#description:unicorn shell

NAME="Unicorn"
ENV=staging
USER=ubuntu

# 環境にあわせてください
ROOT_DIR="/var/www/vhosts/app/current"

GEMFILE="${ROOT_DIR}/Gemfile"
PID="${ROOT_DIR}/tmp/pids/unicorn.pid"
CONF="${ROOT_DIR}/config/unicorn/${ENV}.rb"
OPTIONS=""

start()
{
  if [ -e $PID ]; then
    echo "$NAME already started"
    exit 1
  fi
  echo "start $NAME"
  cd $ROOT_DIR
  su - ${USER} -c "cd ${ROOT_RIR} && BUNDLE_GEMFILE=${GEMFILE} bundle exec unicorn -c ${CONF} -E ${ENV} -D ${OPTIONS}"
}

stop()
{
  if [ ! -e $PID ]; then
    echo "$NAME not started"
    exit 1
  fi
  echo "stop $NAME"
  kill -QUIT `cat ${PID}`
}

force_stop()
{
  if [ ! -e $PID ]; then
    echo "$NAME not started"
    exit 1
  fi
  echo "stop $NAME"
  kill -INT `cat ${PID}`
}

reload()
{
  if [ ! -e $PID ]; then
    echo "$NAME not started"
    start
    exit 0
  fi
  echo "reload $NAME"
  kill -HUP `cat ${PID}`
}

restart()
{
  stop
  sleep 3
  start
}

case "$1" in
  start)
  start
  ;;
  stop)
  stop
  ;;
  force-stop)
  force_stop
  ;;
  reload)
  reload
  ;;
  restart)
  restart
  ;;
  *)
  echo "Syntax Error: release [start|stop|force-stop|reload|restart]"
  ;;
esac

上記で作成したスクリプトを、サーバ起動時に自動起動するように設定してください

unicorn自動起動
sudo sysv-rc-conf unicorn on

delayed_jobの自動起動

railsプロジェクト内にスクリプトを作成

sudo touch /var/www/vhosts/app/shared/config/delayed_job.monitrc
  • プロジェクトのパスは環境に合わせてください
delayed_job.monitrc
check process delayed_job
  with pidfile /var/www/vhosts/app/shared/pids/delayed_job.pid
  start program = "/bin/su - ubuntu -c 'cd /var/www/vhosts/app/current; PATH=/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH RBENV_ROOT=~/.rbenv RBENV_VERSION=2.1.2 RAILS_ENV=staging ~/.rbenv/bin/rbenv exec bundle exec bin/delayed_job -n 2 --queues=mailer,tracking --prefix=reports --pool=mailer:2 --pool=tracking:1 --pool=*:2 start'"
  stop program = "/bin/su - ubuntu -c 'cd /var/www/vhosts/app/current; PATH=/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH RBENV_ROOT=~/.rbenv RBENV_VERSION=2.1.2 RAILS_ENV=staging ~/.rbenv/bin/rbenv exec bundle exec bin/delayed_job -n 2 --queues=mailer,tracking --prefix=reports --pool=mailer:2 --pool=tracking:1 --pool=*:2 stop'"

monitのインストール

インストール
 sudo apt-get install monit

自動起動設定

自動起動
sudo sysv-rc-conf monit on

monitファイルの編集

/etc/monit/配下のmonitrcを下記のように書き換えます。

/etc/monit/monitrc
set daemon 120
set logfile /var/log/monit.log

set idfile /var/lib/monit/id
set statefile /var/lib/monit/state
set eventqueue
    basedir /var/lib/monit/events
    slots 100
set httpd port 2812 and
  allow localhost

###############################################################################
## Includes
###############################################################################
   include /etc/monit/conf.d/*
    # 環境に合わせてください
   include /var/www/vhosts/app/shared/config/delayed_job.monitrc

権限をrootユーザの700にしてください。

権限変更
sudo chmod 700 monitrc

以上です。これで検証用サーバが月曜日 ~ 金曜日の9時 ~ 23時まで起動するようになります。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした