ほりひログ

所属組織の製品 (Azure とか) に関連する内容が多めだけど、個人の見解であって、所属組織を代表する公式情報ではないです。

Key Vault 参照の自動更新を試してみた

f:id:horihiro:20210311154652p:plain

Key Vault 参照とは

ざっくりいうと、

  • Key Vault で厳重に管理されたシークレットに、App Service 上の Web アプリケーションから簡単に参照する機能。

というもの。

これを使わないと、Key Vault で管理されたシークレット (秘匿性の高い文字列、他のサービスから提供された API キーとか) に Web アプリケーションから参照するには、

  • Key Vault へのアクセス処理を、アプリケーション上にゴリゴリ実装する (Key Vault の SDK が必要)
  • アプリケーション設定に生で保存する ( Key Vault での安全な管理をあきらめる) 。

のどれかだった(はず)。

当然、アプリケーション設定に保存してた場合は、App Service リソースの参照権限があればあっさり見れてしまう。

Key Vault 参照では、

  • App Service のアプリケーション設定に特殊な文字列 ( @Microsoft.KeyVault({referenceString}) という参照用の文字列) を設定
  • App Service のマネージド ID を有効にして、その App Service リソースのマネージド ID に Key Vault 参照権限を持たせる

とすることで、Web アプリケーション (と Key Vault への参照権限があるユーザー) からのみ参照を許可にする制御が可能になる。

しかも Web アプリケーションからはアプリケーション設定に生で保存した時と同じように、環境変数として見える。 Web アプリケーションに特殊な実装は不要。なので Key Vault SDK もいらない。割と便利。

ちゃんと知りたい人はこちら。

docs.microsoft.com

Key Vault シークレットのバージョンとバージョン レス参照

一方で、Key Vault に保存されたシークレットにはバージョンがあり。上記の Key Vault 参照用の文字列も下記 2 パターンの書式になっていた。

  • SecretUri=https://VAULT_NAME.vault.azure.net/secrets/SECRET_NAME/SECRET_VERSION
  • VaultName=VAULT_NAME;SecretName=SECRET_NAME;SecretVersion=SECRET_VERSION

この通り、シークレットのバージョン (SECRET_VERSION) が必要。2020 年までは。

これが、最近バージョン指定が不要になり、バージョンを省略した場合は、最新バージョンを参照するようになった。

f:id:horihiro:20210314074332p:plain

App Service 基盤が、App Service から参照されている Key Vault シークレットを定期巡回 (1日1回くらい?) し、新バージョンが追加されていたらアプリケーション側に自動反映する、というもの。なるほど。

試してみた

アプリケーション上から Key Vault 参照の結果を確認できれば何でもいいので、Web ブラウザー上でサクッと環境変数一覧が確認できる php を使用。

手順。

  1. App Service でマネージド ID を有効化する
    f:id:horihiro:20210314075202p:plain
  2. Key Vault のアクセス ポリシーで、シークレットに対する参照権限を App Service のマネージド ID に付与する
    f:id:horihiro:20210314075348p:plain
  3. Key Vault に適当なシークレットを保存する
    f:id:horihiro:20210314075301p:plain
  4. App Service のアプリケーション設定に、Key Vault 参照を追加する
    正常に参照されると下のように表示される
    f:id:horihiro:20210314075917p:plain
  5. 確認用の Web ページとして下記 php ファイルを App Service のホーム (D:\home\site\wwwroot or /home/site/wwwroot ) に置いて Web ブラウザーで開く。
    f:id:horihiro:20210314080357p:plain
    いろいろ表示されるが、その中に環境変数一覧のセクションがあるので、ここに Key Vault 参照として設定したアプリケーション設定が表示されるか確認する。
  6. Key Vault シークレット側に新バージョンを追加し、1 日放置しておく。
    f:id:horihiro:20210314100006p:plain

とある日のお昼時に新バージョンのシークレットを追加してみると、翌朝にはアプリケーションから参照している値が更新されていることを確認できた。

App Service かどうかに関係なく、環境変数の更新にはプロセスの再起動が必要な気がするので、アプリケーションの再起動が発生していたか確認してみる。
# 今回確認したかったのはこの「再起動の有無」。

Kudu の Process Explorerw3sp.exe の情報を見る。

  1. Key Vault 参照設定直後
    f:id:horihiro:20210311171829p:plain
  2. シークレットへの新バージョン追加から 1 日後
    f:id:horihiro:20210311171841p:plain

プロセス ID が変わっているし、start time も更新されている。やはりアプリケーション自体に再起動がかかっている。

ドキュメントには 1 日以内 と書いてあるけど、start time の時刻からは、今回は半日ほどで更新されたみたい。

念のため [問題の診断と解決] の "Web App Restarted" から再起動の有無を確認してみると、キチンと「環境変数が変わったから再起動したからね!」って言っている。

f:id:horihiro:20210311171854p:plain

というわけで、おおむね予想通りの挙動。納得。

注意点

参照先のシークレットの新バージョンを検知すると自動的に再起動するので、再起動の数をできるだけ減らしたい人は設定しない方がいいかもしれない。
とはいっても、App Service 基盤は月に 1 回くらい更新していて、その反映のために (Key Vault 参照の設定に関係なく) 再起動は自動的にされるので、スタートアップ時間を短縮する、とか再起動が起こっても影響がないようにアプリケーションを実装しておくことがお勧め。

余談

実は、バージョンを省略した Key Vault 参照文字列で、最新バージョンを参照する挙動は、以前から非公式で動いていた。
今回は、それに自動更新の仕組み (定期的な最新バージョン チェックと自動再起動) が追加され、きちんとドキュメントに記載された (公式の使用法になった) という話でした。

おわり。