Immutable Infrastructure を目指す
- 最近、巷で(個人的にも) Immutable Infrastructure が流行っているので、AWS で実現するならこんな感じ?というイメージをまとめてみた
そもそも Immutable Infrastructure とは
- "一度、インフラ環境を構築したサーバは、運用が開始したら設定を変更しない" という運用スタイル
- サーバに設定変更が必要になった場合は、別のマシンを用意し、設定が完了したらロードバランサーを切り替える
- AWS などのクラウドが普及し、仮想サーバによりマシンの用意が簡易になったことにより流行る
AWS 上でおこなう Immutable Infrastructure
想定する環境
- 上図のように Elastic Load Balancing (ELB) 配下においた EC2 インスタンスで Rails アプリケーションを動作させていることを想定する
- Rails アプリケーションをデプロイする際に Immutable Infrastructure を適用する
- DB には RDS を使用し、今回は DB に変更が入らないものとする
- DB に変更が入る場合の Immutable Infrastructure での運用は課題。。。
EC2 インスタンスのベースとなる AMI を用意
- あらかじめ必要なソフトウェア(Ruby, Rails etc.) をインストールした AMI を用意しておき、デプロイの際にはこの AMI をベースに EC2 インスタンスを立ち上げる
- ここで使用する AMI を BaseAMI と呼ぶことにする
- BaseAMI は chef 等のプロビジョニングツールを使用する
- BaseAMI を変更したい場合は、chef コードの方を修正し、サーバ環境に直接手を加える事はしない
EC2 インスタンスの作成・ソースコードの取得
- ここからデプロイをおこなう
- デプロイには capistrano 等を使用(Ruby のスクリプトでも OK)
- BaseAMI から新規にインスタンス (New Instance) を作成する
- Git 等を使用し、 New Instance に Rails アプリケーションのソースコードを配置する
Rails アプリケーションの起動
- 取得したソースコード実行し、Rails アプリケーションを起動する
- 今回の例は、DB に変更がない場合を想定しているので、RDS にそのまま接続するのみ
- ELB との接続もおこなう
古いインスタンスの停止・デプロイ完了
- New Instance と ELB を接続し、Health Check が完了したら、Old Instance を ELB から切り離す
- Old Instance で動作している Rails アプリケーションを終了する
- Old Instance のログをよしなに保存し、インスタンスを停止する
- これにより、ゼロダウンタイムリリースが可能になる
- New Instance の動作に不具合があった場合は、Old Instance を再起動し、Rails アプリケーションを動作させたのち、ELB を振り直せば、容易にロールバックも可能
その他
- このままでは、デプロイを複数回繰り返していくうちに Old Instance が増えていくので、2 世代前は terminate するなどのルールを作ると、より Immutable Infrastructure っぽくなる
まとめ
- 本来であれば、上の [EC2 インスタンスのベースとなる AMI を用意] に書いたような BaseAMI は用意せず、デプロイの都度プロビジョニングツール(chef 等)で環境を作りなおしたほうが、より Immutable Infrastructure に則っていると思われる
- しかし、環境の構築に時間がかかる、かつ何度も変わるものでなければ AMI として用意しておいたほうが効率が良いと判断した結果、BaseAMI を使うことにした