Infrastructure as "型付き" Code - 急成長する事業のインフラ再構築

Infrastructure as "型付き" Code - 急成長する事業のインフラ再構築

2020/09/10 BIT VALLEY 2020 で発表したスライドです。

### セッション動画
後日公開予定: https://www.youtube.com/channel/UCRnovD89VB0GQDXfpTvIZ4A

### ブログ記事
BIT VALLEY 2020 にて『 Infrastructure as "型付き" Code - 急成長する事業のインフラ再構築 』を発表しました - エムスリーテックブログ
https://www.m3tech.blog/entry/2020/09/14/110000

### BIT VALLEY 2020
- https://2020.bit-valley.jp/

### 参考資料
- 野村 友規 (2019) 『実践Terraform AWSにおけるシステム設計とベストプラクティス』 インプレスR&D
- Kief Morris (2016) 『Infrastructure as Code』 O'Reilly Media, Inc.
- TypeScript Documentation https://www.typescriptlang.org/docs
- TypeScript Deep Dive 日本語版 https://typescript-jp.gitbook.io/deep-dive/

### 資料に記載した URL
- Introducing the Cloud Development Kit for Terraform (Preview) | AWS Developer Blog https://aws.amazon.com/jp/blogs/developer/introducing-the-cloud-development-kit-for-terraform-preview/
- AWS CloudFormation のクォータ - AWS CloudFormation https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html
- [ECS][Fargate]: Add EFS volumes through CloudFormation · Issue #825 · aws/containers-roadmap https://github.com/aws/containers-roadmap/issues/825

D833ebe946fb6c3ca990758737855f79?s=128

typewriter / takuya

September 10, 2020
Tweet

