grasys blog
grasysブログ

Azure キーコンテナーのシークレットがApp Serviceに反映されるまで

こんにちは。 通勤時間が長めの田舎在住エンジニアのsakaiです。

私が担当した業務でAzureのキーコンテナーに格納したシークレット値が反映されないということが発生しました。

AppServiceの再起動なども行いましたが値が反映されないなどがあったため、いつシークレットが正常に反映されるのか検証を行いました。

準備

キーコンテナーにシークレットを作成

キーコンテナーのシークレットに sakai-key-test を作成します。

値は test01 とします。

App Service側にシークレット参照する変数追加

変数を追加した段階でApp Serviceの構成変更を行うことになり、シークレットの最新の値を取得することになります。

環境変数を表示するようにプログラム修正

今回はPHPのLaravelフレームワークを用いて検証を行っております。

書く場所としてはroutes/web.phpで、http://ホスト名/ でアクセスしたときに画面上にすぐに変数の中身が表示されるようにしております。

Route::get('/', function () {
    echo env('SAKAI_KEY_TEST');
});

ここまでの準備で実際にアクセスしてみると以下のように画面に表示されることを確認できます。

シークレット更新

キーコンテナーのシークレットの値を変更する

まずは値をtest01からtest02に変更してみます。

App Serviceを再起動

冒頭でもお話しましたが、AppServiceの再起動ではシークレットを更新して即時反映はしてくれません。

ただ再起動前に存在していた3つのインスタンスは消失し、新しいインスタンスが生成されました。

しかし構成を変更せずに再起動のみ行うと、更新されたシークレット値をキーコンテナーからフェッチされず、前の値が残り続けます。

スワップを実行

本検証を行っているAppService環境ではproduction slotとstaging slotを用意しており、その2つをスワップで入れ替えます。

※ここで言うproduction slotとstaging slotというのは商用(production)と検証(staging)という意味合いではなく、アプリケーションへのリクエストをメインで動かすスロットをproduction slotと言い、そのメインのスロットのスタンバイの方をstaging slotと言っています。

production slotとstaging slotを入れ替えると再起動と同様にインスタンスが再生成されます。

結果、最新のシークレットの値がフェッチされていました。

スワップ再実行

もしかするとslot切り替えによって前の値(test01)になる可能性があるので再度スワップを行ってみます。
前回のスワップ同様、インスタンスが再生成されます。

結果、前の値に戻ることはなく、双方のスロットで最新のシークレットをフェッチすることができました。

シークレットの値を変更して自動反映させる

公式のドキュメントではApp Serviceのローテーション機能により24時間以内に自動フェッチがされると書いてあります。
https://docs.microsoft.com/ja-jp/azure/app-service/app-service-key-vault-references#rotation

シークレットの値を変更して、ローテーションにより自動フェッチがドキュメント通りにされるのか試してみました。

シークレットの値変更

test02となっていた値をtest03と変更します。
ちなみにこちらを変更したのは17時ちょうどぐらいです。

当たり前ですが変更直後はこれまで同様、値は更新されません。

24時間経過前

24時間以内に自動フェッチされるということで次の日の10時に再度、値を確認。
アクセスしてみると最新の値にフェッチが確認できました。

しかし、複数回アクセスしてみると変更前の値が表示されました。

インスタンスのIDを昨日のIDと見比べると一つだけ昨日のtest02が反映されたインスタンスが残っており、どうやらそのインスタンスにアクセスが行くと変更前の値が表示されてしまうようです。

24時間経過後

そして24時間以上経過した18時頃に再度アクセスしてみます。
結果、何度アクセスしても最新のシークレットの値が表示されるようになりました。

結論

App Serviceの構成変更を伴わない再起動では自動フェッチされない

シークレットがフェッチされるのがApp Serviceに対して行われるため、App Service自体の構成変更を行わないと最新のシークレットは反映されず、インスタンスが再生成されても古い値のまま再生成されてしまいます。

スワップすることで反映はされるが、注意点もあり

前述した内容ではスワップをしたことで反映されていますが、反映の方法としてまずstaging slotに変数を追加し(ここでApp Serviceの構成が変更となっているので最新の値がフェッチできている)、その後スワップしているので出来て当たり前と言えば当たり前でした。
もし構成を変更せずにただのスワップを行った場合は反映されない可能性があるのですが、今回はそこの検証ができていないため、また別の機会に検証出来たらと思います。

シークレットの値を変更して24時間経過で自動フェッチはされるが、古い値を保持したインスタンスが残っていると古い値が表示されてしまう

上記の挙動は変数の値によってはサービス障害にもなりかねないので、自動反映を行う際は上記の挙動を理解した上で自動反映を行うようにしたほうが良さそうです。