お仕事でぼちぼちServerlessFrameworkを使い始めました。
###辛かった
lambdaを始めたばかりの時は「いやー、フレームワークとかまだ早いっしょ」とか「もうちょっとWeb UIで慣れてからやろう」と思っていましたが、
CLIでデプロイできるのはやっぱ楽だし、超早いです。 API gatewayとlambdaの連携の設定とか面倒だし。zipを固める作業とか苦行でした。その先になにかあるかなー、と思っていたんですが。
###で、ServerlessFrameworkですが、使い始めてみると
「ちょっとコレなしにデプロイとか、する気おきないなー」とか「これ取り上げられたら、仕事休みたいなー」という程度に普段使いするツールになりました。
という訳で、私がServerlessFramework導入するまでをまとめてみます。
私は下記の状況で使っています。
- ndenvでバージョン指定してインストール
- node関連はシステムワイドにインストールせずに作業ディレクトリのnode_modules配下のものを使う
- ローカル実行したい( テストを手軽に実行したい... )ので lambda-local というツールをインストール
- slackにWebhookの設定
###nodeインストール
ここを参考にさせていただきながらインストールしました! ->
http://qiita.com/0084ken/items/22ca33032773c6d2f9f4
http://qiita.com/MahoTakara/items/8fdebe32e8f326afa7f8
git clone https://github.com/riywo/anyenv ~/.anyenv
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(anyenv init -)"' >> ~/.bashrc
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(anyenv init -)"' >> ~/.zshrc
exec $SHELL -l
anyenv install ndenv
exec $SHELL -l
anyenv version
ndenv install -l | grep '4.3'
ndenv install v4.4.3
ndenv global v4.4.3
ndenv versions
system
* v4.4.3 (set by /Users/kaoru_inoue/.ndenv/version)
###ServerlessFrameworkのプロジェクト作成
mkdir testservice
cd testService
npm init -y
するとローカルにpackage.jsonというファイルができます。
これはnodeで、このアプリに必要なモジュールなどを一気にいれたり、テスト( すみません、まだできておりません... )を設定したりするファイルです。
モジュールを一気に入れる機能、超便利です。
npm install --save slack-node
npm install --save-dev serverless aws-sdk lambda-local
--save アプリの動作に必要なモジュール
--save-dev 開発に必要なモジュールです
ServerlessFramework は開発には必要ですが、lambda側にアップする必要はないので --save-dev ですね。
あとnodeモジュールの「aws-sdk」はlambda側に予め入っているので、デプロイ時は同梱しなくてもok
下記のようにpackage.jsonが書き換わります。
npm installコマンドは package.jsonという名前のファイルを元に必要なモジュールをインストールします。
ので、package.jsonを作業ディレクトリにコピーして npm install で一発でインストールでも良いです( 同じようなサービスを複数作る場合は雛形みたいなものがあった方が楽そうですね )
{
"name": "testservice",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"babel-polyfill": "^6.23.0",
"slack-node": "^0.1.8"
},
"devDependencies": {
"aws-sdk": "^2.28.0",
"lambda-local": "^1.4.2",
"serverless": "^1.9.0"
}
}
slackに通知するコードです( 下記サンプルの webhookUriは書き換える必要があります! )
ファイル名は「slackTest.js」とします( 任意ですが、後でServerlessFrameworkでデプロイするファイルを指定します )
'use strict';
const AWS = require('aws-sdk');
const Slack = require('slack-node');
const slack = new Slack();
const webhookUri = 'https://hooks.slack.com/services/naisho_himitsu';
slack.setWebhook(webhookUri);
function pushSlackChannel(channel, username, text ){
return new Promise(function(resolve,reject) {
slack.webhook({
channel: channel,
username: username,
text: text
}, function(err, response) {
if (err) {
console.log(response);
reject(new Error('Error'));
return;
} else {
resolve(response);
}
});
});
}
module.exports.slackPost = (event, context, callback) => {
const response = {
statusCode: 200,
body: JSON.stringify({
message: 'slack post in success',
input: event,
}),
};
pushSlackChannel('#general', 'tin-machine', 'こんにちは!')
.then((response) => {
// console.log(response);
callback(null, `Successfully ON watchdog stream.`);
})
.catch(err => {
// console.log(err);
callback('Error occured.');
});
};
###slackアカウント作成( 5分程度? )
上記のコードで指定すべきWebhookURIがありません、はりきってSlackアカウントを作成しましょう( 5分程度 )
メールアドレスが必要です( 私は hogehoge+1@gmail.com みたいなアドレスで登録しました )
- https://slack.com/ にアクセス、メールアドレス入れて[ create new team ]
- メールに確認用の数字が届くので入力
- あとはグループ名を決めたり、招待する人を決めたり
###slackのwebhook urlをコピペ
####画面右上のアカウント名をクリック
####[ Apps & integrations ]をクリック
####[ Add Configuretion ]をクリック
####[ Webhook URL ]の[ Copy URL ]をクリックしてWebhook URLをコピー
###lambda-local でローカルでテスト
lambdaは何かイベントで発動しますが、適当なダミーのデータを作成します。
mkdir event-samples
vi event-samples/testEvent.json
{
"key3": "value3",
"key2": "value2",
"key1": "value1"
}
./node_modules/lambda-local/bin/lambda-local -l slackTest.js -h slackPost -e event-samples/testEvent.json
ローカルで動きましたかね? で、これをサーバレスで動かしたい訳です。
###ServerlessFrameworkでデプロイ!
ServerlessFrameworkでデプロイしてみます。
これをお読みの方はAWSのWebUIで書いたり、zipに固めてアップしたりといった苦行をされている方だとお見受けします。そろそろ楽になっていいはず!
まずは簡単に『時刻で実行されるlambda関数』を設定してみます。 ひとまずリスクが少ないバッチ処理などをlambdaで書いてみるか、といった需要はあるはず。
時刻の指定は日本時間ではなく『UTC』です。いつも混乱しますが、AWS Lambda - Scheduled EventのCron書式を参考にさせていただきつつ、
直近の時刻を指定してみましょう。 日本の方がUTCに対して9時間すすんでいるので... 9時間、引きます。 今が21時なので、echo $((21 - 9)) で 12時ですね。
vi serverless.yml
service: slackPostService
provider:
name: aws
runtime: nodejs4.3
iamRoleStatements:
- Effect: Allow
Action:
- cloudwatch:*
Resource: "*"
package:
exclude:
- jsconfig.json
- event-samples
- package.json
- node_modules/**
- '!node_modules/aws-sdk/**'
- '!node_modules/slack-node/**'
functions:
slackPostFunction:
handler: slackTest.slackPost
events:
- schedule: cron(5 12 ? * MON-FRI *)
###いざデプロイの前に AWS CLI アカウント設定
すみません、pythonのパッケージ管理ツール pipのインストールと、AWSアカウント取得は既に設定ずみとさせてください。これ結構時間かかった記憶があります( が、持ってますよね...? )
AWSのアカウント情報を入力します。AWSにログインし、一番上の[ サービス ]->[ IAM ]->左側の[ ユーザー ]->使えるユーザ名をクリック->[ 認証情報 ]のタブ->[ アクセスキーの作成 ]
ここで作成された
- アクセスキー ID
- シークレットアクセスキー
をメモします。すぐ使います
pip install --upgrade --user awscli
aws configure
AWS Access Key ID [None]: アクセスキー ID
AWS Secret Access Key [None]: シークレットアクセスキー
Default region name [None]: ap-northeast-1
Default output format [None]:
###デプロイ
上記で設定したAWSアカウントでデプロイします。
./node_modules/serverless/bin/serverless deploy --region ap-northeast-1 --stage production
Slackへの通知きましたでしょうか?
これにプラスしてAWS node.jsライブラリと組み合わせて使うと、
EC2を定期的に立ち上げたり、spotfleet群を立ち上げたりできます。
ささっとコピペでいけるようにまとめてみました。 意外と手軽に始められますよServerlessFramework。
次はAWS API Gatewayとの連携をまとめてみます!
( 冒頭にも書きましたが、あれ手動でやると心折れそうになるくらいつらい、なんでlambdaとAPI gatewayの画面いったり来たりしないといけないんだ、という )