エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

3年半デプロイのなかったクラウド電子カルテ体験版をついに本番追従させた話

こんにちは、電子カルテチームの鳥山(@to_lz1)です。私のチームではクラウド電子カルテ「エムスリーデジカル」を開発運用しています。今回はそんなエムスリーデジカルの "オンラインデモ版"、つまり体験版アプリケーションを3年半ぶりにアップデートさせたお話です。具体的には

  • インフラをAWSに移行
  • 最新のコードベースでデプロイ
  • 製品版のリリースと同タイミングでCI/CDできるように変更

という大きく3点を一気に実施しました。

3年半ぶりというとなんだかすごいことのようですが、そもそもなぜ製品版と異なる環境にあったのか、アップデートできないままだったのはなぜなのかといった疑問は皆さま抱かれるかなと思います。

この記事では、オンラインデモ版サイトの移行に関連するエムスリーデジカルのインフラの変遷、そして移行に際して工夫したこと・考えたことをご紹介しようと思います。

前提

エムスリーデジカルは Ruby on Rails を中核に持つアプリケーションで、主要なインフラはサービスローンチ当初から一貫してAWS上に存在します。

一方、今回の主題であるオンラインデモ版はというと、なぜかAWSとは別のクラウドサービス上に存在していました。

2015年サービス開始当時の意思決定の背景を正確に追うのは難しいのですが、概ね以下のような理由だったと推察されます。

  • AWSを利用するよりも安い
  • オンラインデモ版であるがゆえ不特定多数のユーザに公開する必要があり、製品版と同じ環境上に置くことがリスクだった

オンラインデモ版の仕様概要は次のようなものです。

  • コードベースは製品版と同じで、 RAILS_ENV を切替えることで一部機能を追加したり制限したりする
  • コーポレートサイト上の申込みフォームよりアカウント登録が可能
  • 登録時に初期データを自動生成する
    • これにより製品版で必要となる初期設定が不要ですぐに操作を試せる
  • カルテ画面上から即座にお問合せ・面談予約が可能

上記のような便利機能はデジカルの成長に一役買ってくれました。くれたのですが、やはり時が経つとそもそも違う環境にあるサイトへのデプロイというのは滞りがちになります。ほどなくして、事業の成長に伴い製品版の機能追加やインフラ再構築が喫緊の課題となっていき...、このオンラインデモ版は2018年11月の社名変更を最後に更新されない状態になってしまいました。

オンラインデモ版更新の意義と機運

製品版への対応が優先されていたとはいえ、オンラインデモ版の最新化には意義があります。

体験していただく方(=先生)にしてみれば業務に常時利用するツールを選ぶわけで、電子カルテの選択は一大決定です。デジカルはこの3年の間に続々と新機能も出しましたので、製品版に限りなく近い優れた体験を届けたい、という課題感は営業サイド、エンジニアサイドの双方が持ち続けていました。

そんな折、長らく課題になっていたインフラの再整備が順調に進み、一定数の医療機関ごとに独立した環境に切り分けて負荷を分散する「シャード分割」を昨年無事に完了させることが出来ました。完了後の構成は以下のようなもので、アプリケーションもDBもシャードごとに独立して持つような構成になりました*1

ここまで来れば、デモ版を新たな「シャード」の1つとしてAWS上に爆誕させるところまではあと少しです。こうして、デモ版のAWS移行は時を超えバックログの優先項目に挙がってきました。

設計と工夫点

以下では実施にあたってチームで考慮した点をいくつか紹介します。

案件推進面でやったこと

方針が固まったとはいえ、3年半の間 db:migrate もされていなかった環境からデータ移行をするのはいろいろな意味で骨が折れます。

この点は、計画初期から「データの移行は行わない」という意思決定をすることで手間やリスクを軽減しました。

このアプローチですと、移行前にオンラインデモ版を試して下さった方は当然AWS移行とともにログインできなくなってしまいます。ですが、その点は案内文言を出すことでケアすることにしました。こうした決定を事前にビジネスサイドと共に行えたのは良かったと思います。

ログイン失敗時に文言を出せば読み飛ばさずにいてくれるはず、という目論見

またQAに関しては、そもそもオンラインデモ版のQA環境がない状態からのスタートでしたので、ここに関しては

  • QA環境をなるだけ早期に立ち上げる
  • QAチーム・エンジニアともに本番のオンラインデモに登録し、実際に触る
  • 各機能の差分を洗い出し、テスト項目書のインプットにする

といった愚直な手法を取りました。

技術面でやったこと

アカウントレベルの構成

デジカルにはCDKによってコード化されたインフラが既存資産としてあるので、可能な限りこれを流用したいです。

が、セキュリティ面も考える必要があります。デジカル製品版ではクライアント証明書による認証を用いているのですが、オンラインデモ版は不特定多数のリード顧客にアクセスを許すため通信要件が異なります。

製品版と比べればセキュリティレベルは相対的に低くならざるを得ないので、製品版の環境とはAWSアカウントレベルで分離してリスクを軽減しています(様々な要素を図中から省略しています)。

オンラインデモ版はdemoアカウントに、製品版はproductionアカウントに構築

一方、検証環境においてまでこのレベルで分離すると費用や管理の手間などコスト面が無視できないので、検証環境ではオンラインデモ版と製品版が同一アカウント内に存在することを許容しています。

検証環境はいずれもqaアカウント上に存在

