セツゾク

Hayato Shimada Portfolio & Blog

Site cover image

Azure Web App, SQL Server 連携

ハマった

サーバーアプリ開発でかなりハマりました。

開発環境で実行できていた、データベースとアプリケーションの接続が、Azure上でうまくできずに悪戦苦闘。

Azure SQL Serverには当然ながらファイヤーウォールが敷かれているのですが、開発環境用に設定していたIPではアクセスできるのですが、公共LAN等ではアクセス不可でアプリが止まってしまいます。

しかも依頼者の前でそれをやって、アプリが動いていた家に連れていくというね。

依頼者を家に帰した後、色々調べた結果、Azure上に仮想のMicrosoft Entra認証プロバイダー(マネージドID)を用意して、アプリにログインしてくるユーザーの代わりにApp Service→SQL Databaseへの認証を行う方法が解決につながりました。

要するに今まではアプリにログインするユーザーがSQL Databaseの認証に蹴られていたのを、アプリに設定されたマネージドIDに認証してもらうという形態にするイメージですね。

環境

デプロイ:Azure App Service

アプリ開発:ASP.Net Core Blazor

認証:Azure AD B2C

SQL:Azure SQL Server

やったこと

大体このチュートリアル通りにやればできる。

色々注意点もあるので、下記にまとめていきます。

マネージドIDの前に、Microsoft EntraユーザーをSQL Serverに認証させる

自動生成されたIDの前に、実在するユーザーをSQL ServerにEntraユーザーとして認証させます。

チュートリアルではAzure CLIでのやり方が書かれていますが、Azureポータルで、Entra IDを登録してから、SQL Server Management Studioなどを使ってクエリを投げても大丈夫。

この時はCLIが怖かったので、僕はそうしました。

マネージドIDの作成

  • Azure検索窓に「マネージドID」と入力。
  • マネージドID を「作成」から、任意のサブスクリプションとリソースグループを選ぶ。
  • 「リージョン」と「名前」を入力して「確認と作成」

App Serviceに作成したマネージドIDを登録

  • 「App Service」→「作成アプリ」に移動
  • 「設定」→「ID」→「ユーザー割り当て済み」を選択
  • 「追加」で作成したマネージドIDの名前を入力して検索して登録。
hoikunがガチのアプリ名とはだれも思わないだろうな。

Azure Cloud Shellの登場

ここでいよいよAzure CLIを使います。まあ単なるAzure上で動くBashなんですけど、Azure PortalのUIに慣らされ切っていたので、渋々有効化して使いました。

チュートリアルが用意されていたので、それを見るといいと思うよ。

Azure CLIに色々インストールしてから、下記を実行します。

これによって、データベースに接続するアプリに紐づいたマネージドIDが、SQL Serverに対して、Entra IDと同様に操作が可能になります。

az webapp connection create sql 
--resource-group <group-name>  #リソースグループ名
--name <server-name> #アプリ名(マネージドIDが登録されている)
--target-resource-group <sql-group-name> #SQLのリソースグループ名(最初のリソースと一緒かもね)
--server <sql-name> #SQL Server名(マネージドIDを登録したい)
--database <database-name> #データベース名
--user-identity client-id=<client-id> subs-id=<subscription-id> #マネージドIDのclient id とサブスクリプション名
--client-type <client-type> #dotnetと入力(optionの先頭だったから。。脳死)

コードの修正

チュートリアルから外れますが、EF Coreを使いたい場合、program.csにこんな感じの記述を追加します。

// Azure SQL Database への接続を構成
string connectionString =
    Environment.GetEnvironmentVariable("AZURE_SQL_CONNECTIONSTRING")!;

// DbContext の登録
builder.Services.AddDbContext<TestContext>(options =>
    options.UseSqlServer(connectionString));

appsettings.jsonに入力してある文字列は消してもオッケーです。

余談

マネージドIDとかEntra IDとか

パルスのファルシのルシがコクーンでパージ並みに意味不明な単語が出てきますが、一つ一つ意味を抑えれば大丈夫なはず。多分。

余談1:マネージドIDって何?

ChatGPT 4o により生成

AzureにおけるマネージドIDとは、AzureリソースがAzure Active Directory (Azure AD) を利用して他のAzureサービスに安全にアクセスするための自動管理されたIDです。これにより、開発者はコード内に資格情報(ユーザー名やパスワード)を直接埋め込む必要がなくなり、セキュリティが向上します。

Microsoft Learn

マネージドIDには以下の2種類があります:

  1. システム割り当てマネージドID:特定のAzureリソース(例:仮想マシン)に直接関連付けられ、そのリソースのライフサイクルと共に作成および削除されます。

    Microsoft Learn

  2. ユーザー割り当てマネージドID:スタンドアロンのAzureリソースとして作成され、複数のAzureリソースで共有して使用できます。これらのIDは独立したライフサイクルを持ち、明示的に管理されます。

    Microsoft Learn

マネージドIDを使用することで、AzureリソースはAzure AD認証をサポートする他のサービス(例:Azure Key Vault、Azure Storage)に対して、資格情報をコードに含めずに認証およびアクセスが可能となります。

Microsoft Learn

これにより、資格情報の管理負担が軽減され、セキュリティリスクが低減されます。

余談2:Azure Entra 認証ユーザーとの違い

ChatGPT 4o により生成

  • 管理: Entra認証ユーザーは人が管理し、マネージドIDはAzureリソースによって自動的に管理されます。
  • 利用者: Entra認証ユーザーは人間のユーザーに使用され、マネージドIDはアプリケーションやサービスに使用されます。
  • アクセスの方法: Entra認証ユーザーは、ログインと認証を通じてリソースにアクセスしますが、マネージドIDはバックエンドでリソースへのアクセスを許可するために使用され、資格情報の管理が不要です。

まとめ

今回やったことをまとめると、

AzureのEntra認証ユーザーをSQL ServerにCREATEしてALTER権限を付与。

サブスクリプションのリソースグループにマネージドIDを作成し、App Serviceにユーザー割り当てマネージドIDとして登録。

Azure CLIコマンドを使ってマネージドIDをSQL Serverに割り当て、生成された環境変数をアプリが読めるようにすることで、シークレット無しでApp ServiceからSQL Databaseに認証可能になる。

ということです。

パルスのファルシのルシがコクーンでパージ