Transcript

  1. Infrastructure as "型付き" Code 急成長する事業のインフラ再構築 2020/09/10 @ BIT VALLEY 2020

    エムスリー株式会社 ソフトウェアエンジニア / SRE 山口 卓也
  2. 本セッションで話すこと 急成長する事業の裏側 ◦ 複雑化するインフラ ◦ スケールしない一部サービス これらの状況を解決するために どのようにしてインフラ再構築を進めているか? 2

  3. 山口 卓也 / @no_clock エムスリー株式会社 ソフトウェアエンジニア / SRE • Ruby,

    C#, 京都, 猫が好き • 大手 SIer (6 年) → エムスリー (2 年) • 小学 5 年でプログラミング (VB6) • 中学 3 年で「 P2P 地震情報」を公開 • 今もサービス運用中 (15 年以上) 3
  4. クラウド電子カルテ「エムスリーデジカル」 カルテ(診療録)作成を含む クリニックの「受付」「診察」 「会計」を支える Web サービス • 2015/10 サービス開始 背景

    課題 立案 実行 まとめ 4 AWS: ECS (EC2, Fargate), S3, SQS, ELB, RDS (Aurora/PostgreSQL), … 言語/FW: Ruby on Rails, Scala, Node.js / TypeScript, Swift (iPad App), …
  5. 急成長する事業 x10 2 年間で 利用施設数は 10 倍 背景 課題 立案

    実行 まとめ 5
  6. 急成長する事業 x10 2 年間で 利用施設数は 10 倍 8 チームの エンジニア人数

    背景 課題 立案 実行 まとめ 6
  7. 急成長するインフラ [5 年前] 施設数 1 → 100 ☑ Configuration Management

    (Ansible) ☐ Infrastructure Definition (Terraform) ☑ 主要サービスのコンテナ化 ☐ 主要サービスの ECS 化、オートスケール • EC2 インスタンス 十数台 • 手作業でぬくもりのあるスケール作業 背景 課題 立案 実行 まとめ 7
  8. 急成長するインフラ [2 年前] 施設数 100 → 1,000 ☑ Configuration Management

    (Ansible) ☑ Infrastructure Definition (Terraform) ☑ 主要サービスのコンテナ化 ☑ 主要サービスの ECS 化、オートスケール ほぼスケーラブルなインフラ完成 背景 課題 立案 実行 まとめ 8
  9. 急成長するインフラ [半年前] 施設数 1,000 → 10,000 ☑ IaC, 主要部分のオートスケール ☑

    全サービスのコンテナ化 ☑ SQS 活用、 ECS クラスタ分割等   のスケーラビリティ改善 ほぼスケーラブルだから、 このままスケールさせればヨシ! 背景 課題 立案 実行 まとめ 9
  10. 背景 課題 立案 実行 まとめ 10 ほぼスケーラブルだから、 このままスケールさせればヨシ! (よくない)

  11. 急成長するインフラは複雑さを増す 増え続けるインフラ • 管理対象は 2 倍以上 • コード量は 3 倍以上

    複雑さが増すインフラコード • 微妙なモジュール構成 • 長い長い値の引き回し 背景 課題 立案 実行 まとめ 11
  12. 急成長するインフラは複雑さを増す 「割れ窓」「作業ミス」… • IaC を部分適用しはじめる (実態との差が残り続ける) • 適用対象を選ぶ手間が増える • 適用対象を間違える

    • 不具合の原因に 「 IaC の適用漏れ」 が加わり調査が難しくなる 背景 課題 立案 実行 まとめ 12
  13. 急成長するインフラに近づく限界 最大までスケールアップした RDS • db.r4.16xlarge (R4 で最大) • vCPU: 64,

    Mem: 488 GiB 主要でないサービスはスケールしないまま • ECS だがスケールはしない (コンテナ化、自動復旧が目的) • 当初設計で想定していない 成長ステージに突入 背景 課題 立案 実行 まとめ 13
  14. 次のステージに向けた課題 施設数 1,000 → 10,000 • 複雑化するインフラを うまく管理したい • RDS

    と主要でないサービスも スケーラビリティを確保したい 背景 課題 立案 実行 まとめ 14
  15. 課題をどう乗り越えるか ※実際はリモート チームで議論 • 解決策の立案、技術選定 ◦ チームに裁量がある (運用まで責任を持つ) • チームを超えて相談

    ◦ Slack 、雑談、その他 ◦ CTO にも気軽に相談 • ビジネスサイドも理解し、 尊重してくれている 背景 課題 立案 実行 まとめ 15
  16. アイディア ざっくりした検討結果 チューニング、負荷軽減 10,000 施設までスケールしない RDS シャーディング 多くの場合アプリケーションでの考慮が必要 複雑さが増す、開発スピードが落ちる 主要でないサービスの

    再設計、再実装 スケールさせる代わりにサービスの複雑さが増す 10,000 までスケールするか不透明 DBMS の変更 テーブル・クエリの再設計が必要 (アプリも修正) システム全体の水平分割 (シャーディング) インフラの複雑さが大幅に増すが、 アプリケーションの修正はほぼ無し 課題をどう乗り越えるか スケーラビリティ編   インフラ管理編 背景 課題 立案 実行 まとめ 16
  17. 課題をどう乗り越えるか スケーラビリティ編   インフラ管理編 アイディア ざっくりした検討結果 割れ窓の修復 10,000 施設までは耐えられない ドキュメント整備 ミスは減るが手間は減らない Terraform

    コード書き直し 水平分割したシステムの表現・管理が難しい 肥大化する tfstate の分割・管理が必要 別の IaC ツールに移行 - AWS CDK + TypeScript 全面書き直し・ツール学習コスト等の問題あるが 自動化・効率化・水平分割の表現がしやすい 背景 課題 立案 実行 まとめ 17
  18. 課題を乗り越える スケーラビリティの確保 システム全体の水平分割 (シャーディング) 18 複雑化するインフラの管理 別の IaC ツールに移行 AWS

    CDK + TypeScript 背景 課題 立案 実行 まとめ
  19. 課題を乗り越える スケーラビリティの確保 システム全体の水平分割 (シャーディング) 19 複雑化するインフラの管理 別の IaC ツールに移行 AWS

    CDK + TypeScript 背景 課題 立案 実行 まとめ
  20. イメージ図 スケーラビリティの確保:  システム全体の水平分割 構成 • 同じシステム構成(シャード) を複数用意 • 各サービスは原則変更なし (シャードを意識しない)

    • 施設はいずれかのシャードに所属 • 約 300 施設ごとに 1 シャード 背景 課題 立案 実行 まとめ シャードC 施設601~900 シャードB 施設301~600 シャードA 施設1~300 20
  21. スケーラビリティの確保:  システム全体の水平分割 欠点 • シャード間のデータ参照は不可  →カルテは相互参照しない  →薬剤等のマスタは複製 • 管理対象のインフラ増加 •

    リリース管理がシャード毎に  →ラッパーツールで   緩和 (後述) 利点 • 原則インフラ変更のみ ◦ サービスへの機能追加の スピードを維持 • 約 300 施設で 1 シャード ◦ 運用ノウハウのある規模 (スケールしないサービスも大丈夫) ◦ リリースやテーブル変更も シャード毎に可能 ◦ 障害発生時の影響を局所化 背景 課題 立案 実行 まとめ シャードC 施設601~900 シャードB 施設301~600 シャードA 施設1~300 21
  22. 課題を乗り越える スケーラビリティの確保 システム全体の水平分割 (シャーディング) 22 複雑化するインフラの管理 別の IaC ツールに移行 AWS

    CDK + TypeScript 背景 課題 立案 実行 まとめ
  23. 複雑化するインフラの管理:  IaC: AWS CDK + TypeScript AWS CDK (Cloud Development

    Kit) • 2019/07: GA (一般提供) • プログラミング言語で IaC • CloudFormation 経由で プロビジョニング (*1) TypeScript • 2020/08: TypeScript 4.0 • JavaScript + 型システム AWS CDK 薄いラッパーツール Cloud Formation (*1) プレビュー版として CDK for Terraform もある: Introducing the Cloud Development Kit for Terraform (Preview) 背景 課題 立案 実行 まとめ 23
  24. 複雑化するインフラの管理: IaC: AWS CDK + TypeScript  による Ruby on Rails

    サービスの表現 構成図抜粋 2 つの ECS クラスタ • オンライン (API サーバ) • バッチ (DelayedJob) クラスタ間の違い • スケーリング、起動コマンド • ロードバランサの有無 背景 課題 立案 実行 まとめ 24
  25. 複雑化するインフラの管理: IaC: AWS CDK + TypeScript  による Ruby on Rails

    サービスの表現 スケーリング、起動コマンドの違い サブクラスで定義するだけ • RailsAppEcs 抽象クラス ◦ RailsAppApi サブクラス ◦ RailsAppBatch サブクラス 背景 課題 立案 実行 まとめ 25
  26. 複雑化するインフラの管理: IaC: AWS CDK + TypeScript  による Ruby on Rails

    サービスの表現 背景 課題 立案 実行 まとめ 26 オンライン 固有定義 LB設定 バッチ 固有定義 (まだない) 共通定義 EcsApp Pattern Props EcsBatchAppPatternProps EcsHttpAppPatternProps ロードバランサの有無の違い • TypeScript の型システムを活用 • Intersection Types (&) • Union Types (|)
  27. 複雑化するインフラの管理: IaC: AWS CDK + TypeScript  による Ruby on Rails

    サービスの表現 背景 課題 立案 実行 まとめ 27 ロードバランサの有無の違い • TypeScript の型システムを活用 • Intersection Types (&) • Union Types (|) • 分かりやすい、重複がない • Ruby on Rails 以外の サービスでも再利用可能 バッチ Ecs BatchApp Pattern Props オンライン Ecs HttpApp Pattern Props
  28. 複雑化するインフラの管理: IaC: AWS CDK + TypeScript  による Ruby on Rails

    サービスの表現 (おまけ) 環境ごとの設定値の差 • Mapped Type TypeScript サポート (VSCode) • 補完、定義ジャンプ、参照検索 がしっかり効く 背景 課題 立案 実行 まとめ 28
  29. 課題を乗り越える スケーラビリティの確保 システム全体の水平分割 (シャーディング) 29 複雑化するインフラの管理 別の IaC ツールに移行 AWS

    CDK + TypeScript 背景 課題 立案 実行 まとめ 水平分割で生まれる課題に… 薄いラッパーツール
  30. 水平分割で生まれる課題に…  薄いラッパーツール 水平分割で大量に増えるインフラの 自動的・効率的な管理 • Stack (tfstate 相当) の管理 •

    Stack の依存関係の可視化 • CloudFormation の 面倒なところの隠蔽 • 差分表示及びレビュー管理 • 実行ログの記録、 Slack 通知 AWS CDK 薄いラッパーツール Cloud Formation 背景 課題 立案 実行 まとめ 30 シャードC 施設601~900 シャードB 施設301~600 シャードA 施設1~300
  31. 水平分割で生まれる課題に…  薄いラッパーツール 水平分割で大量に増えるインフラの 自動的・効率的な管理 • Stack (tfstate 相当) の管理 •

    Stack の依存関係の可視化 • CloudFormation の 面倒なところの隠蔽 • 差分表示及びレビュー管理 • 実行ログの記録、 Slack 通知 背景 課題 立案 実行 まとめ 31 シャードC 施設601~900 シャードB 施設301~600 シャードA 施設1~300
  32. 複雑化するインフラの管理:  IaC: AWS CDK + TypeScript 良い点 • CDK や

    CloudFormation の API が充実、自動化しやすい • 自由度が高く柔軟 • TypeScript の型システムを活用 ◦ 分かりやすい、間違いにくい ◦ ライフサイクルが比較的長いインフラを堅実にコード化 • Node.js エコシステム 背景 課題 立案 実行 まとめ 32
  33. 複雑化するインフラの管理:  IaC: AWS CDK + TypeScript 微妙な点 • AWS ロックイン

    • CloudFormation の制限や仕様 ◦ リソース数やテンプレートのサイズ制限 (*1) ◦ ドリフト検出(コードと現状との差分検出)の誤検出 ◦ 新機能の対応が Terraform より遅い場合も (*2) • CDK の型定義が完全ではなく、時折 any が出現する • 自由度が高いのでスパゲッティコード化しやすい • Node.js / TS の進化速度とインフラの進化速度のズレ (*1) AWS CloudFormation のクォータ - AWS CloudFormation (*2) [ECS][Fargate]: Add EFS volumes through CloudFormation · Issue #825 · aws/containers-roadmap 背景 課題 立案 実行 まとめ 33
  34. メリット・デメリットあるが 総合的には良さそう! 本番稼働に向けて絶賛作業中! 34

  35. Infrastructure as "型付き" Code 急成長する事業のインフラ再構築 スケーラビリティの確保 • システム全体の水平分割 (シャーディング) 複雑化するインフラの管理

    • AWS CDK + TypeScript での Infrastructure as Code We’re hiring! 興味があればカジュアル面談で! 背景 課題 立案 実行 まとめ AWS CDK 薄いラッパーツール Cloud Formation シャードC 施設601~900 シャードB 施設301~600 シャードA 施設1~300 35