はじめに
昨今のシステムはビジネスの競争力の源泉になりつつあります。だから、1回構築したら完了ではなく、ビジネス環境やユーザーのニーズの変化に合わせて日々改善や新しい機能を実装・リリースして継続的に価値を高めなければ競争力を急速に失ってしまいます。
現在のシステム開発の状況は最新のテクノロジーを駆使しシステムを継続的に改善しやすい状態にすることで、ユーザーに素早く価値提供することが重要になっています。
システムを継続的に改善しやすい状態にする上で重要な指針として、The Twelve-Factor Appという手法が重要であると考えています。
今回実際にThe Twelve-Factor Appでアプリやインフラを構築して、一連の流れを連載形式で書き綴りたいと思います。実際に構築するインフラやアプリは下図になります。
目次(順次追記)
- 第1回 The Twelve-Factor App on AWS & Django(The Twelve-Factor Appとは) ← 今回
The Twelve-Factor App
The Twelve-Factor Appとは、2011年にHerokuのエンジニアが何百何千ものアプリケーションの開発・運用・スケールに間接的に立ち会った経験から提唱したアプリ開発の手法で現在でも適用できる要素が多いと思います。
The Twelve-Factor Appは以下を目的にしています。
- セットアップ自動化のために宣言的なフォーマットを使い、プロジェクトに新しく加わった開発者が要する時間とコストを最小化する。
- 下層のOSへの 依存関係を明確化し、実行環境間での移植性を最大化する。
- モダンなクラウドプラットフォーム上へのデプロイに適しており、サーバー管理やシステム管理を不要なものにする。
- 開発環境と本番環境の差異を最小限にし、アジリティを最大化する継続的デプロイを可能にする。
- ツール、アーキテクチャ、開発プラクティスを大幅に変更することなくスケールアップできる。
The Twelve-Factor Appの12個のFactor(要素)を確認し今回実施することを記載します。
- I. コードベース - バージョン管理されている1個のコードベースと複数のデプロイ
- Githubにsample-ecs-todo-appという1個のリポジトリを作成し、sample-ecs-todo-appリポジトリをそれぞれの環境にデプロイする。
- II. 依存関係 - 依存関係を明示的に宣言し分離する
- PythonとNuxtで開発するので、pipenvとnpmを使ってアプリの依存関係を管理し、Dockerfileで依存関係に基づきインストールを行う。
- III. 設定 - 設定を環境変数に格納する
- ECSのコンテナ定義を利用して、アプリと設定を分離し、設定を外部から注入できるようにする。
- IV. バックエンドサービス - バックエンドサービスをアタッチされたリソースとして扱う
- データベースとしてRDSを利用する。設定に格納したRDSのエンドポイントでアクセス可能にし、エンドポイントの切り替えで自由にデータベースを付け離しができるようにする。
- V. ビルド、リリース、実行 - ビルド、リリース、実行の3つのステージを厳密に分離する
- CodeBuildを使用してコンテナイメージを作成してAWS ECRにプッシュする。
- CodeDeployを使用して作成したコンテナイメージとコンテナ定義を組み合わせてECS Fargateにデプロイする。
- VI. プロセス - アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する
- 1個のステートレスなPythonアプリケーションプロセスをコンテナで実行し、APIエンドポイントを公開する。
- 永続化すべきデータは全てRDSに保存する。
- VII. ポートバインディング - ポートバインディングを通してサービスを公開する
- Nginxをコンテナ実行環境のポート80にバインドし、静的ファイルはNginxで処理し、APIへのアクセスはDjangoアプリのコンテナにプロキシします。
- VIII. 並行性 - プロセスモデルによってスケールアウトする
- サービスに複数のタスク数を指定して、ECSにおいて失敗したタスクが自動的に再起動するように設定する。
- サービスでタスクの最大数を指定して、CPUのメトリクスを監視してオートスケールするよう設定する。
- IX. 廃棄容易性 - 高速な起動とグレースフルシャットダウンで堅牢性を最大化する
- Amazon ECSは、スケールイン時や正常なアプリケーション終了動作時において、アプリケーションプロセスに対してSIGTERMと呼ばれるシグナルを発行します(Fargateでは最大120秒まで設定可能)。
- シグナルに対する待機時間として、デフォルトの30秒(Fargateとアプリ)で問題ないので、設定は変更しません。
- X. 開発/本番一致 - 開発、ステージング、本番環境をできるだけ一致させた状態を保つ
- CodePipelineでCI/CDパイプラインを構築し、同一のコンテナイメージを開発・本番環境へデプロイするようにする。
- Terraformで同一のバックエンドサービスを利用するよう定義する。
- XI. ログ - ログをイベントストリームとして扱う
- ローカルのファイルへログを出力するのではなく、Amazon CloudWatch Logsへログを送信するよう設定する。
- XII. 管理プロセス - 管理タスクを1回限りのプロセスとして実行する
- DBマイグレートをデプロイプロセスに含める。
- 管理・メンテナンスのためのタスクを起動できるようにする。
技術スタック
上記を踏まえ、今回それぞれの分野で使用する主要なテクノロジーは以下になります。
- インフラ
- AWS
- IaC
- Terraform
- フロントエンド
- Nuxt
- バックエンド
- Python
- Django
次回(第2回)では、早速バックエンドのアプリを開発したいと思います。
参考
The Twelve-Factor App
Amazon ECS と AWS Fargate を利用した Twelve-Factor Apps の開発
The Twelve-Factor App on AWS