Beyond the Twelve-Factor App の目的とやること

5 min read読了の目安(約5200字

この文書はなにか

Beyond the Twelve-Factor App [1] は良文書だと思うのですが、それぞれの項目の目的や理由が明確ではないように思えました。言うまでもないことなのかもしれませんが、はっきりしていないと不安かなとも思います。

Beyond the Twelve-Factor App には以下の15の項目があります。優先順位順です。

  1. One codebase, one application
  2. API first
  3. Dependency management
  4. Design, build, release, and run
  5. Configuration, credentials, and code
  6. Logs
  7. Disposability
  8. Backing services
  9. Environment parity
  10. Administrative processes
  11. Port binding
  12. Stateless processes
  13. Concurrency
  14. Telemetry
  15. Authentication and authorization

本文書ではそれぞれの目的とやることをすくいあげてまとめてみました。 一部私の勝手作文になっているところもあります。私の理解不足や勘違いで元文書の意図を誤解しているところがあるかもしれません。間違いの指摘を歓迎します。[2]

元文書の背景

Beyond the Twelve-Factor App の前段として、The Twelve-Factor App [3] という文書があります。これは、Software as a Serviceを作り上げるための方法論について書かれたものです。herokuの人が書いています。

Beyond the Twelve-Factor App はもとのTwelve-Factor App について内容の追加と詳細化を行なったものです。pivotalの人が書いています。

1. One codebase, one application

何のために

  • ビルド、デプロイを自動化したい。アプリが複数リポジトリに分かれていたら自動化が難しくなる。
  • 複数アプリや複数チームで1個のリポジトリを共有していたら、コンウェイの法則[4]に従うほうが自然である。

何をする

アプリとリポジトリは1対1にする。1個のコードベースというのは、共通のルートを持つ複数リポジトリでも良い。

2. API First

何のために

  • ユーザストーリーや機能について利害関係者との議論を持てるようなリソースが欲しい。
  • ほかシステムとの結合作業する際の失敗を避けたい。

何をする

APIを開発プロセスの第一級の成果物とする。 [5]

3. Dependency Management

何のために

アプリケーションが稼働環境の設定に依存しないようにしたい。繰り返し可能なデプロイをしやすくしたい。

何をする

依存するライブラリやツールをアプリごとに定義する。
稼働環境に何があるか、どんなライブラリやツールがあるかについては何も前提を置かない。

4. Design, Build, Release, Run

何のために

開発者の安心を保ちながらリリーススピードを上げたい。

何をする

開発から運用のフローを、設計、ビルド、リリース、実行の4つに分ける。それぞれ独立に実行させる。詳細は以下の通り。

設計

次にリリースされる機能について設計する。
全体的な設計はあるが変化するものであるので、イテレーション毎に少しずつ行う。
また、この段階で依存するライブラリについても決定する。

ビルド

コードがバイナリアーティファクト(=ビルド)に変換される。CIツールが使われるべきである。
1個のビルドが複数の環境にリリースされるかたちになる。(テスト、QA、本番など)
「私の環境でしか動かない」問題が起きていたら、本項の4ステップが正しく分離されていないことを意味する。

リリース

ビルドに環境ごとの設定やアプリ固有の設定を施して、リリースとなる。
リリースにはそれぞれユニークなIDが付けられて、かつ不変であるべきである。
トラブルシューティングやロールバックにも活用できる。

実行

環境にリリースされたものをクラウドプロバイダーが実行させる。
クラウド実行環境はアプリを実行させ、ヘルスチェックし、ログを取ることに責任を持つ。また、動的スケールや耐故障性のための管理タスクも同様である。

5. Configuration, Credentials, and Code

何のために

環境毎に異なる設定とコードを同じ管理下に置くと、環境毎設定を管理するのが大変になる。認証情報とコードを同じ管理下に置くと、多数の開発者が見ることができて好ましくない。

何をする

設定・認証情報・コードを分けて管理する。認証情報と設定は環境変数とし、リリースの際にビルド生成物に登録する。

6. Logs

何のために

アプリがログ情報の管理をしないようにして、アプリを簡素化させたい。アプリ実行環境が動的にたくさんに増えると、環境毎にログファイルが作られる。そういうログ情報を楽に管理/分析したい。

何をする

ログを時間毎に流れてくる情報として扱う。アプリとしてはどこに置くかは関知しないようにし、ログをstdoutstderrに出すだけにする。その出力を収集・分析するような、別のツールやシステムを利用する。

周辺の議論

アプリ開発者はログ出力の設計に凝りがちであるが、アプリの枠内で色々するのはやめて、標準出力に出すのみにするべきである。

7. Disposability

何のために

アプリを素早くスケール、デプロイ、リリース、リカバーさせたい。

何をする

実行プロセスを簡単に捨てられるようにする。また、アプリの開始・終了を素早くできるようにする。長時間かかるキャッシュの初期化処理が必要なものは可能ならバッキングサービスに分ける。

8. Backing Services

何のために

アプリが依存するサービスを簡単に自由に接続したり切断したい。
障害発生時などに役に立つ。

何をする

アプリが依存するサービス(=バッキングサービス)を宣言する。クラウド環境の機能で実際に接続させる。

9. Environment Parity

何のために

チーム全体がアプリがどの環境でも動作すると確信が持てるようにしたい。環境とは、開発環境やテスト環境やQA環境や本番環境などのことである。

何をする

すべての環境が同じになるようにする。

周辺の議論

以下の場合、相違が起きやすい。総じてヒューマンエラーである。

  • コード修正からリリースまでが長い。どんな修正をしたかや環境の変更をしたかを忘れてしまう。
  • 手動でリリースしている。そもそも手作業は間違えるものであるので相違になる。
  • 本番と同じバッキングサービスを準備するのが面倒で大変である。すると似ているが違うもので代用するようになりこれが相違になる。

10 Administrative Processes

背景

管理プロセスとは

  • DB移行 [6]
  • REPLでの処理
  • 定時バッチ
  • 1回だけ実行する特別な処理。

というものである。もともとの12factor ではアプリの1部機能としてこれらの処理をせよと言っているが、これはやめて別のやり方がないか検討するべきである。アプリが水平スケールしたときに1つのインスタンスだけでこれらの機能が動作することになってしまう。

何をする

管理プロセスをアプリの機能で実行しない。
1度きりの処理、定時バッチなどは別のやり方を検討する。

周辺の議論

定時バッチはcronでやるのではなく、RESTfulなエンドポイントを用意して外部から定時で起動するのが最良である。あるいは、バッチ関係のコードを抜き出して別のマイクロサービスにする。

11 Port Binding

何のために

  • 水平スケーリングする場合、ルーティング・スケーリング・高可用性・耐故障性などのネットワーク設定をすべて人力で設定するのは難しい。クラウドプロバイダーがやるべき。
  • 1個のサーバに複数アプリを乗せる場合、アプリが使うポートを細かく管理したくない。

何をする

アプリ開発者がアプリ毎に外部提供するポートを決定する。クラウドプロバイダーがそのポートと実際に公開させるポートをつなぐ。

12 Stateless Processes

何のために

サーバをいつでもすばやく止めたりスケールしやすくしたいので、サーバの起動停止を簡単に行えるようにしたい。

何をする

サーバ内に複数リクエスト間で引き継げるようなデータを持たない。[7]
必要ならバッキングサービス内に保持する。

13 Concurrency

何のために

サーバを増強するときは、水平スケールさせたい。1台のマシンを強化するのではなく、サーバの台数を増やしてスケールしたい。

何をする

処理するプロセスが複数あるという構成でアプリを設計する。処理がプロセスに別れていれば、プロセスを複数マシンに分散させることがしやすい。

14 Telemetry

何のために

システムのログを効果的に取得したい。クラウドネイティブアプリでは、実際のサーバに直接アクセスできるとも限らない。サーバがスケールして、インスタンスが100倍に増えたらログの量も100倍になることもある。

何をする

アプリケーションのパフォーマンス測定について検討しておく。

周辺の議論

パフォーマンスには、以下のものが考えられる。

  • Application performance monitoring (APM)
    • 例:秒ごとのHTTP処理数
  • Domain-specific telemetry
    • 例:直近20分である商品がiPad経由でいくつ売れたか
  • Health and system logs
    • 例:システムのヘルスチェック情報。起動・停止・スケールなどのイベント情報。

補足

具体的にこうしろというものはないが、意識して取り方や内容について検討必要といっている様に見える。

15 Authentication and Authorization

何をする

セキュリティの設計/実装を開発の初日から実施する。

補足

クラウド環境であろうがなかろうがセキュリティはとても重要。後回しにしてはだめ。

参考リンク

Beyond the Twelve-Factor App

https://tanzu.vmware.com/content/ebooks/beyond-the-12-factor-app

The Twelve-Factor App

https://12factor.net/ja/
脚注
  1. https://tanzu.vmware.com/content/ebooks/beyond-the-12-factor-app ↩︎

  2. 間違い探し遊びにどうでしょうか。 ↩︎

  3. https://12factor.net/ ↩︎

  4. 「システムを設計する組織は、その構造をそっくりまねた構造の設計を生み出してしまう」 https://ja.wikipedia.org/wiki/メルヴィン・コンウェイ ↩︎

  5. この項目は、契約を最優先にする開発スタイルの拡張とのことである。おおまかに言えば、サービスが外向けに提供する仕様を決めるということです。 ↩︎

  6. データの移行とか古いデータの消込など? ↩︎

  7. Servletで言うところの、セッションスコープやアプリケーションスコープの変数を持たないということ。 ↩︎