Azure Web AppsからDBへの接続情報の設定

#はじめに
WebアプリケーションでDBへの接続を行うとき、アプリケーションはどこかにDBへの接続情報を持つ必要がある。

一番シンプルな解決方法は、アプリケーション内に接続文字列として情報を埋め込むパターンだが、この方法だと接続先を変更するためにアプリケーションの再ビルドが必要となってしまい、保守の手間が大きくなる問題点がある。

二つ目の方法は、アプリケーションの構成ファイル(web.configなど)に接続情報を記述する方法で、この方法だと構成ファイルの文字列を変更してあげれば接続先の変更は可能で、アプリケーションの再ビルドは不要である。ただしこの場合別の問題が発生する。SQL ServerなどのDBでは接続文字列にIDやパスワードを記述するため、ファイルにアクセスされると機密情報が洩れてしまうセキュリティ上の問題が発生する。

アプリケーションの配置先が社内の専用サーバーであり、管理者のみがログインしてアプリのデプロイ・構成ファイルの修正を行うのであればアクセスできるユーザーが限られているという点で安全性を確保できているといえそうだが、Azure上にアプリケーションをGitデプロイする場合などは設定が書かれた構成ファイル自身もGit上に配置しないといけないため、問題となる場合が多いことが予想される。

Gitは通常開発者にもアクセス権限が付与されるが、一般に管理者でないユーザー(体制によっては部外者)に接続情報が見える環境というのは危険である。

では、接続情報はGit管理しないという方針が考えられるが、Git上デプロイでCI/CDの環境を構築しているのに構成ファイルだけは別途修正が必要というのも受け入れがたいのではないだろうか。

Azureではこの問題を解決するため、従来web.configに記述可能であったconnectionStringsセクションの情報をApp Serviceの構成情報としてAzure上で管理できる機能を持っている。

以下では、2020年2月時点でのApp Serviceでの接続文字列情報の設定方法と、アプリケーション側での値の取得について記載する。
#App Serviceにおける接続文字列の設定
設定に用いる画面は、下記のメニューから行けるApp Serviceの構成画面で行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484026/e5d3da7c-8b34-ceec-ee64-7bd7788bd7dc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484026/2c1fadc5-821c-899b-9f1e-454714747abe.png)
構成画面の下の方にある「接続文字列」の設定で、新しい接続文字列リンクを押して、設定画面を開く。
ここで「名前」はアプリケーションから接続文字列を取得する際のキーとなるので、App Service内で一意とする必要がある。

値に関しては、接続文字列をそのまま記述すればよいのだが、SQL Databaseの接続文字列画面からコピペしてくると当然パスワードの部分が書かれていないため、自分で設定してあげる必要がある。

種類のところは接続対象となるDBの種類を指定する。

接続文字列はApp Serviceに対して設定しているが、App ServiceはIISにおけるアプリケーションプールに対応していると考えられるため、App Serviceに登録した複数のアプリケーションからこの接続情報は利用することが可能である。

この点はアプリケーションごとに配置されるweb.conifgに接続情報を記述するのとは若干性質が異なるが、再起動のタイミングなどが一致する複数のアプリケーションが接続文字列を共有することはそこまで不自然な設定ではないだろう。

なお、ここで設定した値はweb.configに反映されることはなくあくまでアプリケーションから利用可能となっただけである。ファイルに接続情報が書かれないという点がこのアプローチがセキュアな理由である。
#アプリケーションからの接続文字列の利用
アプリケーションから接続文字列を利用するのは、web.configにconnectionStringsセクションを記述した場合と全く同じである。以下に簡単なサンプルコードを載せる。

VS2019でASP.NET Webアプリケーションプロジェクトを新規作成すると、自動でサンプルのアプリケーションが作成される。このアプリケーションのdefault.aspxに設定した接続文字列を表示するコードを追加する。

```xml:default.aspx
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GetConnectionStringSample._Default" %>
 
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
 
    <div class="jumbotron">
        <h1>ASP.NET</h1>
        <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS, and JavaScript.</p>
        <p><a href="http://www.asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p>
    </div>
 
    <div class="row">
        <div class="col-md-4">
            <h2>Getting started</h2>
            <p>
                ASP.NET Web Forms lets you build dynamic websites using a familiar drag-and-drop, event-driven model.
            A design surface and hundreds of controls and components let you rapidly build sophisticated, powerful UI-driven sites with data access.
            </p>
            <p>
                <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301948">Learn more &raquo;</a>
            </p>
        </div>
        <div class="col-md-4">
            <h2>Get more libraries</h2>
            <p>
                NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.
            </p>
            <p>
                <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301949">Learn more &raquo;</a>
            </p>
        </div>
        <div class="col-md-4">
            <h2>Web Hosting</h2>
            <p>
                You can easily find a web hosting company that offers the right mix of features and price for your applications.
            </p>
            <p>
                <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301950">Learn more &raquo;</a>
            </p>
        </div>
        <!-- ここから -->
        <div class="col-md-4">
            <h2>ConnectionString</h2>
            <p>
                接続文字列
            </p>
            <p>
                <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
            </p>
        </div>
        <!-- ここまで追記 -->
    </div>
</asp:Content>
```
コードビハインドには、Labelに対して接続文字列をセットするコードを記述する。

```cs:default.aspx.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace GetConnectionStringSample
{
    public partial class _Default : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            var csSection = ConfigurationManager.ConnectionStrings["SqlDbConnection"];
            if(csSection != null)
            {
                Label1.Text = csSection.ConnectionString;
            }
            else
            {
                Label1.Text = "接続文字列が定義されていません";
            }
        }
    }
}
```
ここで、ConfigurationManager.ConnectionStrings["SqlDbConnection"]の「SqlDbConnection」の部分がApp Serviceの接続文字列で定義した「名前」の部分である。

このアプリケーションをAzure上にデプロイし、App Serviceで「SqlDbConnection」という接続文字列を定義すれば、設定した接続文字列が画面上に表示されるはずである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484026/749c139f-3873-0a14-e667-6a16dddc129f.png)