新卒必見?AWSだけで今日学んだこと(TIL)を定期配信して効率よく学習しよう

新卒必見?AWSだけで今日学んだこと(TIL)を定期配信して効率よく学習しよう

突然ですが、みなさん、「TIL」をご存知でしょうか。

TILとは
「Today I Learned」
の略で、
「私が今日学んだこと」という意味ですね。
つまり今日勉強したことをメモって行こうぜー、みたいなことです。
結構gitのリポジトリもあったりして流行りそうな感じになっています。

以前マークダウンをブラウザで見れるMkDocsをGitBucketと連携して自動更新するでも言及したように、
エンジニアとは毎日勉強、新しい学びの毎日、しかし全部なんて覚えてられないので、どこかにメモっておきたくなりますよね。

僕は未だにこのメモる習慣を続けているのですが、それに加えて、TILもつけています。
TILとして毎日勉強したことを箇条書きにして簡単にメモをして、これを使って毎日復習しようと考えてたんですね。

しかし、困ったことに、僕はTILはつけても別に見なかったんですね。
これではせっかくつけても全く記憶に定着しないわけですよ。
まぁお前がズボラなだけだろって言われればその通りなんですが、、、
そこはやはりエンジニア、極力機械にお任せしたい。自分から能動的にブラウザ開くのもめんどくさい。

てな訳で、システムから定期的に僕にTILの内容をメールするようにしてしまいました。

ゴール

今回のゴールは、その日つけたTILの内容をメールでお知らせするシステムを作ることです。

そのためにEC2を使うのは めんどくさい もったいない、AWSのフルマネージドなサービスだけでなんとかしたい。
てなわけで、CloudWatchでイベントを定期実行できるので、こいつを利用します。まぁcronですね。
そしてAWSで何か処理すると言えばLambda
メールはSNSで送れます。

イメージはこんな感じです。

環境

今回使うのは以下です。

CloudWatch
Lambda
SNS
Node.js 4.3

実装

さて、1つずつ行きましょう。

SNSでのメール送信準備

まずはSNSでメールを送信できるようにしておきます。
SNSはpushだけでなく、メールも送れるんですねー

まずは、トピックを作成します。

SNSのコンソール画面に行き、左のメニューからTopicsを選びます。

そして上のCreate new TopicからTopicを作ります。

Topicというのは、メッセージを送ったり受けたりする通信チャネルらしいです。
よくわかんないですね。
まぁメッセージを送受信するための一つのアカウントくらいに考えておけばいいんじゃないでしょうか。

create topicを押すと、モーダルが出てきます。
Topic nameとDescriptionを適当に入れましょう。
Descriptionが後にメールを送った時にユーザー名として表示されます。

これでTopicの作成は完了です。
ここでできたArnは後で使いますので、メモっておきましょう。

次にSubscriptionを作成します。

先ほどできたTopicにアクセスします。
するとこんな画面が出てきます↓

そうすると入力したメールアドレスあてに、確認のメールがきます。
このメールに含まれているConfirm subscriptionをクリックして購読完了です。
これで指定したメールアドレス宛てにメールが送れます。

SNSの用意はこれで完了です。

Lambdaで処理の実装

実際にメールを送る処理を作ります。

おなじみLambdaの出番です。
楽しい楽しいプログラミングの時間ですね。

そういえば最近、AWS Summitに行ってきまして、そこでよくLambdaの話が出ていました。
最近はいろんなところからLambdaが使えるので、やはりみんな当たり前のように使っているんだな、と感じました。
幸せなサーバーレスの時代がもうすぐかもしれませんね。

さて少し横道にずれましたが、
ここではLambdaから先ほど作ったSNSのTopicを使ってメールを送信させます。

今回はNode.jsでやります。
新しいFunctionを作って、プログラムを作成します。

僕の場合は、TILをweb上で見れるようにしてありますので、大まかな流れとして、
スクレイピング → 整形 → SNSにデータを渡してメール送信の依頼
となりそうです。

TILを保存する場所や形式は人それぞれだと思うので、今回はスクレイピング周りは無視して、SNSに送信をよろしくする処理だけお話しします。

var AWS = require('aws-sdk');
var sns = new AWS.SNS();

exports.handler = function(event, context) {
var params = {
Message: '送りたい内容',
MessageAttributes: {
someKey: {
DataType: 'String',
StringValue: 'String'
},
},
Subject: 'メールのサブジェクト',
TopicArn: '先ほど作ったTopicのArn'
};
sns.publish(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
}

これだけですね。ほぼ公式かどこかから持ってきたコードそのままです。
AWSのsdkを使うのがポイントですかね。
下の方のsns.publishにparamsを渡せば送信できちゃいます。

これで実装は完了ですが、一つだけやることがあります。
それはLambdaからSNSに対してメール処理をよろしくできるよう、Lambdaが使うRoleをいじる必要があります。
サービスをまたぐので、Roleでアクセスを許可する必要がありますね。

IAMから今回Lambdaで使うRoleを選び、ロールポリシーを作成します。

ここで
ロールポリシーの作成 > Policy Generator
から、AWSサービスでSNSを選び、アクションでPublishを選びます。
そしてARNに先ほど作ったSNSのTopicのARNを入れます。

そしてステートメントの追加でOKです。

これで準備完了、早速メールを送りましょう!

動作確認

さて動作確認してみましょう。
動作確認なので、一旦TIL云々は置いておいて、上で書いたコードだけを動かします。

Lambdaの上の方のSave and Testで実行!

きましたねー、これで内容だけTILにすれば良さそうです。

CloudWatchでイベント定期実行

さて長くなりましたが、最後にCloudWatchから定期実行するようにします。
これはめちゃくちゃ簡単です。

CloudWatchに行くと、左のメニューにイベントというものがあります。
クリックすると出てくるCreate Ruleからスケジュールのイベントルールを作ります。

そして↓の画像のように実行するスケジュールを入れて(UTCなのでご注意を)、先ほど作ったLambdaを選びます。
そして右下をクリックして進めて作成すればOKです!

今回も長くなってしまいましたが、かなり勉強の効率も上がるので、特に勉強真っ只中の新卒さんなんかはAWSの練習も兼ねてトライして見てください!