一般的なプロジェクトの開発からリリースまでの流れとして、
- ローカルや Azure 上の Dev 環境で開発
- Azure 上のステージング環境でテスト
- Azure 上の本番環境にリリース
となる事が多いと思うが(他知らないので、その前提で進めます)、このステップを踏む場合、Azure のリソースも基本的にはそれぞれのステージごとに用意する必要がある。
けど、Azure のリソースを使う場合この選択肢がいくつかあるので、どれを選択するかと言う話。
この話については、当該システムでどの Azure リソースを使うかにもよるので一概にこの方法でと言うのは言えないが、ここでは Web Apps を使ったシステムを例に考えてみる。
自分が考えつく各ステージごとのリソースの分け方としては、以下のような分け方がある。
- サブスクリプションで分ける
- App Service で分ける
- Web Apps で分ける
- スロットで分ける
基本的には、上に行くほどコストや手間がかかるがリソースとしては安定し、下に行くほどコストや手間がかからないがリソースとしては安定しない。
色々と考え方はあると思うが、個人的には、本番とそれ以外は、サブスクリプションを分けてしまった方が、ヒューマンエラーなども起こりづらく、色々すっきりすると思う。
それぞれの方法について、メリットとデメリットを挙げると、以下な感じ。
- メリット
- ヒューマンエラーが起こりづらい。特に、開発時に誤って本番リソースに対して変更等かけてしまうと言った間違いは起こりづらくなる
- リソースが安定する。本番と開発でリソースが分かれているので、いくら開発で負荷かけたり不安定な状態になったとしても、本番には影響ない
- 本番環境のスケールアップ・スケールアウトが、本番環境だけにフォーカスして検討・設定できる
- デメリット
- コストがかかる。開発用リソースは最低限のプランで用意するとしても、それなりのランニングコストを覚悟する必要がある
- リソースの準備・メンテの手間がかかる
- ダッシュボードなどを利用した本番リソースの日常の監視がしづらい (普段は開発用のサブスクリプションでしか作業していない場合)
App Service で分ける
- メリット
- ヒューマンエラーが起こりづらい。サブスクリプション毎わけるのに比べれば発生確率上がるが、Azure リソース自体は別なので、まだ起こりづらいと言えるレベル
- リソースが安定する。本番と開発でリソースが分かれているので、いくら開発で負荷かけたり不安定な状態になったとしても、本番には影響ない
- 本番環境のスケールアップ・スケールアウトが、本番環境だけにフォーカスして検討・設定できる
- デメリット
- コストがかかる。コスト面で見ると、サブスクリプション毎分けるのと大差ないレベル
- リソースの準備・メンテの手間がかかる。これも、サブスクリプション毎分けるのと大差ないレベル。証明書のインストールなども、App Service 単位で必要
Web Apps で分ける
- メリット
- コストがかからない。本番・開発で同じ App Service を使う場合、料金は App Service 単位でかかるので、コストを節約することができる
- ヒューマンエラーが起こりづらい。Azure ポータルで見た時の Azure リソースとしては別 Web Apps として分かれているので、基本的には App Service で分けるのと同様のレベル
- デメリット
- リソースが安定しない。本番・開発で同じ App Service を使う場合、利用可能な CPU、メモリリソースなども全 Web Apps で共有するため、開発用 Web Apps で生じた負荷などが、本番環境にも影響してしまう。例えば大量アクセス時の動作確認しようとして開発環境に負荷をかけると、本番環境も同様の負荷状況に陥ってしまう。逆も同じ
- 本番環境のスケールアップ・スケールアウトが、本番環境だけにフォーカスして検討・設定できない(App Service 単位での設定になるため)
スロットで分ける
- メリット
- コストがかからない。本番・開発で同じ App Service を使う場合、料金は App Service 単位でかかるので、コストを節約することができる
- スロットのスワップによるデプロイが利用できる
- デメリット
- ヒューマンエラーが起こりやすい。特に Web Apps は既定スロットを運用スロット(=本番スロット)として扱うことが多いと思うが、Azure ポータルで当該 Web Apps を開いた時に初期表示されるのが既定スロット(=本番スロット)である事が、ヒューマンエラー発生時のリスクの高さに拍車をかけている。仮に Dev, Prd を同一アプリのスロットで分けて開発する場合、開発中は相当注意して Azure ポータルで Dev スロットの操作を行う必要がある
- リソースが安定しない。本番・開発で同じ App Service を使う場合、利用可能な CPU、メモリリソースなども全 Web Apps で共有するため、開発用 Web Apps で生じた負荷などが、本番環境にも影響してしまう。例えば大量アクセス時の動作確認しようとして開発環境に負荷をかけると、本番環境も同様の負荷状況に陥ってしまう。逆も同じ
- 本番環境のスケールアップ・スケールアウトが、本番環境だけにフォーカスして検討・設定できない(App Service 単位での設定になるため)
個人的に思うところ
なるべくコストを低く抑えたいと言うのは普通どこでも最初に挙げる要望だと思う。ただ、メリットとデメリット、リスクとリターンのバランスを考慮する必要がある。
ヒューマンエラーの可能性とリソースの安定性、デプロイの影響、URL などの接続情報の分離、コストなどを総合的に鑑みた場合、自分としては以下のような選択肢が思い浮かぶ。
- 開発環境の負荷や不安定さが本番環境にも影響を与えるのはよろしくない。これを優先して考慮すると、本番と開発は、少なくとも App Service を分ける必要がある。またこうすることで、本番インスタンスのスケールアップ・アウトもシンプルに設計することが可能
- 本番へのリリースは、スロットのスワップで行いたい。これを考慮すると、本番及び、本番リリース前の動作確認用のステージング環境を、同じ Web Apps のスロットで分ける方法が良いかなと思う
- 開発及び、開発よりのステージング(?)環境は、コストを考慮して同じ App Service または Web Apps に用意する
- 可能であれば、本番系と開発系で、サブスクリプションを分けたい
異なるアプリの Azure リソース上の共存について
上述した内容は同じアプリの Dev, Stg, Prd 毎の扱いについてだが、やろうと思えば異なるアプリも同じような考えで同一リソースに共存することが可能。
ただ、異なるアプリを同一リソースで動作させる場合、最低でも、デプロイや URL、バックアップの単位などは他に影響ないように分けるべき。
例えば Web Apps に関して言えば、App Service プランを共有するのはギリギリいけるとしても、Web App リソースは完全に分けるべき。
Blob ストレージも、接続時の URL が同じで困るのであれば、ストレージ アカウントを分ける。
同様に DB も、DB コピーの単位がスキーマ単位なので、最低限スキーマ単位では分ける、など。