大部分の構成は本番と変わらず保てており、無理なく維持できる範囲の差分に留められたかと思っています。

リバースプロキシの改修

デジカルへのリクエストを最初に受けるサーバは nginx + Go製リバースプロキシからなる ECS Service です。

オンラインデモ版のためだけにこれら既存資産に大きな改修を入れることは避けたかったので、以下のようなアプローチを取ってオンラインデモ版専用のリバースプロキシを構築しました。

  • nginx は一部ファイルだけを書き換えた別のbuild stageとして定義
  • Goのコードはフィーチャーフラグ的な環境変数によって一部動作を切替える
  • 一方、上記を組み合わせた CDKのStack は既存コードと切り離して新規作成

以下の図でいう赤枠部分がこれに該当します。

別案として Stack の実装も共通化する方向があり得ますが、

  • 検証環境アカウントでは製品版とオンラインデモ版のStackを同居させるので、別のコンポーネントとして扱ったほうが都合が良い
  • オンラインデモ版の事情に引っ張られて製品版のインフラ更新・適用に制約が出ると厳しい

と言った理由から、IaCの記述に一定の重複が出ることは許容してこのようなアプローチにしています。

マスタデータ同期

電子カルテは医師の診療行為を公的なマスタデータに準拠する形で残す必要があるため、診療報酬の点数といった複数のマスタデータを定期的に更新する必要があります。

私のチームでは現在、

  1. CLIツールまたはスクリプトを用いて最初のシャードに更新を反映
  2. GitLab CIを実行し、他の全シャードにデータを同期

という2ステップでこの業務を回しています。

ある程度自動化されているとはいえ、繰り返される手作業であることに変わりはありません*2

オンラインデモ版の追加に伴ってこれが2倍の作業量になってしまうと大変なので、既存の仕組みを活かしつつ以下のような構成で解決しました。

図中左側が製品版アカウント、右側がオンラインデモ版アカウントを示します。

既存の仕組みとして Step Functions で S3 への Dump と Restore を行っていましたが、その間に SNS への通知を挟み、これを介してまた別の Step Functions を呼び出せるようにしています。

エンジニアとしては、今までと同じようにGitLab CIを実行すればあとはすべて自動でオンラインデモ版までデータ同期が行われるので、作業量を全く増やさずに同期を実現することが出来ました。

Cross Account での SNS と Lambda の利用に関しては公式のチュートリアルもあり、これを参考にすることでアカウントを跨ぐ自動化を比較的シンプルに実現できました。

Tutorial: Using AWS Lambda with Amazon Simple Notification Service - AWS Lambda

この仕組みは将来さらにデジカルが拡大して製品版が1アカウントですまなくなった場合でも応用が効くかなと思います*3

結果と振り返り

こうしてデジカルのオンライン体験版は2022年5月に無事AWSへの移行を終えました。

しかし、不測の事態もいくつかあり、当初予定から後ろ倒れしてしまったのもまた事実です。チームで対処し、協力して乗り越えられたのは非常にありがたかったのですが、

  • 文書化されず、3年半の間に埋もれてしまったオンラインデモ版特有の知識があった
  • それにより確認観点の考慮漏れが生じた

という問題があったことは否めません。この反省を活かすため、Confluenceには「デモ版デジカル」のページを誕生させ、過去の自分に伝えたいことを極力言語化して残しました*4

まとめ

入社以来複数のプロダクトのAWS移行を担当してきたのですが、振り返ってみても今回が最大規模だったと思います。

移行プロジェクトは一定規模を超えると技術力とプロジェクトマネジメント力との総合格闘技になるな、というのが率直な感想です。

特に、「多い検討事項を減らしていく」こと、つまり

  • エンジニアとしてシンプルで持続可能な設計を追求すること
  • ビジネス側も巻き込んで最も簡便な手段を模索すること

そして「それでも残るたくさんの検討事項を討ち漏らさない」こと、つまり

  • 機能、インフラ構成要素、外部通信など複数の軸で確認すべき事項を洗い出すこと
  • QAチームなどと連携して効率的に品質を確保すること

の両面が極めて重要であるということを身を持って学ぶことが出来ました。

今回主題にさせて頂いた「オンラインデモ版」は、一段抽象化して捉えると「あるプロダクトの微妙に動作が異なるバージョン」と言えます。言葉を選ばず言ってしまうと、こういうコンポーネントはエンジニアを困らせるものになりがちです。しかし、そういうサブシステムこそがビジネス上大事だったりする、というのもままあることかなと思料します。

類似の課題を持つ方へ、今回の記事が少しでも参考になれば幸いです。

We are Hiring!

クラウド電子カルテチームを始め、エムスリーでは最高のプロダクトを作って医療を前進させるメンバーを複数チームで大募集中です!

話を聞いてみたいなと思った方は、ぜひ以下のページからカジュアル面談等お申し込み下さい。お待ちしております!

jobs.m3.com

*1:なおインフラ再整備に関する詳細は こちら でお読み頂けます!

*2:余談ながら、もちろん全自動化も悲願です。改定時期などマスタの更新が頻繁かつ大規模な場合は事前確認が必要なケースが有る、などの事情が最後の壁として立ちはだかっています

*3:そのときにはもっとスマートなマネージドサービスが生まれているかもしれませんね。その場合はまた技術選定をすることになるでしょう

*4:このブログ自体もドキュメントにあたる側面があると思っています