AWS LambdaでRubyスクリプトをCloudWatchで定期実行する

この記事を書いたひと: @t4traw 2019年9月19日

AWS Lambdaでrubyスクリプトを登録し、CloudWatchで定期的に実行というのを、よく作っているので書いておきます。

今回書いたAWS Lambdaでrubyのスクリプト(標準以外のgemを使うパターン)のサンプルはt4traw/lambda-ruby-templateにpushしておきました。

まず、実際に書くrubyのコードの注意点として、

  • 関数単位で実行するので、必要な処理は関数にまとめておく
  • その関数の引数にを(event:, context:)としておく
  • gemを使う場合、そのgemもzipでまとめてアップロードしないといけないので、ローカルにインストールする(つまりbundle install --path vendor/bundleにしておく必要アリ)

といったところでしょうか。今回はSlackへランダムな文字列を定期的にポストするシンプルなコードをLambdaとCloudWatchで実装したいと思います。

Rubyは一応2.5.0をインストールしておく

AWS Lambdaのrubyランタイムは2.5.0なので、開発環境も一応2.5.0にしておきます。僕の場合はrbenvですので、こんな具合にしておきます。

$ rbenv install 2.5.0
$ rbenv local 2.5.0

gemをインストールする

ruby2.6以上だとbundlerは標準だったけど、2.5.0は標準ではないので、まずはbundlerをインストールします。で、bundle initします。

$ gem i bundler
$ bundle init

Gemfileに必要なgemを書きます。

Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "slack-notifier"

そしたら、bundle installします。上にもありましたが、あとでgemごとパッケージしないといけないのでローカルにインストールする必要があります。

$ bundle install --path vendor/bundle

実際にコードを書く

SlackにSecureRandomで生成した文字列をSlackにポストするだけなので、とくに難しいことはありません😁

SlackのWEBHOOK_URLは各自カスタムインテグレーションで生成してくださいませ。

app.rb
require 'slack-notifier'
require 'securerandom'

WEBHOOK_URL = 'YOUR_WEBHOOK_URL'

def foobar(event:, context:)
  notifier = Slack::Notifier.new(WEBHOOK_URL)
  notifier.ping SecureRandom.hex(16)
end

試しに、foobarとか書いて、bundle exec ruby app.rbで実行してみてください。

AWS CLIのセットアップ

AWS CLIを使うので、brewでインストールします。

$ brew install awscli

インストールが終わったら、IAMでLambda, CloudWatchにアクセスができるグループ&ユーザーを作成し、認証を開始します。

途中リージョンを聞かれるので、ap-northeast-1(東京リージョン)を指定しておきます。output formatはデフォで構わないので、何も入力せずにEnterを押しておきます。

$ aws configure

デプロイする

Lambdaで関数を作成しておきます。

今回作った物をzipでパッケージします。

$ zip -r function.zip app.rb vendor

そして、AWS CLIでデプロイします。–function-nameは適宜変更してください。

$ aws lambda update-function-code --function-name 上で作った関数名 --zip-file fileb://function.zip

デプロイできたらLambdaの画面で確認し、イベントハンドラをfile_name.function_nameに変更し、保存します。

そしたら、試しにスクリプトをlambda上で実行します。画面上部のテストボタンをおして、パラメーターはとりあえず空のhashで作成し、実行してみます。

無事、動きました😄

CloudWatchで定期実行する

トリガーを追加をクリックして、CloudWatch Eventsを追加します。

で、新規ルールの作成をし、ルール名と説明とスケジュールを登録します。スケジュールはcron式で書けるのですが、日にちか曜日を指定しない場合は?で入力する必要があったりするので、詳しくはドキュメントを参照してください。

ルールのスケジュール式 - Amazon CloudWatch Events

今回は毎週水曜日の日本時間17時に実行してほしいので、cron(0 8 ? * WED *)といった感じに書きます。時間はGMTなんで注意してください。

最後に保存(追加ボタンを押す)を忘れないように👍


以上、簡単なLambdaとCloudWatchの定期実行の方法でした!

一番得意なrubyでサクっとlambdaのコードを作れるのが本当に嬉しいですw

また、今まではHeroku Schedulerでなんとかやっていたのですが、Heroku Schedulerは毎分、毎時、毎日のどれかしか選べない……。CloudWatchはcron式で定期実行でき、他にもCloudWatchで監視している○○をフラグに実行など、柔軟な方法を選べるのが最高です!

それでは👐