ASP.NET セッション格納先 Azure Redis Cache の設定を動的に変更する

ASP.NET のセッション情報の格納先は、オンプレでは StateServer モードを使うことが多いと思う (InProc は使わない前提)。 オンプレではステートサービスを利用する方法で良いが、Azure Web Apps 上で動作させる場合、ステートサービスが利用できない。 代替案として、Azure リソースの一つである Azure Redis Cache が利用できる。

Azure Redis Cache 自体は ASP.NET のセッション情報格納用に用意されているわけではなく、純粋に NoSQL DB として用意されているが、ASP.NET のセッション格納先として利用できる Microsoft.Web.RedisSessionStateProvider NuGet ライブラリが用意されていて、ASP.NET Web アプリ開発側としてはそこまで特殊な操作は必要ない。

Redis Cache の設定を動的に変更する

Redis Cache をセッションの格納先に使用する場合、host, port, accessKey や databaseId などの設定は、基本的には web.config で設定することになる。 web.config による設定で問題ないプロジェクトであれば良いが、Azure Web Apps で ASP.NET を動かす場合、スロットを使用して本番とステージングで環境を分け、本番デプロイはスワップを使用する事が多いと思う。 この場合、web.config のみで対応すると、本番スワップ後に本番用の web.config 設定に手動で切り替える必要があり、変更の手間や間違える可能性が出てくる。

その為、Redis Cache の設定についてもアプリ設定などから環境ごとの設定を読み込み、その設定を自動で適用出来るのが望ましい。

使用しているのがセッションという比較的低レベルの場所の為、操作できるタイミングは多くないが、以下のように Global.asax の Application_Start イベントであれば、動的に設定を行うことが出来る。

protected void Application_Start()
{
    ...

    SessionStateSection sessionStateSection = (SessionStateSection)WebConfigurationManager.GetSection("system.web/SessionState");
    ProviderSettings ps = sessionStateSection.Providers[0];
    ps.Parameters["host"] = "アプリ設定から取得した設定等";
}

※ なお、この記事の内容とは直接関係ないが、設定値に問題があるなどして上記処理でエラーが発生すると、ASP.NET 的に致命的なエラーの状態になりやすいので、注意

参考情報

Azure SQL Database の差し替え

Azure SQL Database を別の名称のデータベースと差し替えたい場合(バックアップからリストアした DB と差し替える等)、データベース名を SSMS で変更して差し替えを行うことが出来る。

ただ、Azure SQL Database だとシングルユーザーモードは使えないらしく、他に誰も使っていない時に名前変更する必要があるらしい。

Azure SQL Database のバックアップについて

Azure SQL Database (サーバーではないので注意) のバックアップ方法は、主に以下。

  1. Azure ポータルでのコピー (Azure SQL サーバーへの Database のコピー)
  2. Azure ポータルでのエクスポート (Azure ストレージへの BACPAC ファイルの保存)
  3. SSMS でのエクスポート (ローカルへの BACPAC ファイルの保存)
  4. ビルトインの自動バックアップ (Azure 側で常に自動バックアップされている)

Azure ポータルでのコピー

Azure ポータルで当該 SQL Database リソースを表示し、[概要] 画面の [コピー] メニューから、Azure SQL サーバーへのデータベースのコピーを行う。 バックアップとはまた少し違うが、対象データベースを基にした別データベースを作成するのであれば、この方法が一番手間がない。

後述するように Azure ポータルでのエクスポート作業時は Azure IP がファイアウォールで許可されている必要があるが、コピー操作ではそのような制限はない様子。 また、エクスポートでは 15 分前後かかるデータベースも、コピーだと数分で済むので、そういう意味でもコピーはお手軽。

コピー先データベースのリソースグループや価格レベルはコピー元と同じ設定となるが、どちらもコピー完了後に変更出来るので、特に問題はないはず。 (リソースグループの変更は、当該 SQL Database が格納されている SQL サーバーごと行う必要がある)

Azure ポータルでのエクスポート

Azure ポータルで当該 SQL Database リソースを表示し、[概要] 画面の [エクスポート] メニューから、BACPAC ファイルの Azure ストレージへのエクスポートを行う。 事前にエクスポート先の Azure ストレージアカウントを用意しておく必要があるので、注意。 後述する SSMS のようにクライアント端末に SSMS をインストールする必要もなく、Azure ポータルだけで操作完了できるが、ファイアウォール設定で Azure の IP が許可されている必要があるようなので、その点だけ注意。

また、エクスポート処理にはほとんど使用していないような状態のデータベースでも 15 分前後かかり、DTU も 100% 使ったりするので、この点も注意。 公式ドキュメントでは、エクスポート操作が 20 時間を超える場合は処理がキャンセルされるので、エクスポート操作時だけコンピューティングサイズを増やして処理時間を短くするような方法も記載されているので、DB 的にかなり負荷がかかる処理の様子。

