AWS DevDay TOKYO 2019 day1 参加レポと個人的な感想

[（株）いい生活 サーバープラットフォームチーム](https://jobs.qiita.com/employers/e-seikatsu/development_teams/24) の多田 (@es-y-tada)です。
サーバサイドエンジニアとして、 [EKS](https://aws.amazon.com/jp/eks/) を基盤とした新規APIの開発・運用を行っています。
今回は先日行われた 
[AWS DevDay Tokyo 2019](https://aws.amazon.com/jp/about-aws/events/2019/devday/)  の1日目に参加させていただいたので、
個人的に印象的だったセッションのいくつかについてレポートします。

## 第一回AWSFargate簡単デプロイ選手権

* 原 康紘（アマゾン ウェブ サービス ジャパン株式会社）

https://aws-seminar.smktg.jp/public/session/view/215)

### 概要

> 本セッションは、AWS のオフィシャルツールを筆頭に、各種 OSS を使った Fargate へのコンテナのデプロイを考察し、みなさまの探究心をくすぐることをゴールとしています。
>
> コンテナに限らず、デプロイに関わるツールを選定するとき、人々は以下のようなことを考慮・検討します。
>
> - 簡単に利用できること 
> - 既存の開発・運用ワークフローやツール群とマッチすること
> - デプロイの仕組みを作り込む際に、必要十分なカスタマイズ性があること
>
> その上で、利用シーンもツールの選定に影響を与えます
>
> - 単にテスト的にコンテナをデプロイしたいのか、それともプロダクション環境に継続的にデプロイすることを前提としているのか
> - Web サーバーのような常駐プロセスをデプロイしたいのか、単発のジョブを実行したいのか
> - 誰(人間、CDサーバー)がデプロイを実行するのか
>
> 噛めば噛むほど味の出るデプロイメントの世界に本セッションを通して一緒に飛び込みましょう！

### 期待

私自身は普段は Kubernetes (EKS) をメインに利用していますが、弊社内では [AWS Fargate](https://aws.amazon.com/jp/fargate/) を活用しているサービス[^1]もあり、良し悪しについて度々疑問に思うことがあります。

「簡単」とよく聞く AWS Fargate 、もう一度学び直してみたいと思い（また、現在の動向知りたいと思い）聴講しました。

[^1]: 弊社の AWS 利用事例については https://speakerdeck.com/akipom/awswozui-da-xian-huo-yong-sitabu-dong-chan-ye-xiang-keb2bsabisufalsekuraudosihutoshi-li で詳しく解説しています

### 内容メモ

#### なぜ AWS Fargate なのか

ECS の場合を想像してみる

* EC2 でコンテナを運用する場合、 EC2 の運用業務が発生する
  * ISやエージェントのパッチ当て・更新
  * コンテナ・ホストマシンのリソース最適化・スケーリング
    * この部分の運用コストが二重化してしまっている
  * 運用業務は企業競争力に必ずしも繋がらない。どの会社でも当たり前にやっていることだから
* AWS Fargate
  * 仮想マシンを意識する必要がなくなる
  * コンテナを仮想マシンと同じレイヤの実体として扱える
    * ex. VPC の CIDR や SecurityGroup を直接コンテナにアタッチして扱える

#### Fargate を使ったデプロイ

概念的には

* Task Definition（コンテナイメージ、URL、CPU、メモリ、環境変数など） と Cluster を準備
* Task, Service を run する

```console
$ docker push ..
$ aws ecs register-task-definition ..
$ aws ecs create-service ..
```

#### もっとも簡単に Fargate でコンテナをデプロイする方法: [awslabs/fargatecli](https://github.com/awslabs/fargatecli)

例： docker hub にある nginx:latest を Fargate で動かす

* VPC にポート80を開放するSGを作る
* `fargate task run ..`
* `fargate service create ..`

例：ローカルのコンテナイメージを動かす

* Fargate CLI の実行ディレクトリの Dockerfile をビルド -> デプロイまで自動でできる

Fargate CLI が内部でやっていること

* デフォルトVPCにサプネット等を作成
* ECRレジストリの作成
* ECSクラスタの作成
* ECSタスク実行IAMロール作成
* ECSタスク定義
* ECSサービス定義

* SGはユーザが自分で準備やっておく必要がある

Pros

* 各種必要リソースが自動生成されるので、それを見て概念や各リソース定義の中身を勉強しやすい
* 細かい設定も可能だが、とにかく簡単

Cons

* 本番環境で使うには少々アドホック過ぎる
* Infrastructure as Code や CI/DI パイプラインについてはもう少し考えて環境が作りたいところ

turnerlabs/fargate の CLI のほうがもう少し運用に配慮したインターフェースになっている


#### Fargate に対応したデプロイサービス

* ECS 以外のAWSリソースもある
* どのようにロールバックするか

Fargate へのデプロイツールは fargatecli 以外にも多数ある[^1]
* AWSのサービスは MVP から始めて、ローンチ後に後方互換性を保ちつつ機能追加していくやり方なので、UCに合わせてユーザ側がうまく取り計らう必要がある

[^1]: https://github.com/nathanpeck/awesome-ecs#build-and-deploy-tools などを参照のこと

##### AWS Management Console

* 閲覧目的には良いが、継続的デプロイには向かない

##### [AWS CLI](https://aws.amazon.com/jp/cli/)

* Pros
  * 新サービスにも必ず対応、APIの呼び出しパラメータもほぼ全て利用可能
* Cons
  * CI/DI パイプラインの実体がシェル芸に
  * リソースの依存関係がコマンド実行順になる、ロールバックを書こうとすると複雑化しがち

##### [ecs-deploy](https://github.com/silinternational/ecs-deploy)

* Pros
  * 1つのシェルスクリプトの中で AWS API を読んでいるだけなので理解しやすい
  * コミュニティで揉まれているので自前で作るよりも安全
* Cons
  * Fargete 以外のリソースのプロビジョニング方法によっては折り合いが悪いことがある
  * 実体が単なるシェルなので魔改造したくなってしまう

##### [ECS CLI](https://github.com/aws/amazon-ecs-cli)

* Pros
  * docker compose を利用できる
  * ECS固有機能もサポート
* Cons
  * Fargete 以外のリソースのプロビジョニングを管理は自分でやる必要がある

##### [AWS CloudFormation](https://aws.amazon.com/jp/cloudformation/)

* Pros
  * 全てのAWSリソースを用意できるため1つのツールで済む
  * Infrastructure as Code 
  * 予定される変更差分も見られる
  * AWSリソース間の依存関係も定義できる
  * CI/DI との相性も良い
* Cons
  * AWSリソースを十分に知る必要
  * 最新のパラメータがサポートされるまでには時間がかかることもある
  * ライフサイクルの異なるリソースの管理は難しい

##### [AWS CDK](https://github.com/aws/aws-cdk)

* Pros
  * プログラムを書いているようにかける
  * ユニットテスト書きやすい
* Cons
  * 抽象度が高いことは良し悪しあり

##### [ecspresso](https://github.com/kayac/ecspresso)

* Pros
  * 薄いラッパ
  * must_env とかができる
* Cons
  * AWS CLI と同様

#### プラグイン 

VSCode の ECS 用プラグインがちょうど利用可能になっている

* https://aws.amazon.com/jp/about-aws/whats-new/2019/10/amazon-elastic-container-service-now-supports-intellisense-in-visual-studio-code/
 
### 所感

コンテナ化したアプリケーションをとりあえず動かしてみたい！という用途であれば fargatecli すごく良さそうに感じました。
ただセッション中も言われてましたが、プロダクションで使うものではなさそう。

特に EKS 使っている身としては、EC2 と Fargate どちらがよりおいしいかというのは聞いていて気になったところ。
EC2インスタンスのサイジングを考えなくて済むメリットもわかる一方、見えているからこそ柔軟にカスタムできる良さもあるので、唯一解はなく構築したいシステムの状況やフェーズに合わせて選択していくもの、ということなのだと思います。

また、現状 ECS Fargate では 永続ストレージ(ブロックデバイス/ファイルシステム)が 使えないことや、EC2 ECS に比べるとタスク起動オーバーヘッドが大きいことも気になります（いずれ解消されていくのかもしれませんが）。

EKS か ECS  かという点で考えたことも記載しておきます。

* ECS であってもプロダクションレベルのシステムを準備しようとすれば、 CloudFormation 含めたテンプレートファイルの記載は避けては通れない
    *  EKS のほうが考慮事項や記述量は増えるので、この手間の差とカスタマイズ可能というメリットを天秤にかけてどちらをとるか
    *  デプロイの手間で言っても、結局テンプレートは書かねばならないことを思うと変わらないと思われる。むしろ EKS (Kubernetes) なら `kubectl apply -f/-k` で一発ではある
*  ECS Fargate 選択した場合、特に永続ストレージ使えないとなるとクラスタの中で立てられるアプリケーション/ミドルウェアに制約ができるので、そのあたりまで含めてマネージドサービスで賄うという判断ができるかどうか
    *  例えば [ElastiCache](https://aws.amazon.com/jp/elasticache/) でなく自前で Redis 立てるほうがコスト的に優位という場合でもその選択肢がとれない（ Fargate では立てられない）

---

## マルチテナント時代におけるテスト・ベストプラクティス

清水  毅（アマゾン ウェブ サービス ジャパン株式会社 パートナーソリューションアーキテクト）

* https://aws-seminar.smktg.jp/public/session/view/263

### 概要

> 「WEBアプリケーションにおけるテストは非常に悩ましい問題ですが、テストコードやCIツールでのテスト、あわせてTestサービスのSaaSを利用するなどされていると思います。最近では、さらにマルチテナントにおけるテストが更に実施に悩まれている状況をよくお聞きします。どのようにテストをしていけばいいのかをおさらいとなるような初歩的な内容を含めてまとめます。特にSecurity観点とPerformance観点でどのような考慮点があってどのようなテストが求められるのかについて検討していきます。」 下記コンテンツをベースに負荷テスト・セキュリティテストについてまとめる予定です。（下記はAWSサービスは関係がないのですがAWSセキュリティサービスなど絡めることを考慮します） Testing SaaS Solutions on AWS https://aws.amazon.com/blogs/apn/testing-saas-solutions-on-aws/

### 期待

弊社はまさにマルチテナントに向けた [SaaS](https://www.e-seikatsu.info/service/) を提供しており、セッション概要はまさしくドンピシャでした。

特に、「マルチテナント × テスト」という（一般にはおそらく）珍しい組み合わせに興味を持ち、聴講しました。

### 内容メモ

#### マルチテナントの基本

このセッションでは「マルチテナント ≒ SaaS」と定義する。

#### マルチテナントの特徴

* 使用量やユーザ数で課金
* オンデマンドでセルフサービス
* マルチテナントでインフラを共有
* 柔軟な使用量

そもそも、マルチテナントは運用コスト・インフラコストをダブルダウンするのが重要な目的。
インフラ・運用コストは抑えないと競争力が弱まるので、SaaSでは規模やステージに合わせたインフラや運用方法が大事。

* マルチテナントのパフォーマンス
  * 需要に対してインフラの供給をスケールさせたい（コストをマッチさせる）
* マルチテナントのセキュリティ
  * マルチテナント固有のセキュリティというものがありこれを意識する必要がある

#### SaaSアプリケーションの典型的なアーキテクチャ

* 認証
  * ユーザ・テナント登録、ユーザ管理、テナントレベル別システムサポート（_ティア_ とも。ライセンスによる使える機能の違いなど）
* テナント分離
  * 動作させるマシンやアプリケーション自体を分離するかどうか
  * 分離するほどセキュアな一方、コストは増加
* データパーティショニング
  * データを分離するかどうか、分離するとしてもどのレベルでやるか
  * 分離するほどセキュアな一方、コストは増加
  * RDB の限界との戦いでもある

#### テスト

マルチテナントに限らず、パフォーマンステスト・セキュリティテストに強いエンジニアというのは意外と少ない。

##### パフォーマンステスト

どこに基準・目標を定めるか？が非常に重要

* **UX** に基づき **レイテンシ・スループット** などの目標を設定
* 限界性能テスト・耐久テストも忘れない
  * 長時間走行時のメモリリークでアプリケーションがクラッシュするなどはよくある話

##### セキュリティテスト

* ブラックボックステスト
* ホワイトボックステスト
* グラスボックステスト

#### マルチテナントテスト

マルチテナントに固有と言えるのはサービステストのレイヤ

* ユニットテスト、一般的なウェブアプリケーションのテストだけでなく、継続的テスト・モニタリングが必要

#### SaaS Operations: A higher DevOps bar

* 次のようなサイクルをうまく回していく必要がある
  1. Speed
  2. Rapid delivery
  3. Scale
  4. Security
  5. Zero downtime
  6. Collaboration

#### ベストプラクティス

1. テナント負荷
  * マルチテナントの予測不能な負荷によるパフォーマンス問題を表面化させる
  * ex. あるテナントAのオペレーションによってテナントBのパフォーマンスが悪化する
2. テナント分離
  * 認証認可のような _ビジネス要件_ にまつわる脆弱性は一般のwebアプリケーションセキュリティテストでテストできない
3. テナントライフサイクル
  * テナントのユーザ体験としてのテスト
  * テナント内のユーザの一貫した体験・ワークフローがうまく回っているか
4. ティア境界
  * 契約レベル=ティア
  * ポリシー通りかどうかをティア毎に分類したモニタリングと合わせて実施
5. フォールトトレランステスト
  * 本番で実測 _しておく_ こと
  * GameDay を設けられると最良

#### Tips

* そもそも可観測性を持ったシステムにしておかないと、いくらテストしても原因特定に至らない可能性がある
* 「たまに遅い」は GC を疑う
* 本番環境でのテストをやること
* [AWS SaaS Portal](https://aws.amazon.com/jp/partners/isv-saas-portal/)
  * パッケージベンダー向けのサポート・プラクティスなどがまとめられている

### 所感

Webサービスに必要な基本的なテストの復習と、そこに加えて マルチテナント の SaaS 事業者として必要なテストとは？というところまで踏み込んだ素晴らしいセッション。
セッション中は「本当に徹底的にテストできていますか？」という講演者の思いがビシバシと伝わってくる感じがしました。

引き合いに出されていた課題はまさしく自分のことのように腑に落ちました。
日頃立ち向かっている課題が改めて言語化され、対応していくためのプラクティスとして整理されたことで非常にすっきりとした気持ちになりました。

* テナント分離レベルとコスト・パフォーマンスリスク/セキュリティリスクとの間でのトレードオフは避けては通れないし、悩ましい部分
* 非機能観点がテストから漏れやすいことは度々課題になる話。エンジニアの習熟度の問題と片付けるのは簡単ですが、非機能テストの観点を Webサービス、 SaaS ではどのように定めるべきかがわからない（難しい）というのが本質的にはあるのかもしれません
  *「パフォーマンス目標は UX 目標を元に定める」、当たり前ですが改めて心に刻んでおくべき考え方

個人的には1日目の **ベストセッション** 。もっと早く聞きたかった・・・

## AWS の隙間を埋めるOSS開発

藤原 俊一郎（株式会社カヤック）

* https://aws-seminar.smktg.jp/public/session/view/549

### 概要

> AWSのマネージドサービスは運用の省力化に大変ありがたいものですが、各サービス間の連携が完璧なものばかりではありません。AWSにおける長年のシステム運用を通じて、各サービスの隙間を埋めるOSSや公式にサポートされていないSDKを開発することで、よりよい運用を目指してきました。なぜOSSにするのか、どのような思想で設計、開発、運用をしているのかを、実例をもとにご紹介します

### 期待

AWS のサービス間連携に悩むのは使い始めるとあるあるなのではないでしょうか。
普段は OSS は使う側の立場ですが、どのように思考して作られているのか気になり、聴講しました。

また、[原さんのセッション](##第一回AWSFargate簡単デプロイ選手権) でおすすめされたセッションでもあります。


### AWSの「隙間」とは

AWSのマネージドサービスはローンチ時はコア機能のみの状態から成長していく

* 追いつくまでは足りない部分がある
* 例：10年前にリリースされたサービスだが、RDSのログが CloudWatchLogs に流れるようになったのは結構最近

パッチ運用・バージョンアップなどの人的コストを払えないのなら、多少不便でもマネージドサービスを利用すべき

#### 隙間家具を作る

* 小さく、そのUC内で適切な汎用度を持ったものを、マネージドサービスが対応したら **捨てる** つもりで作る

### 「隙間家具」OSSの実例と設計思想

以下の OSS は藤原さんの作成物であり、 GitHub で [公開中](https://github.com/fujiwara)

### [Rin](https://github.com/fujiwara/Rin)

* [Redshift](https://aws.amazon.com/jp/redshift/) へデータを取り込むためには Redshift へ S3 にコピーするリクエストを発行する必要がある
  * S3 への put イベントをフックしてコピーを発行
  * fluentd の plugin に Redshift のコピーを発行するものがあったので使っていたが、 Redshift がメンテナンスで停止するときにコピーが失敗してしまう
  * このときのリトライ処理で、 S3 への put と Redshift のコピー全体をリトライしてしまうため使いづらかった
  * S3->Redshift の部分の小さな隙間を埋める思想で Rin を開発
  * Firehose が登場して元々の用途では要らなくなったが、 ELB/ALB のログを送るのには使えている（適度な汎用性だった）
  * **マネージドになったときにきれいに取り外せる設計が大事**
  * リトライ設計が大事

### [s32cs](https://github.com/fujiwara/s32cs)

* [CloudSearch](https://aws.amazon.com/jp/cloudsearch/) にデータを継続的に取り込む方法が現状もマネージドにない
* S3のイベントをフックして、データの変換+CloudSearchへ投入
  * json を配列形式に変換しなくてはいけなかった
* firehose -> S3のイベントフック（データドリブン）は結構便利（定期実行バッチよりも可用性が高まる、分散処理などもやりやすい）
  * firehose は吐き出しを秒数とサイズの両方で指定でき、サイズの制御ができるので、安心してオンメモリに積んだりできる
* 状態はマネージドサービスに起き、状態を持たない処理だけ書くとスケールが簡単

### [ssmwrap](https://github.com/fujiwara/ssmwrap)

* [SSM](https://aws.amazon.com/jp/systems-manager/) Parameter Store の値を環境変数に設定してコマンドを exec する wrapper
  * 類似品はたくさんある
* ECS task に SSM の値を渡すために開発
* コンテナのエントリポイントに使える、パラメータストアがエラーの場合のリトライが設定可能、変数を指定ファイルに書き出す機能
  * パラメータストアの RPS が 1000 で割とすぐ死ぬので
* ECS はすぐに対応したが、 EC2 や AWS外でも使えるので便利に使っている
* Go のライブラリとしても使える

将来マネージドになりそうなものでも、アプリケーションベタ書きで解決せずに小さいコード・ツールに切り出したほうが良い

* 直書きすると密結合するので改修しづらい
* ライブラリになっていないコードをコピペして別プロジェクトで使われると・・・

### OSS として作る

自分たちしか使わなくても OSS にしてしまったほうがよい

OSSにするならどうなるか考えるようになってよい

* ドキュメントを書く気にもなる
* 社内事情の混入を防ぐ
  * 責任分界点を見極めることで設計きれいになる
* 魔改造を防ぐ

ツールを作って隙間が解決したとしても、AWS にサポートケースに要望をきちんと伝えること

### 所感

「うまい抽象度でツール化する」というのが、センスが要求される難しいところだと思いながら聞いていました。

コピペによって、オリジナルの開発者が認知していない謎の fork が増えていく現象はありがちなので、（社内的な事情もあるでしょうから） OSS までいかなくとも、社内に _公開_ して、使い方を定める活動は進めていくべきなのかもしれません。

本筋ではありませんが、このようなツールをバイナリで配布できる Go が少しうらやましく感じました。普段は Python ばかり書いているので・・・

---

## 40分でわかるDynamoDBでのApp開発

成田  俊（アマゾン ウェブ サービス ジャパン株式会社 ソリューションアーキテクト）

* https://aws-seminar.smktg.jp/public/session/view/556

### 概要

> Amazon DynamoDBはフルマネージドサービスで提供されるkey-value およびドキュメントデータベースです。世界中でもAmazonを始め多くのユーザーに利用されており、是非このセッションでDynamoDBを利用した開発の導入部分を学んで頂きたいと考えています。 本セッションではpythonで書かれたサンプルアプリを例として主要なデータ操作、よく比較されるRedisとのユースケースでの使い分けなどを解説します。 是非アプリケーション開発でDynamoDBを導入する手助けになれば幸いです。

### 期待

普段は主に RDB （MySQL や Aurora for MySQL）を使ったサービスの開発をしているのですが、クラウド化/クラウドネイティブ化の流れの中で、 [DynamoDB](https://aws.amazon.com/jp/dynamodb/) を始めとするサーバレスデータストアには興味がありました。

今回は DynamoDB を使ったアプリケーション開発をなんと 40分で理解できるということで、聴講しました。

### 内容メモ

#### Introduction

"You build it, you run it" - Werner Vogels

* 作った人が運用もやる
* メンテナンスフリーなマネージドサービスを使えることはプログラマにとってうれしいこと

Table構造

* Table, items(行), attributes(列), PartitionKey(主キー), SortKey（relationship,query）
  * PartitionKey と SortKey 以外は attribute に抜けがあっても良い（スキーマレス）

[NoSQL Workbench for Amazon DynamoDB](https://aws.amazon.com/jp/blogs/news/nosql-workbench-for-amazon-dynamodb-available-in-preview/) が preview で公開されている

* 一通りの操作が可能
* 作ったクエリを発行するための python などのコードを生成可能

demoアプリを作ってみる

API GateWay -> Lambda([Chalice](https://github.com/aws/chalice)) -> DynamoDB

DynamoDB でモデリングするには？

* Redis の Stream型やSortedSet型とはまた違ったモデリングをする
* PertitionKey+SortKey と GSI にわける
* 書き込みをスケールさせるためには、キーが集中しないものを PertitionKey にするほうが効率的
  * 一度書いてから、 DynamoDB Stream と組み合わせる（ElasticSearch なども裏で使える）

* put時のオプションで消費したユニットの取得やデータが存在するかどうかのチェックなども行える
* クエリ時に利用するインデックスを指定
* `LastEvaluatedKey` でページング

DynamoDB streams

* Lambda で DynamoDB のイベントをフックし、 Redis の cache に積んだり
* Lambda -> Kinesis という技もある

#### CI・テストをどうするか

* AWS内で解決できるならやはりCodeBuildなど
* テーブル名が conflict する可能性があるので毎回 table 名をユニークに新規作成するのが楽
  * 並列数が大きすぎると DynamoDB の API の limit に引っかかる可能性もある
* DynamoDB Local を活用するのも手（コンテナ or jar）
* CodeBuild の場合は同一コンテナ内で DynamoDB-local のプロセスとアプリケーションプロセスの両方を実行する必要あり

### 所感

DynamoDB はキー設計がキモ、かつ従来のデータストアとは違うところも多いので、ずっと RDB やってきたゆえに難しいところだな、と思いました。
NoSQL Workbench for Amazon DynamoDB はまたプレビュー版だそうですが、大変使いやすそうですしさっそく触ってようと思います。

「とりあえずサーバサイドの App 作ってみたい」という場面で、 DynamoDB + Chalice は最良に近い選択肢かもしれません。
Chalice が Lambda から [API Gateway](https://aws.amazon.com/jp/api-gateway/) 、必要な IAM Role まで含めてコマンド一発で 作ってくれるのは、初学者には大変ありがたいことだと思います（僕の場合普段から Python, [Flask](https://a2c.bitbucket.io/flask/) を使っているからこその贔屓目もあるんですが）。

## 全体所感

General Session でも触れられていましたが、 AWS Summit に比べるとセッションがエンジニア向けの内容にフォーカスされていると確かに感じました。

* すでに利用していてより使いこなしたいもの
* まだ利用していないがこれから試してみたいもの

など、バランスよく学ぶことができたのもよかったと思います。

### 個人的な総括

* クラウドを前提とした世界観では、利用する技術やアーキテクチャもサービスのフェーズに合わせて変化させたほうが良い。どのフェーズにも完全にマッチするという技術はそうそうありえない
* AWS のサービスも変化・改良が進んでいくため、柔軟に取り入れられるようなアーキテクチャにしておくと恩恵を受けやすい
* システムのモダン化・開発サイクルの高速化していくうえで、徹底的にテストする仕組みは最重要とも言える。従来のテスト項目も漏れなく行いつつ SaaS 特有の事情についてもテスト項目に加えて、本番環境含めたテストを継続的に行うべし

次回以降も楽しみなイベントになりました。

## さいごに

株式会社いい生活では「不動産テック」領域で共に成長し、付加価値を生み出す仲間を募集しています。

https://jobs.qiita.com/postings/197