AWS Lambdaに入門する

Amazon Elasticsearch Serviceに引き続き、AWS Lambdaに入門しました。Lambdaを使って、Amazon Elasticsearch Serviceで特定の単語を検索をさせてslackに書き込んでくれるbot君を練習台でやってみました。

やりたいこと

AWS強化月間(?)ということでAmazon Elasticsearch Serviceに入門していました。

twitterやslackのデータ置き場は無事に自宅のmac miniからAmazon Elasticsearch Serviceに移行できました。しかし、肝心のクローラーは相変わらず自宅のmac miniのjenkinsが頑張っているので、それをAWS Lambdaで代わりにやってもらおうというのがやりたいことです。一気にやるのはしんどいので、今回は以下のことをやってみます。

  • CloudWatch Eventsで定期的にlambdaを起動
  • Amazon Elasticsearch Serviceに貯蓄されているtwitterのデータから特定の単語を含むものを検索
    • goを使って書いていますが、AWSの認証をどうやるか
  • 検索にヒットした発言をslackに投稿
    • lambdaから簡単に外に出られるのか

簡単なことしかやっていないですが、まぁ手始めということで。

準備: 適切なポリシーを設定する

後で説明しますが、apexからあれこれできるようにする必要があるので、IAMのポリシーを設定します。

IAMのポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:Create*",
                "iam:Attach*",
                "lambda:*"
            ],
            "Resource": "*"
        }
    ]
}

Goで書いたプログラムをapexを使いAWS Lambdaに転送

AWS Lambdaでサポートされている言語はNode.js、Java、C#、Pythonのみですが、最近練習しているGoで書きたかったので方法を探りました。

ちょっと脇道にそれますが、最近オフィスでNetatmoを使ってco2濃度をはかって、閾値を越えたら強制的に窓を開ける活動が流行っています。東京はGoogle App Scriptでやっています。

京都では同様のことをlambdaでやっている同僚がいて、聞いてみるとapexを使っているようでした。なるほど、これを使うとGoで書いてlambdaで動かせるようです。

Goでビルドしたバイナリをlambdaに送り、それを実行しているようで、外部のライブラリに依存していても割と安心なのはいいですね。サーバー上でライブラリをインストールする手間が省けます。AWSのコンソール画面をほぼ開くことなく、apex deployでlambdaにコードがdeployされていき、apex invoke hello --logsとやるとlambdaのプロセスを叩けました。1時間もかからずお手軽。

Lambda上からAmazon Elasticsearch Serviceで検索

GoからElasticsearchを叩けるようにするライブラリを作っている人はすでにいらっしゃいました。

これを使うとやりたいことができそうですが、AWSの認証を突破しないといけません。私の場合、IPでの接続制限ではなくロールでの制限をやっているので、その情報を上述のclientに渡す必要があります。AWSがgo用のsdkを用意してくれていて、それを利用した認証情報をclientに食わせると、Amazon Elasticsearch Serviceで検索できるようになりました。

あとはこれをlambda上で動かせるようにすれば完成です。githubに上げました。

ACCESS_KEYやtokenも環境変数としてlambdaに登録していく必要がありますが、以下のようにするとそこまで面倒を見てくれます。

% apex deploy --set AWS_ES_ENDPOINT=https://search-XXX.ap-northeast-1.es.amazonaws.com --set AWS_ES_ACCESS_KEY_ID=XXX --set AWS_ES_SECRET_ACCESS_KEY=YYY --set SLACK_TOKEN=xoxp-XXX --set SLACK_CHANNEL_NAME=mackerel_search
% apex invoke hello --logs < event.json

毎回invokeしたくないので、AWSのコンソール画面からトリガー(CloudWatch イベント - スケジュール: cron)を設定しました。これで数分に一回、lambda側で勝手に起動してくれます。

MackerelのAWS連携でLambdaを監視

お決まり感がありますが、Mackerelで監視させます。MackerelのAWS連携はLambdaに先日対応したので、agentを入れることなくlambdaをMackerelにホストとして登録することができます。

read_onlyなロールを作ったらすぐ連携できます、便利。

f:id:syou6162:20170331091611p:plain

まとめ

AWS lambda上でGoを使って割と自由にコードを実行することができました。今回はElasticsearchの検索しかやっていませんが、元々はクローラーを作ってElasticsearchに結果を格納していきたかったのでした。しかし、ひとまず準備は整ったかなと思います。AWSのサービスも2つ触ったことになるし、段々雰囲気が分かってきたので勉強も進みつつあると思いたいです。勉強だけだと辛いので、自分で楽しめるやつをやっていこうとは思います。

Amazon Web Services実践入門 (WEB+DB PRESS plus)

Amazon Web Services実践入門 (WEB+DB PRESS plus)