ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

Managed Service Identity を使って Azure Key Vault から接続文字列を取得する

Azure Key Vault は、アプリケーションが利用するシークレットを安全に保管してくれるサービスです。シークレットには、DBの接続文字列、API のアクセスキー、証明書などの情報があります。
アプリケーションで Azure Key Vault から接続文字列を取得するには、Azure Active Directory のサービスプリンシパルが必要となり、ソースコードに決め打ちしない構成やサービスプリンシパルの有効期間の管理など、少し手間がかかります。
Managed Service Identity(MSI)を使うことで、このあたりの煩わしさを解消できるようになっていたので、まとめておきます。

azure.microsoft.com

Azure Key Vault を作成する

Azure Portal を開いて、Azure Key Vault を作成します。特に説明は必要ないと思います。

f:id:TonyTonyKun:20190410202248p:plain

続いて、シークレットを作成します。今回は、SQL の接続文字列を想定したシークレット(SqlConnection)を追加しました。

f:id:TonyTonyKun:20190410202408p:plain

Azure Key Vault 側の準備は、これで完了です。

ローカル開発環境で接続文字列を取得する

Managed Service Identity(MSI)を利用すると、認証資格情報をアプリケーションに含めずに、Azure の各サービスへ認証を行うことができます。
今回は、ASP.NET Core で作成した Web アプリケーションで試してみます。Visual Studio のテンプレートから作成したシンプルな MVC アプリケーションです。
MSI を使って Azure Key Vault に接続するための2つの NuGet ライブラリをインストールします。

Install-Package Microsoft.Azure.KeyVault -Version 3.0.3
Install-Package Microsoft.Azure.Services.AppAuthentication -Version 1.0.3

HomeController クラスで、MSI を使って Azure Key Vault から接続文字列を取得するコードを書きます。
vaultBaseUrl は、先ほど作成した Azure Key Vault のURL です。AzureServiceTokenProvider を使って KeyVaultClient をインスタンス化している部分がポイントです。

public class HomeController : Controller
{
    public async Task<IActionResult> About()
    {
        var vaultBaseUrl = "https://xxx.vault.azure.net/";
        var provider = new AzureServiceTokenProvider();
        using (var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback)))
        {
            var secret = await client.GetSecretAsync(vaultBaseUrl, "SqlConnection");
            ViewData["Message"] = secret.Value;
        }

        return View();
    }
}

ローカル開発環境で Visual Studio からデバッグ実行してみます。Azure Key Vault に作成したシークレット(SqlConnection)の値が取得できたことがわかります。

f:id:TonyTonyKun:20190410202424p:plain

ここで疑問に思うのが、ローカル開発環境からシークレットを取得できた理由です。
最近の Visual Studio では、Azure サービス認証に登録されたアカウントのトークンを使って AzureServiceTokenProvider が生成されるようになっているので、Visual Studio から Azure Web Apps にデプロイなどの機能を使っていれば、特に意識せずに Azure Key Vault に作成したシークレットを取得することができます。

f:id:TonyTonyKun:20190420121207p:plain

環境によってこの方法が利用できない場合には、環境変数「AzureServicesAuthConnectionString」を使いましょう。設定する値については、こちらを参照してください。

Azure Web Apps で接続文字列を取得する

先ほど作成した ASP.NET Core の Web アプリケーションを Azure Web Apps にデプロイしてみます。
Azure Web Apps の MSI を有効にしておきます。このタイミングで、サービスプリンシパルが追加されます。

f:id:TonyTonyKun:20190410203001p:plain

続いて、Azure Key Vault の Access policies で、Azure Web Apps のサービスプリンシパルを許可します。必要最低限のパーミッションとして、シークレットの Get だけを許可しました。忘れずに Save ボタンで保存ましょう。

f:id:TonyTonyKun:20190410202454p:plain

ASP.NET Core の Web アプリケーションを Azure Web Apps にデプロイし、結果を確認します。

f:id:TonyTonyKun:20190410202505p:plain

Azure Key Vault に作成したシークレット(SqlConnection)の値が取得できたことがわかります。

まとめ

アプリケーションを開発する際には、DBの接続文字列、API のアクセスキー、証明書などのシークレットは手間をかけずに安全に管理したいところです。MSI と Azure Key Vault を組み合わせて使うことで、このあたりの煩わしさを解消できます。パブリックなリポジトリでシークレットを公開してしまう事故を防ぐためにも、しっかりとアーキテクチャで考慮しておきたい事項です。

Microsoft Tech Summit 2018 で登壇しました

先月の話になりますが、Microsoft Tech Summit 2018 のブレイクアウトセッション「.NET 開発者のためのマイクロサービス 入門」に登壇しました。
セッション資料と動画が一般公開されているので、イベントに参加していない方でも視聴できます。

