Immutable Infrastructureを導入する

現在たまチームでは、以下のような自動化を実現している。

gyron-infra-old

自動化の柱は大きく分けて二つあって、まずは Deployment Pipeline。アプリケーションコードを変更して git push すると、Jenkins上でビルドされて、Amazon S3上へのパッケージのリリースから、アプリケーションサーバー上へのデプロイまで自動で行われる。

もう一つはサーバー群の構成管理 (Provisioning)で、Chef による Codification(コード化) が実現されている。

この環境でかれこれ二年ぐらい運用してきたが、自動デプロイは便利だと思いつつ、いくつかの問題点が明らかになってきた。

  • デプロイの際に更新されるのはアプリケーションだけなので、サーバー上のミドルウェアの更新をいつやるか、どうやって安全にやるかを考えるのはなかなか悩ましかった。
  • Chefを経由するより、まずはサーバーを直接直してしまおうという誘惑が常にある(突然のセキュリティアップデートが必要になった場合など)。
  • EC2のインスタンスがリタイアするときにあたふたしてしまう。
  • Chefのコードを書く人がインフラ担当者に限られてしまい、アプリケーション開発者側から手出し出来なくなる。
  • 簡単とは言えないChefにも問題があると思われ。
  • ProvisioningコードがCI上に乗っかってない。

というわけで、たまチームへの新たな要求や DevOps の新たなトレンドなどを鑑みて、インフラの大幅刷新を行うことにした。

以下が、目下移行中、新インフラの概要図である。

gyron-infra-new

大きく変わるのはアプリケーション開発者が担当するビルドの部分。以下、重要なポイントごとに検討してみる。

DeploymentとProvisioningの統合

今までは別々に管理されていた Deployment と Provisioning のプロセスを統合して、アプリケーション側で Server Image の生成まで面倒を見るようにする。

現状のビルドプロセス:

deploy-and-provision-old

新ビルドプロセス:

deploy-and-provision

この統合によって、Provisioningの大部分がアプリケーション側に移動することになる。今まではインフラ担当者の責任だった Provisioning を各アプリケーションの開発者が担当することによって、誰もがアプリケーションコードを扱う感覚でProvisioningコードを扱えるようになることを狙いたい。

また、今回は Chef から Ansible への移行も行う。プロジェクト全体で Provisioning を共有する場合、あるいはインフラが大規模になるようなケースであれば Chef のメリットもあると思われるが、アプリケーションに Provisioning を含めてしまうという今回のケースでは、より習得が容易でコンパクトに書ける Ansible が向いているのではないかという判断である。

アプリだけでなくサーバー全体を含めたContinuous Integration

今までCI上で実施されていたのはアプリのビルドまでだった。新しい仕組みでは、サーバーのビルド(AMIの作成)までをCI上で回す。これによって、以下のようなメリットが得られる。

  • Provisioningも自動テストの対象にできる(serverspec
  • アプリケーションの変更を行う感覚でミドルウェアの変更を行える
  • サーバーのPortabilityが改善し、テスト用の環境などが構築しやすくなる

Immutable Infrastructure

新インフラのアプリケーションサーバーは、原則として、一度起動した後にsshなどでログインしてその状態を変更しないようにする。アプリケーションやミドルウェアを更新する場合は、コードを変更してServer Imageを作り直し、古いサーバーを破棄して新しいサーバーに入れ替える。

このような方針で管理されたインフラを「Immutable Infrastructure」と呼ぶ。インフラがコードに表現された以外の状態を取り得ないということは、コードさえあれば環境を容易に再現できるということであり、テストが簡単になる、理解しやすくなる、不測の事態が起こりづらくなる、Blue-Green Deployment がやりやすくなるなど、数多くのメリットがある。

DevOps Split – BuildとOrchestration

新しいインフラでは、Server Image (AMI) という Artifact を生成するプロセスと、そのArtifactを利用してOrchestration(サーバーの構成管理)を行うプロセスを分離する。前者は個々のアプリケーション開発者が担当し、後者はチーム全体で共同管理することになる。

以下は HashiCorp で紹介されているワークフロー:

Atlas-DevOps-Split

このワークフローを採用した場合、Artifactの作成で流れが一旦切れるため、git pushしたらアプリケーションの更新まで行われるという、現状実現できている自動化を再現するのが難しくなる。新インフラで得られるメリットに比べたら些細なことだと言えるかもしれないが、今後の課題ということでここに記録しておく。

CIのCodification – JenkinsからCircleCIへ

現状のインフラで自動化の要を担っているJenkinsであるが、ジョブの数が多くなってくると管理が大変になってくる上に、設定が Codification されていないという問題があるため、CircleCIに移行することにした。

Blue-Green Deployment

現状のインフラで Blue-Green Deployment を実現しているのは、状態(セッション)を持たないアプリケーションに限られ、かつデプロイ作業の多くは手動で行っている(ELBの操作など)。新インフラでは、以下のような手法を採用して、全てのアプリでより安全な Blue-Green Deployment の導入を目指す。

  • JEEアプリについては、 tomcat-redis-session-manager を利用してセッションをRedis (Elasticache) に保存するようにし、アプリケーションサーバーをステートレスにする。
  • Terraform を利用して新しい Server Image を立ち上げた後、Smoke Testで動作確認し、ELB配下で新旧の切り替えを行う。
  • Terraformによって、サーバーの設定・構成がコード化されると共に、管理コンソールで操作する必要がなくなるため、ヒューマンエラーの予防になる。