ASP.NETでWebアプリを作成する時にWebConfigに各種設定を記載することは多いと思います。特にDBへの接続文字列や個別設定のKeyValue等さまざまあると思います。
Azure Web Appsで運用する場合はセキュリティ上の観点からアプリケーション設定に記載してSystem.Configuration.ConfigurationManager.AppSettings[“key:embed:cite];で参照することが多いと思いますがWebConfigに記載されている同名のKeyがある場合どちらが優先されるか気になったので調べてみました。
※この記事は2017年4月20日時点の情報になります。
事前準備
検証にあたってASP.NETでサンプルアプリケーションを作成します。
作成したらWebConfigのappSettingsに検証用のKeyValueを追加します。
ログインControllerに追加したKeyValueを取得するコードを記載します。
ログイン画面のviewに表示用のViewBagを記載します。
必要なコードを記載したらF5実行しましょう。
localhostで上記のように表示されていれば成功です。
検証
次にAzureのWebAppsにデプロイします。Azureへのデプロイ方法についてはここでは割愛します。
デプロイした直後はアプリケーション設定をしていないのでWebConfigで設定している文字が表示されます。
ではここでアプリケーション設定に同一KEYで違うVALUEの設定をしてみましょう。
設定が完了したらサイト更新してみるとアプリケーション設定で設定した値が表示されると思います。つまりこれはWebConfigの値よりもアプリケーション設定の値を優先しているということになります。
試しにアプリケーション設定からkey[test2]を削除してみます。するとWebConfigに記載のある値が表示されました。
続いてkuduを確認してみましょう。
URLのサブドメインとドメインの間に「scm」を追加します。例)https://***.scm.azurewebsites.net
kuduの管理画面が開いたらEnviromentのEnviroment variables(環境変数)を確認します。アプリ設定で設定した内容が表示されていると思います。
アプリケーション設定で設定した値はkuduの環境変数になるんのでこちらを優先して取得するみたいです。
まとめ
アプリ設定の値はweb appsをホストしているapp serviceの環境変数になりSystem.Configuration.ConfigurationManager.AppSettings[“key:embed:cite];はアプリ設定を優先して取得するということがわかりました。多分ですがImmutable Infrastractureの観点からデプロイ後にサーバにあるWebConfigに変更を加えたとしても全体に影響を与えないためアプリ設定を優先的に取得しているのだと思います。WebConfigの値を変えるのであれば再デプロイするのが定石ですしね。
余談
ASP.NET開発の時にGitHubを利用する場合などで接続文字列や他システム連携用のトークンをどこに保存すべきか悩むことがあると思います。WebConfigにそのまま記載してGitHubのパブリックリポジトリにプッシュする方法はセキュリティ上の観点から推奨されていませんがローカル開発を行っている時はWebConfigに情報を記載せざるをえません。
ではどうするか?
私がよくやるのはGitHubにPushする用のビルド構成と開発用のビルド構成を分けて作成しWebConfigを各ビルド用に切り出します。開発用のWeb.開発用.Configに各種設定を記載してGitHub用のWeb.GitHub.Configには<keyを記入>等と記載しておきます。開発時は開発のビルド構成を選択してビルド時にWebConfigを書き換えて作業を行い、GitHubにPushする時はGitHub用のビルド構成でビルドを行いWebConfigを書き換えてからCommitしてPushするようにします。勿論、Web.開発用.ConfigとWeb.GitHub.Configはgit.ignoreしておきます。こうしておけばいちいちWebConfigを手動で弄る手間を減らすことが可能です。
では、Web AppsにGitHub経由でCIをする場合、接続文字列等の情報が記載されているConfigファイルがないがどうするのか?と疑問に思う方もいると思います。そこでWeb Appsのアプリケーション設定になります。
コーディング内ではSystem.Configuration.ConfigurationManager.AppSettings[“key:embed:cite];を利用して設定情報を取得しています。これは先にも述べたとおりアプリケーション設定でもWebConfigでも同じ設定情報の取得方法であり、アプリ設定が優先になる特徴をもっています。つまりWebConfigに接続文字列等の記載がなくてもアプリケーション設定に設定しておけば情報を取得できます。
もちろんアプリ設定をしていなければエラーになるので設定漏れがないようにする注意が必要です。また、RBACを利用して編集可能なユーザの絞込みもしておいたほうがいいでしょう。簡単に変更・削除ができていしまいますので。
結構いい方法だと思うのですがデメリットをあげるとしたらローカル環境とクラウド環境で設定情報が2重管理になってしまう点ですかね。
この記事を読んでもし他にいい方法を知っている方がいらっしゃれば情報をください。お願いします。
コメント