www.youtube.com

共同登壇というスタイルだったので、後半部分の説明とデモを担当しました。
マイクロサービス というと Kubernetes がトレンドで、Java を使って開発するイメージがありますが、.NET Core でも開発できるし、.NET 開発者の皆さんにマイクロサービス開発の世界観を伝えたかったです。
でも、実際にはマイクロサービス に向かないシステムもあるので、何でもかんでもマイクロサービスにするのは止めましょう。

f:id:TonyTonyKun:20181224141952j:plain

コミュニティでの登壇は何度かありましたが、有償イベントでは初めての登壇でした。前日まではいつものお店に飲みに行くぐらい余裕な感じでしたが、当日の朝になって緊張してきて2回もリハしたことはいい思い出です(笑)

ちなみに、他のセッションについても資料や動画が一般公開されているので、冬休みを使ってキャッチアップしてみるのも良いと思います。

Microsoft Tech Summit 2018 | インフラエンジニア、アーキテクト、IT IT 戦略にかかわる皆様の為の技術カンファレンス - Microsoft Events &amp; Seminars

Azure SignalR Service で ASP.NET SignalR を使ってみる

この記事は、Azure Advent Calendar 2018 の 8 日目 の記事です。
qiita.com
Ignite 2018 で GA が発表された Azure SignalR Service ですが、ASP.NET Core SignalR だけでなく、まだプレビューですが ASP.NET SignalR にも対応しています。
今回は、Core ではない ASP.NET SignalR を使って試してみました。

Azure SignalR Service とは

Azure SignalR Service は、SignalR を使って開発したアプリケーションのコネクションやスケーリングを管理してくれるマネージドサービスです。
build 2018 のセッションから引用したスライドです。
f:id:TonyTonyKun:20181118124127j:plain
アプリケーションの規模が大きくなると、バックエンドで Redis や Service Bus を使ったコネクションやスケーリングの管理が必要になります。このような面倒なところを Azure SignalR Service に任せることができます。
Azure SignalR Service の使い方は、こちらの公式ドキュメントにある通りですが、早速試していきます。
github.com

Azure SignalR Service を作成する

Azure Portal から、Azure SignalR Service を作成します。

f:id:TonyTonyKun:20181118142922p:plain

Standard プラン以外の他に、20 コネクションまでの Free プランもあります。東日本リージョンもあるので、安心して使えます。

ASP.NET SignalR のコードを変更する

ASP.NET SignalR のプロジェクトに対して、Azure SignalR Service に対応するための変更を加えていきます。

NuGet ライブラリのインストール

まず、Azure SignalR Service 用の NuGet ライブラリの Microsoft.Azure.SignalR.AspNet をインストールします。

PM> Install-Package Microsoft.Azure.SignalR.AspNet -Version 1.0.0-preview1-10259

NuGet ライブラリをインストールしたら、HTML ファイルで指定されている JavaScript のパスを変更します。

<script src="Scripts/jquery.signalR-2.4.0-preview2-20181018-02.min.js"></script>

Startup クラスを変更する

Startup クラスで呼び出している MapSignalR メソッドを MapAzureSignalR メソッドに置き換えます。引数には、他のアプリケーションと区別する一意な名前を渡します。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        //app.MapSignalR();
        app.MapAzureSignalR(this.GetType().FullName);
    }
}

接続文字列の追加

Web.config に Azure SignalR Service の接続文字列を設定します。接続文字列は、Azure Portal から取得できます。

<connectionStrings>
  <add name="Azure:SignalR:ConnectionString" connectionString="Endpoint=xxx;AccessKey=xxx;Version=1.0;"/>
</connectionStrings>

動作確認

ASP.NET SignalR のサンプルとして、クリスマスなので懐かしい Fireworks のアプリケーションを Azure Web Apps にデプロイしました。

f:id:TonyTonyKun:20181208094616p:plain

自分で打ち上げた花火を、他のブラウザでもリアルタイムに観ることができます。
試してみたい方は、こちらの URL からどうぞ。

ブラウザの開発者ツールで確認すると、Azure SignalR Service に接続されていることがわかります。

f:id:TonyTonyKun:20181208103828p:plain

まとめ

ASP.NET SignalR は、チャットやダッシュボードなどのリアルタイムな Web アプリケーションを開発できるフレームワークです。
今から開発するなら ASP.NET Core SignalR を選択すべきですが、それが難しい場合でも Azure SignalR Service を使うことができます。
本番運用では、バックエンドでコネクションやスケーリングの管理が必須となるので、 Redis や Service Bus を使わずに Azure に任せられる嬉しいサービスだと思います。