はじめてのサーバレスアーキテクチャの設計と実装( Lambda, DynamoDB )

この記事は、[mediba Advent Calendar 2018](https://adventar.org/calendars/3315)の11日目です。

# はじめに
こんにちは、新卒一年目のエンジニア(仮免)のMYMです。
研修が終了し配属されてから6ヶ月立ったということで、
自分自身もアウトプットをしなければいけない時期になってしまいました。
現在のポジションはインフラ領域を担当しており、普段の業務は以下の事を行っています。

* 開発部のアカウント作成と管理
* 社内システムやサービスに障害が起きた際の対応
* 社内システムのインフラ部分の設計と開発
* 繰り返し手で実施していることをクラウドサービスを使用して自動化する <- 今回お話する内容

今回は、上にある中の4つ目のことについてフォーカスいたします。
業務の内容とは直接関係がないのですが、それらで得られたナレッジを
プライベートで活用したことについて詳しく説明していきます。

# サーバレスアーキテクチャとは
最初にこの言葉を聞いたときには、みんな何を言っているのかよくわからなかったです。😇
サーバがないとプログラムなどの処理が動かないのは当然のこと、どんな魔法を使っているのか疑問でした。🙄

調べていくと、サーバレスとは言いつつも実際にサーバが存在していないわけではなく、サーバはデータセンター内に存在しています。
ただ、自分がサーバを所有するのではなく、クラウドベンダが所有しているサーバに自分が開発したプログラムや設定を乗せます。
それにより、開発されたプログラムのみが実行されて見えるため、あたかもサーバが無いように見えます。
ユーザはサーバを導入する手間が省かれ、開発作業のみに集中できるため効率が格段に上がります。
また、サーバ故障の対応や[EOSL( End Of Service Life )](http://e-words.jp/w/EOSL.html)を気にする必要がなく可用性や保守性に長けています。

## 仮想コンピューターとサーバレスの違い
### 概要
AWS( Amazon Web Service )では仮想サーバ環境とサーバレス実行環境が提供されています。
仮想サーバ環境として、[EC2( Elastic Compute Cloud )](https://aws.amazon.com/jp/ec2/)があります。
一般的なIaas( Infrastructure as a Service )サービスであり、ラックに乗せたり、配線作業が必要なくワンクリックでサーバが立ち上がります。

一方サーバレス実行環境として[Lambda](https://aws.amazon.com/jp/lambda/)があります。
こちらは、自分で開発したソースコードを乗せるだけで、コードの実行ができます。
対応言語は以下の通りであり、[re:Invent2018](https://reinvent.awsevents.com/)の発表でRubyが追加されたので個人的に嬉しいです。
(2018年12月現在)

* Node.js( 6.10, 8.10 )
* Python( 2.7, 3.6, 3.7)
* Java( 8 )
* C#( 1.0, 2.0, 2.1 )
* Go
* Ruby( 2.5 )

さらに、Custom Runtimesという機能も発表されたので、好きな言語で書け、そのバージョンに悩まさせることは無くなりそうです。

### どのサービスを使っていいのか比較してみた
EC2とLambdaどちらを使えば良いのか選定する必要があったので、まとめてみました。

|                   |      EC2      |    Lambda    |
|:-----------------:|:-------------:|:------------:|
|     インフラ管理    |       あり      |     なし     |
|        料金        | 1時間あたりの課金 | 使用した分のみ課金 |
| 他AWSサービスとの連携/接続 | 基本的にAWS CLIを使用 | ロールを設定 |

特に料金については、Lambdaは1回の実行と使用したメモリ量、使用時間で加算されます。
100万回までの実行は無料であるため、非常にコストを抑えることができます。
さらに、LambdaはさまざまなAWSサービスと簡単に接続でき、使用するサービスの権限を与えるだけで使用できます。
EC2だと[DynamoDB](https://aws.amazon.com/jp/dynamodb/)などのマネージドなサービス接続する場合には、AWSのアクセスキーとシークレットキーを取得しCredentialに登録する必要があり手間がかかってしまいます。

個人的に利用するかつ、利用頻度が少ない場合に関してはLambdaを使用したほうがお得かと思います。


# 個人的なソリューション( ゴミ捨て当番通知bot )
私は他の人と共同で生活しており、ごみ捨て当番については物理的なカレンダーに記述していました。
誰も物理的なカレンダーは見ることなく忘れ去られてしまってました。
そこで、ゴミ捨て日の前日に当番の人にLINEで通知する仕組みを作れば、以下の要件が達成出来るので開発を開始しました。

* メンバー全体にゴミ捨て当番の共有
* 誰がゴミ出し当番なのかというログ

## サーバレスアーキテクチャ(構成図)
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/149402/05bc15b5-e307-3b6c-c425-849eb0c3043e.png)


ゴミ捨て当番通知botの処理
1. CloudWatch Eventsより、指定した時間にLambdaをキック
2. LambdaはDynamo DBと呼ばれるデータベースにアクセスし必要な情報を取得
3. 取得した情報をLINEに通知する

## LINEの通知画面
![モザイク.png](https://qiita-image-store.s3.amazonaws.com/0/149402/ba0b71ce-8cb2-285f-0a0a-1100f65a79e1.png)


日本語訳: 

```
以下のゴミを出していただけますでしょうか
* ビン
* カン
* ダンボール
* プラスチックゴミ
* ペットボトル
```

## 導入結果
かかったコストは¥40/月でした。
（このコストは開発時にCloudWatchLogsの転送量が多くなってしまったためです）
一般的なVPSを契約すると、一番安いタイプでも約¥1,000/月払うことになり、
自分稟議が通らない可能性があります。

ゴミ捨て自動通知botを導入してから2つの変化がありました。

* LINEに証拠を残しているので誰が当番かひと目で分かる
* 前日にゴミ捨て当番を投稿しているおかげでゴミ捨てが遅れることが少なくなった

# まとめ
今回はサーバレスアーキテクチャとはなんぞやという部分から始まり、個人的な問題解決、AWSのサービスを利用するまでの内容を書いてみました。
学生時代はAWS=無駄にお金が取られるというイメージが強く億劫になっていました。
しかし、実際にAWSサービスのサーバレスアーキテクチャを利用すると低コストでインフラ周りの管理が必要なくなるため、他のことにも注力することができました。
今後もサーバレスアーキテクチャを採用していく予定です。

P.S.
ゴミ捨て自動通知botのソースコードを[Github.com](https://github.com/mym-kingbob/GarbagePlan)に公開しておりますので、issueやプルリク大歓迎です🙏