本記事で目指す構成
CloudWatch EventsをトリガーにLambdaを起動し、Slackへメッセージを飛ばす。
※ CloudWatch EventsにはあらかじめCron式で実行スケジュールを設定しておく。
↑こんな感じで自動で定期実行してくれるようになる。
対象読者
- Rubyで定期実行プログラムを作成してみたい人
- Lambdaに触れてみたい人
仕様
言語: Ruby2.5系
インフラ: Lambda、ClowdWatch Events
※ SlackBotは各自あらかじめ作成しておいてください。
完成形
periodic-slack-bot-on-aws-lambda
※ 一から作るのが面倒な方は↑からgit cloneしてください。
プログラムを作成
Slackへメッセージを飛ばすためのプログラムを作成していく。
ディレクトリを作成
$ mkdir periodic-slack-bot-on-aws-lambda
$ cd periodic-slack-bot-on-aws-lambda
Gitを設定
$ git init
$ touch .gitignore
.bundle
/vendor/bundle
Gitで管理したくないものを記述。
Rubyのバージョンを指定
$ rbenv local 2.5.1
# 2.5系を推奨
Gemをインストール
$ bundle init
↑のコマンドでGemfileを生成し、以下のように編集する。
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
ruby '2.5.1'
gem 'async-websocket'
gem 'slack-ruby-bot'
その後、必要なGemをインストール。
$ bundle install --path vendor/bundle
※ 後ほどGemも含めてzipファイルにパッケージングする必要があるため、グローバルではなく「vendor/bundle」以下(ローカル)にインストールしなければならない。
app.rbを作成
$ touch app.rb
require 'slack-ruby-client'
Slack.configure do |conf|
conf.token = ENV['SLACK_BOT_TOKEN']
end
def post_to_slack(event:, context:)
client = Slack::Web::Client.new
client.chat_postMessage(channel: ENV['SLACK_CHANNEL_NAME'], text: 'テスト送信 from AWS Lambda', as_user: true)
end
※ 引数に「(event:, context:)」を渡さないと動かないので注意。
参照記事: Python の AWS Lambda 関数ハンドラー
Lambdaへデプロイ
プログラムを作成したら、Lambdaへデプロイするための準備を行う。
AWS CLIをインストール
今回は「AWS CLI」と呼ばれるツールを使いながらデプロイしていくので、まだインストールできてないない場合はインストールしておく。
$ brew install awscli
IAMユーザーを作成
デプロイを行うためのIAMユーザーを作成していく。
まずは「IAM」→「ポリシー」→「ポリシーの作成」へと進み、JSONタブから以下の文を貼り付ける。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"apigateway:*",
"cloudformation:*",
"dynamodb:*",
"events:*",
"iam:*",
"lambda:*",
"logs:*",
"route53:*",
"s3:*"
],
"Resource": [
"*"
]
}
]
}
適当にポリシー名や説明を記述し、「ポリシーの作成」をクリック。
次に「IAM」→「ユーザー」→「ユーザーの作成」へと進み、適当な名前を付けた後「プログラムによるアクセス」にチェックを入れて次へ進む。
「既存のポリシーを直接アタッチ」から先ほど作成した「MinimalDeployIAMPolicy」を選択し、次へ進む。
(タグは任意でOK)最後に確認画面が表示されるので、問題無ければ「ユーザーの作成」をクリック。
すると「アクセスキーID」と「シークレットアクセスキー」の2つが発行されるので、csvファイルをダウンロードするなりメモするなり大事に保管しておく。
AWS CLIの設定
$ aws configure --profile lambda(任意のプロフィール名でOK)
AWS Access Key ID # 先ほど作成したアクセスキーID
AWS Secret Access Key # 先ほど作成したシークレットアクセスキー
Default region name # ap-northeast-1
Default output format # json
ターミナルで「aws configure」と打ち込むと対話形式で色々聞かれるので、それぞれ必要な情報を入力していく。
関数を作成
AWSのコンソール画面から「AWS Lambda」を開き、「関数の作成」をクリック。
- 関数名(任意の名前)
- ランタイム(Ruby2.5)
を入力して関数を作成する。(その他はデフォルトの値もしくは空欄でOK)
「環境変数の編集」から
- SLACK_BOT_TOKEN
- SLACK_CHANNEL_NAME
それぞれ環境変数をセット。
「ランタイム設定を編集」からハンドラ名を「app.post_to_slack(ファイル名.メソッド名)」に変更。
デプロイ
作成したプログラムをzipファイルとしてパッケージング。
$ zip -r function.zip app.rb vendor
aws cliを使いデプロイ。
$ aws lambda update-function-code --function-name PeriodicSlackBotOnAwsLambda --zip-file fileb://function.zip --profile lambda
{
"FunctionName": "PeriodicSlackBotOnAwsLambda",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:**************:function:PeriodicSlackBotOnAwsLambda",
"Runtime": "ruby2.5",
"Role": "arn:aws:iam::**************:role/service-role/PeriodicSlackBotOnAwsLambda-role-**************",
"Handler": "app.post_to_slack",
"CodeSize": 12941753,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2020-10-09T21:08:11.888+0000",
"CodeSha256": "**************/**************=",
"Version": "$LATEST",
"Environment": {
"Variables": {
"SLACK_CHANNEL_NAME": "#**************",
"SLACK_BOT_TOKEN": "xoxb-**************-**************-**************"
}
},
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "********-****-****-****-********",
"State": "Active",
"LastUpdateStatus": "Successful"
}
※ --function-nameには先ほど作成した関数名をセット。
テスト実行
「テストイベントの設定」から適当にテストを作成。(ハッシュは空欄でOK)
「テスト」をクリックし、指定したSlackチャンネルへメッセージが飛んでいれば成功。
CloudWatch Eventsでスケジュール管理
トリガーの設定
「トリガーを追加」をクリック。
- トリガー名: CloudWatch Events
- ルール: 新規ルールの作成
- ルール名: test_30minutes(任意)
- ルールの説明: 30分に1回実行(任意)
- ルールタイプ: スケジュール式
- スケジュール式: cron(*/30 * * * ? *)
※ 実行間隔はそれぞれお好みで設定。
cron式の書き方の説明については今回省略。
参照: クーロン(cron)をさわってみるお
もし上手く行かなかった場合はCloudWatchのロググループ内にログが出力されているはずなので適宜デバッグ。
あとがき
お疲れ様でした!もし記事通りに進めて上手く動作しない箇所があったらコメント蘭などで指摘していただけると幸いです。