Serverless Frameworkを触ってみた + 環境変数のアップロードまでやってみる

最近はあちこちでサーバーレスってTwitterのTLでよく聞くようになってて興味を持っています。
そういや、
今年の8月にもJAWS-UG沖縄 真夏の熱すぎるサーバレス祭り! - Doorkeeperに参加したのだれど、
その時のブログを書くの忘れてたのを今気づいた。
(過去記事漁ってみたら無かったからきっと書いてない…)
↑の勉強会に参加したときにServerless Frameworkの存在を初めて知りました。

と前置きはこのくらいにして
Serverless Frameworkをちょっと触ってみたときのログを書いておきます。
最近、AWSのLambdaさんが環境変数使えるようになったのと、
Serverless Frameworkが環境変数のアップロードに対応したのでそこまでがんばってみました。

Serverless Frameworkの導入から実行まで

下記は割愛します。

  • npmのインストール
  • awsのアクセスキー取得と登録

serverless frameworkのインストールは公式のドキュメントに書いてある通り

$ npm install -g serverless

で、プロジェクト作る時は

$ serverless create --template aws-nodejs --path my-service

でいけた。
後、ローカルで実行したかったのでserverless-run-function-pluginも入れておく。

$ npm install -g serverless-run-function-plugin

my-serviceディレクトリに移動して/handler.jsの中身をちょちょいと書き換えて

module.exports.hello = (event, context, callback) => {
  console.log("テストメッセージ");
  };

実行します。

$ serverless run -f hello

すると、テストメッセージが表示される。

環境変数のアップロードまでやってみる

ただアップロードするだけじゃ面白くないので
実際に環境変数が呼ばれて動くところまで確認してみます。
1分に1度Slackにメッセージをポストする感じのLambda Functionを作ってみます。
(1分に1度もポストされるとすごいうっとおしいので注意…w)

プロジェクトを新しく作成します。

$ serverless create --template aws-nodejs --path slack-post
$ cd slack-post

ソースはgistに上げて起きました。

今回読み込む環境変数は下記の3つです。

  1. WEBHOOK_URL (incomming-webhook)
  2. CHANNEL (postするchannel)
  3. USERNAME (postするときに表示されるusername)

handler.jsでは、slack_post用のfunctionを作成して、process.env.XXXXで各環境変数を読み込んでいます。

今回、slackにメッセージをポストするためにslack-nodeを使います。
package.jsonはだいぶ適当に書いてます。
package.jsonを用意できたら

$ npm install

で、node_modulesというディレクトリが出来上がり、パッケージがインストールされます。

serverless.ymlは、ほぼほぼサンプルのまんまなんですが、
environmenteventsを追加してます。
environmentGithubのissueみたら4日前ほどに追加されたみたい。
eventsは1分おきに実行するように記述

ここまで書けたのでアップロードまでやってみます。
アップロードは下記のコマンドでOKです。

$ serverless deploy

stage別にあげる方法とかもあるんですが、勉強不足のため今回は割愛。
で、Lambdaのコンソールを見てみるとちゃんと環境変数も上がってますね。

1分置きにslackにpostされるようになってるのでぽんぽん通知がきます(笑)

これではあとあと大変なことになるので、deployしたものを消しましょう。

$ serverless remove

これで消えます。

はまったところ

serverlessでハマったところは特に無かったんだけど、 serverlessを使うにあたりAWSのアクセス権がいろいろと必要で、結構ハマった。
S3とLambdaのアクセス権は良いとして、CloudFormationのアクセス権が必要だったんだけれど、
IAMのアクセス権の追加 -> ポリシーのアタッチでCloudFormationの項目が無かった…
なので下記のポリシーを自分で作成してアタッチした。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1398823592000",
            "Effect": "Allow",
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:UpdateStack",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStackResources",
                "cloudformation:DescribeStacks",
                "cloudformation:DeleteStack",
                "cloudformation:ListStacks"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

おしまい。