エクスポート状況は当該データベースの画面ではなく、当該データベースが格納されている SQL サーバーの画面から確認できる。

SSMS でのエクスポート

Azure ポータルでのエクスポートの、ローカル版。 SQL Server Management Studio (SSMS) で対象 DB に接続後、対象 Database を右クリックし、コンテキストメニューから [タスク] - [データ層アプリケーションのエクスポート] をクリックする。 格納しているデータがほとんどなくても、エクスポート処理には 15 分前後かかるので、注意。

ビルトインの自動バックアップ

Azure SQL Database は Azure 側の仕組みで常に自動バックアップされている。Basic プランでも直近一週間以内であれば任意の日時の時点を指定して復帰可能。 コピーやエクスポートについて上述したが、自動バックアップの期間内の状態に戻せれば良いのであれば、実質的に明示的なバックアップは不要となる。

Azure リソースの名前付けについて

名前付け規約に関する公式ドキュメントは以下。

Azure リソースは Azure ポータル一箇所で全て管理されているため、ひと目でリソースの種別や目的が分かるような名前付けをする事が非常に重要となる。 なお、ここでは一つのサブスクリプションで一つのプロジェクトのリソースを管理する状況を仮定する。 場合によっては複数プロジェクト(もしくは特にプロジェクトが決まっていない)のリソースを同一サブスクリプションで管理する状況もあるかもしれないが、その場合は更に検討が必要と思われる。

基本的な考え方としては、最初に一番重要な要素を持ってくるべき。また、各リソースはアイコン付きで表示されるのでリソース種別も基本的にはそれで分かるが、一応、リソース種別もリソース名に含めた方が無難。 まとめると、基本形としては全て小文字で以下を想定。

[ステージ名]-[サービス名]-[リソース種別]

なお、[ステージ名] は、本番については基本的に "prd" を付与せず、サービス名から始まるリソースを本番として扱う。

例:
[dev] dev-service1-rg
[stg] stg-service1-rg
[prd] service1-rg

リソースによってはハイフンなどの記号が使用できないのもあるので、その辺りはハイフン使わずに詰めて名前付けするなど、適宜対応する。

複雑なパスワードの生成

以下のノートンのサイトで簡単に作成できる。

インターネット上のサービスである事が気になるのであれば、

  • 同時生成数を増やす
  • 作成した文字列の一部を自分で変更する
  • スマホなど、オフィスとは関係のない IP の端末で表示して、目でコピー

とかで十分にリスクは軽減できると思う。

Azure SQL Database を使用する時の考慮事項

DB 作成時の照合順序の初期値が SQL_Latin1_General_CP1_CI_AS

照合順序を初期値のまま DB 作成すると、varchar 型の列に日本語 (2 バイト文字) を入れると文字化けする。 2 バイト文字は必ず nvarchar の列に入れるなどのルールであれば問題ないが、そうでなければ、日本語用の照合順序で作成しておくのが無難。 なお、照合順序は後から変更することが出来ないため、作成後に変更したい場合は DB の作り直しになる。

日時の扱いは UTC

照合順序の初期値と似たような話だが、クラウド上に存在する PaaS の宿命みたいなもの。

ファイアウォールによる送信元 IP 制限が常に有効

クラウド上に配置された DB なのである意味当然かもしれないが、ホワイトリスト形式のファイアウォール IP 制限が既定でかけられている。 アクセス元の IP が動的に変わる場合は都度当該 IP が通るように構成し直す必要があるので、注意。 なお、通常の IP フィルタとは別に「Azure サービスへのアクセスを許可」と言う設定が用意されており、この設定をオンにすることで、「全ての Azure リソース」からのアクセスを許可することが出来る。 Azure Web Apps だろうが Azure 仮想マシンだろうが Azure リソースからの通信については全ての許可することになり、自分が管理している Azure リソース以外も許可されるので、扱いには注意。 ただ、後述するように、Azure SQL Database の機能のいくつかはこの設定がオンである事を前提としているため、単純にセキュリティだけ考慮してオフにすると、必要な機能が使用できなくなる可能性があるので、注意。

VNET に接続する方法もあるようだが、自分は動作未確認。

ファイアウォールの「全ての Azure リソース」がオンになっていないと使用できない機能がある

Azure ポータルから使用できる機能のいくつかは、別の Azure リソースからの操作となるようで、Azure リソースからの接続が許可されている必要がある。

データベースのバックアップは自動で行われている

一番安い Basic プランでも一週間前まではいつでも復帰可能。手動でのバックアップももちろん可能。

master データベースは基本的に操作できない

少なくとも、Azure ポータルからは master データベースを選択しての操作は、基本的に出来ない。 そのため、Azure SQL Database の機能の一つであるアラート機能なども、master データベースに対しては利用できない。

SSMS から直接操作することは、可能。