athome-developer’s blog

不動産情報サービスのアットホームの開発者が発信するブログ

AMIを駆使したリリースバージョン管理の仕組み

お久しぶりです。
以前こちらの記事を書かせていただきました、Cメディア開発グループの伊藤です。
今回は、「不動産情報サイト アットホーム」のリリース運用について紹介できればと思います。

新しいプロジェクトの開発において、リリース作業は必要不可欠ですよね? 多くのユーザーが快適に不動産情報サイト アットホームを利用できるように、常に最新の情報や使いやすい機能を提供することが求められます。 そのためには定期的なバージョン更新が必要です。

また、本番環境のリリースが行われれば、それに合わせて複数ある検証環境も随時更新していかないと環境自体がどんどん古くなってしまいます。 基盤チームで環境を管理している私たちにとって、特に検証環境の多さやバージョン管理の必要性は日々痛感するところです。

そこで今回は不動産情報サイト アットホームをリリースする際のバージョン管理の仕組みに焦点を当て、AWSサービスを駆使した環境管理の舞台裏を覗きつつ、運用していて私が実際に感じていることを率直にお話していきたいと思います。

前回に引き続き、AWSやエンジニアの世界に興味を持ってもらえるような記事となればうれしいです。


目次

不動産情報サイト アットホーム リリースの仕組みは?

では、早速ですが不動産情報サイト アットホームのリリースはどのように行われているのでしょうか?

不動産情報サイト アットホームのリリースは、Blue/Greenデプロイツール(以下、BGツール)と呼ばれる処理が走ることで、APサーバ、WEBサーバ、検索用DBサーバの構築を一元的に行っています。 この方法を確立する前は稼働中のサーバのファイルを手動でアップデートしていたため、リリース作業が大変手間だったと当時運用していた方からも聞いています。

ここでは新しい環境が構築されるまでの流れを視覚的にイメージしやすいように紹介します。

前提として「Blue面」(=稼働中の環境)と「Green面」(=新しく構築する環境)、この2つがリリースの”セット”だと考えていただければと思います。

図1 不動産情報サイト アットホーム リリースの仕組み
図1 不動産情報サイト アットホーム リリースの仕組み

新しい環境が構築されるまでの手順

①BGツールが動くと、「Green面」環境が新たに作られる
②必要なリソースが問題なく作成されたらALB*1の向き先を切り替える
③切り替えがうまくいったら、BGツールで作成した「Green面」環境が「Blue面」環境として稼働する
※不要になった旧「Blue面」は、問題なく新しい環境に切り替わったことを確認した後、削除される

次のリリースが行われる場合は①~③をまた繰り返します。 もし構築に失敗した場合は新しい環境には切り替えず前バージョンのサーバで稼働し続けるため、サイトが見られなくなるというようなトラブルを防ぐことができます。

このような運用方式にすることで、ユーザーにサービスを提供しながら新しい環境の構築が可能となり、安定した稼働が実現できているのです。
では、BGツールは何の情報を基にインスタンスを作成しているのでしょうか。
その答えが今回ご紹介する「AMI」となります!

AMIって何?

では、AMIとはいったい何なのでしょうか?

AMI(Amazon Machine Image)とは、Amazon EC2(Elastic Compute Cloud)インスタンス(=実際に動く状態になったサーバ)を作るためのテンプレートであり、
いわばインスタンスの「ひな形」のようなものです。

このAMIを使用することでサーバに必要なOSやデータが組み込まれた新しいEC2インスタンスを手軽に作成でき、簡単に運用を始めることができます。

“手軽にインスタンスを作成するためのAMI”というイメージですが、実はほかの活用方法もあるのです。
AMIには4つ種類があるので、今回は1つずつ身近なものに例えながら紹介していきます。

図2 AMIの種類
図2 AMIの種類

一言でAMIと言ってもさまざまな使い道がある中で、不動産情報サイト アットホームでは「カスタムAMI」を活用してサーバを再構築しています!

AMIを使ったバージョン管理

では、先程触れた「カスタムAMI」を実際にどのようにバージョン管理に利用しているのでしょうか?

今回は実際に私が運用している不動産情報サイト アットホームの検証環境を例に紹介します。

検証環境では、1日に何度も自動的にリリースが走ったり開発者が手動でもリリースできたり…と実際はなかなかの頻度でリリースが行われています。
そのため、より頻繁なビルド/デプロイでも環境が維持できるようなバージョンの管理体制が必要不可欠なのです。


AMIを作成、利用するタイミング

AMIは各サーバごとに作成され、そして作成を行うとAMIIDといわれる「ami-」から始まるランダムな英数字で構成されたIDを発行します。
そのAMIIDをインスタンス作成時に指定することで、そのバージョンのインスタンスが作成されるという仕組みとなっています。

以下は検証環境でAMIが作成されるタイミングと、AMIIDを使ってインスタンスを作成する(=リリースされる)タイミングを図で表したものです。

図3 AMI作成/利用のタイミング
図3 AMI作成/利用のタイミング

ここまで検証環境で頻繁にリリースが行われているのは、開発者が日々多くの案件に対応する中で、開発の修正をより早く頻繁に画面反映させるようにするためです。


検索用DBのバージョン管理

検索用DBはテーブルの内容に変更があった場合のみ、AMIの作成が行われます。

これは不動産情報サイト アットホームには連携用DBと検索用DB、2種類のDBが存在することが理由として挙げられます。
サイト上に物件データを表示させるためには、連携用DBから検索用DBサーバにデータをロードする必要があります。

ただし、この連携用DBと検索用DBのテーブルの設定を正確に合わせないと、サイト自体が正しく動作しなくなってしまいます。

どの変更を含んだバージョンを基にDBを作成するのか、そのテンプレート的な役割を担っているのもAMIなのです。

※検索用DBサーバのインスタンス作成のタイミングは
 ①テーブルの内容に変更があった場合(AMI作成時)
 ②夜間データ洗替時
のみとなっています。

図4 検索用DBのバージョン管理
図4 検索用DBのバージョン管理

図4の様に、「bkn_no(物件No)」「date(登録日付)」「open_flg(公開フラグ)」のカラム情報を持っているテーブルがあるとします。
このテーブルに新しいカラム「new_kbn(新区分値)」を追加したい場合、連携用DBだけに登録してしまうと検索用DBへのロード時に整合性が合わずエラーとなってしまいます。
それを防ぐためにAMIを用いて整合性を持たせます。

①新しいテーブルの情報を含んだ新バージョンのAMIを作成
②作成したAMIを基に検索用DBをリリース

検索用DBのリリース後に連携用DBのカラム情報を登録することで、検索用DBへのロード時にエラーになるトラブルを防ぐことができます。
また検索用DBからリリースを行うことで、万が一検索用DBにだけ新しいカラムがある状態で連携が走ってしまっても、新しいカラムの値はNULLとして登録されるだけなのでサービスに影響はありません。


このように検証環境では頻繁なAMI作成が行われていますが、実はAMIの作成が行われるのは検証環境だけなのです。
その理由が、不動産情報サイト アットホームがAMIを用いてリリース管理を行っている最大の要因になります。


環境構築からリリースまで

では、その最大の理由を紐解くためにまずは実際に新しいプロジェクトの環境構築からリリースに至るまでのフローを追ってみましょう。

図5 環境構築からリリースまで
図5 環境構築からリリースまで

①今回のプロジェクトで利用する環境に対して、構築作業を行う
検証環境は現在全部で10面前後あります。その中から今回のプロジェクトで使用する環境を管理者が決め、基盤を最新のバージョンに合わせる作業(=構築作業)をしていきます。 この時構築した基盤と同じバージョンのDB_AMIIDを指定することで、連携用DBとの整合性を担保しています。

②フロントのリリースバージョンをその環境にあてる
基盤の構築完了後、フロント側のバージョンを環境に指定することで、開発期間中は常に特定のリリースブランチでAMI作成からリリースまでを行うことができます。

③作成された環境で、開発→テストを行う
開発中、検証環境では頻繁にリリースが行われます。
そして開発チームが検証環境にリリースしたものをテストチームが確認していきます。

④テスト完了後、AMI凍結を行う
テストが終わると、リリース対象の検証環境のブランチがこれ以降勝手に更新されないように設定を行います。 この、テスト完了後にリリースブランチのアップデートを止める作業を私たちは「AMI凍結」と呼んでいます。
「AMI凍結時点のAMIID」を本番に設定しリリースを行うことで、テストチームがテストした完璧なリソースのみをリリースできるような仕組みになっています。

⑤リリース作業を行う
④で凍結したAMIIDを基にリリースが行われ、開発した機能やサービスがユーザーに提供されます。

もうお気づきの方もいるかと思いますが、環境構築からリリースまでの手順で出てきた「AMI凍結」が今回のカギになります。
「テストを完全に終わらせた完璧なブランチでしかAMIを作成しない」というフローを確立することで、ブランチのコミット漏れや余分なコミットから引き起こされるサービス障害のリスクを防いでいるのです。

これがAMIを用いてリリースバージョンを管理している最大の理由となります!

また、他にも、サーバのオートスケーリング*2を実現するためにもAMIは欠かせないものとなっています。

実際の運用で感じた効果や課題

AMIをつかったバージョン管理の仕組みとメリットが整理できたところで、私が実際に基盤チームで環境を管理していて感じていることをお話ししていきたいと思います。

やはり一番は、リリースの手軽さやリリースのしやすさなのではないかなと思います。

AMIの作成、BGツールの実行、新しいバージョンのリリースまでが簡単に30分ほどで完了すること、そして作成で失敗した場合は切り替わらないという仕組み自体がリスクを最小限に抑えられているため、開発や運用がスムーズだと日々感じています。
特にAPサーバやWEBサーバに関しては、毎回リリースされるたびにAMIIDが作成されるため、本番環境へリリースする際のバージョンの信頼性が確保されていて安心感があります。


また、検証環境の構築作業で基盤を最新の状態まで更新させたい時、AMIは環境依存をしていないので一度別の環境で作成したAMIを他の環境にも使用することができます。
最新のAMI_IDを指定することで最新化した連携用DBとの整合性を保った検索用DBが簡単に作成できることも、便利だと感じているところです。
構築作業は1カ月に2~3度は発生する作業なので、手間をかけずに作業できるのはとても心強い仕組みです。


検証環境を運用していて私が課題と感じる点は、検索用DBのAMI管理でどのAMIがどの環境で使われているのかを逐一チームで把握していないと連携用DBと検索用DBの整合性がとれずエラーになってしまった場合に、原因の特定やどのバージョンのAMIと整合性が合うのか特定するのに時間が掛かってしまうことです。
現在は社内ツールのドキュメントで管理しているためそちらを参考にすれば問題はありませんが、記載漏れも可能性としては大いにあるので、より確実な運用の確立が必要かもしれません。


ここまで不動産情報サイト アットホームのリリース管理について整理してきましたが、私は一つの疑問が浮かんでいました。
AWS勉強中の私にとっては、「ビルド→デプロイを素早く安全に実現できるサービスは?」といわれると、まずCodePipelineをはじめとしたCodeシリーズ*3を考えます。

Codeシリーズを採用せずにAMIでの管理に踏み切った理由ってなんだろうと疑問に思ったので、これを機に有識者の方に伺ってみました!

Codeシリーズは毎回コンテナを立ち上げ直してデプロイが行われるので、いくら環境を同じにしたつもりでも環境依存のリソースが足りないなどでコンテナを立ち上げ直した際にエラーが出てしまう可能性があります。
対してAMIの場合、必ずベースのAMI(OSとミドルウェアのみが入ったAMI)から作成しているので、必要なミドルウェアが不足している・・・などのトラブルでエラーになる心配もなく、スムーズにインスタンスを作ることができます!


とのことでした。 また、Codeシリーズを全く使用していないというわけではなく、一部のサービスではCodeシリーズをベースにAMIを現行のBGツールと同じ思想でリリースを行っているということでした。
AMIでの運用方式を取り入れることで必要な部品がそろった前提でインスタンス作成することができ、単にCodeシリーズのみで構築するよりも安全な運用設計になっているのだという工夫に気づくことができました。
「CI/CDに強いサービスはCodeシリーズで、これさえ使えば問題ない。」という単純な設計ではなく、 実現したい状況に応じて何のサービスを使うべきかが細かく選定され、運用面にも考慮された最適な設計なのだと再認識することができました!

まとめ

今回のテーマ選定の目的は、AMIを駆使したバージョン管理の仕組みをより深く理解していただくこと、そしてAMI自体について幅広く知っていただきたいという思いからでした。

自分自身、これまで検証環境の運用に取り組んでいましたが理解が曖昧な部分も多くありました。
しかし今回の執筆を通じて改めて仕組みを整理し直すことで点と点が線でつながる感覚が生まれ、不動産情報サイト アットホームの運用プロセスについての理解を一層深めることができました。 運用のしやすさも再認識し、自身の成長を感じています。


またAMIを使ったバージョン管理のしくみや、運用上のメリットにも改めて目を向けたことでの学びもありました。
AMIの活用方法に関しては単純に「簡単にインスタンス作成ができるもの」だと理解していましたが、その実態をより深く知ることでサービスの潜在的な活用の幅に気づくことができたと思います。

それぞれのサービスや運用にあったベストプラクティスが考えられるよう、今後もAWSサービスごとの知識を深めていきたいです。

最後までお読みいただきありがとうございました!

*1:アプリケーションの負荷分散とルーティングを行うAWSサービス

*2:自動的にリソースの拡大・縮小を行い、負荷を均等に分散するシステム

*3:ここではAWS CodePipeline, AWS CodeBuild, AWS CodeCommit, AWS CodeDeployを指しています