はじめに
Azure Container Appsでアプリケーションを実行する際、KeyVaultからContainer Appsにシークレット値を格納したり、ボリュームとしてマウントしたいということが多々あると思います。
2023年7月20日現在、KeyVaultからシークレットを参照する機能はPreviewとなっていますが、今回は先取りして実際に使ってみたいと思います。
指定方法
Bicepファイルの内容は以下のようになります。
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31'existing = { name: managedIdentityName } resource environment 'Microsoft.App/managedEnvironments@2023-04-01-preview' existing = { name: acaEnvironmentName } resource app 'Microsoft.App/containerApps@2023-04-01-preview' = { name: appName location: location identity: { type: 'UserAssigned' userAssignedIdentities: { '${managedIdentity.id}': {} } } properties: { managedEnvironmentId: environment.id configuration: { // 〜〜省略〜〜 secrets: [ { // ${kv.properties.vaultUri} は末尾に '/' を含んでいます keyVaultUrl: '${kv.properties.vaultUri}secrets/appSecret1' name: 'appenv1' identity: managedIdentity.id } { keyVaultUrl: '${kv.properties.vaultUri}secrets/appSecret2' name: 'appenv2' identity: managedIdentity.id } { keyVaultUrl: '${kv.properties.vaultUri}secrets/secretConfig' name: 'secretfile' identity: managedIdentity.id } ] // 〜〜省略〜〜 } template: { containers: [ { image: '${appImageName}:${appImageTag}' name: appName env:[ { name: 'APP_ENV_1' secretRef: 'appenv1' } { name: 'APP_ENV_2' secretRef: 'appenv2' } ] // 〜〜省略 volumeMounts: [ { volumeName: 'secret-config' mountPath: '/mnt/config' } ] } ] volumes: [ { name: 'secret-config' storageType: 'Secret' secrets: [ { secretRef: 'secretconfig' path: 'secret-config.yaml' } ] } ] // 〜〜省略〜〜 tags: tags }
参照するシークレット情報の指定
KeyVaultからシークレットを取得するために必要となるのが properties.configration.secrets
です。
ここに環境変数として参照するもの、ファイルとしてマウントするもの、双方の項目情報をすべて列挙しなければなりません。
指定内容は以下のようになります。
{ keyVaultUrl: '${kv.properties.vaultUri}secrets/appSecret2' name: 'appenv2' identity: managedIdentity.id }
name
はこのアプリケーションリソース内におけるシークレットのキーです。キーは小文字の英数字、'_'または'.'が使用可能です。また先頭と末尾は英数字を使用しなければなりません。
identity
はKeyVault へのアクセスする際にmanaged identityを利用する場合に指定します。このmanaged identityはBicep中の identity
のところで指定してある必要があります。またここではUser managed identitiyを使用していますが、System managed identityを使用する場合は 'System' と指定します。
keyVaultUrl
は参照するシークレット値のURLです。 secretの場合、https://${kv.properties.vaultUri}
とkeyvaultのリソース情報を参照するとよいでしょう。このとき${kv.properties.vaultUri}
の末尾には '/' が含まれていることに注意してURLを指定してください。
なお、指定の際、末尾にバージョン情報をつけることができます。バージョン情報を省略した場合、最新バージョンの値を参照します。バージョンを指定していない場合、新しいバージョンがKeyVault上で有効になると、30分以内にアプリケーションは最新バージョンを取得します。また、環境変数でシークレットを参照している場合は自動的に再起動されます。
シークレット値の環境変数への格納
まずは環境変数に格納してみましょう。 properties.template.containers[].env
で環境変数を指定します。
{ name: 'APP_ENV_1' secretRef: 'appenv1' }
name
には環境変数名を指定します。
secretRef
には さきほどの secrets のところで指定した name
のキーを指定します。
これだけで終了です。
シークレットファイルのマウント
KeyVaultのシークレットにファイルを登録することもあると思います。そうした場合はボリュームとしてマウントして利用します。まずは properties
.template.volumes[]` への指定です。
{ name: 'secret-config' storageType: 'Secret' secrets: [ { secretRef: 'secretconfig' path: 'secret-config.yaml' } ] }
name
にはあとでvolumeMount時に使用するためのキー名を記述します。
storageType
は今回KeyVaultを利用してるため 'Secret' と指定します。
secrets[]
にはシークレットに格納されているファイルの情報を記述します。secretRef
には さきほどの secrets のところで指定した name
のキーを指定します。pathには マウントする際のファイル名を記述します。
続いて properties.template.containers[].volumeMounts
です。ここからは通常のvolumeMountと同じです。
{ volumeName: 'secret-config' mountPath: '/mnt/config' }
volumeName
はさきほどvolumesで指定したボリュームのキー名を指定します。mountPathはマウントする際のディレクトリ名を指定します。
以上で完了です。
今後の課題
シークレットの更新時の動作として以下のようになっていると記載しました。
バージョンを指定していない場合、新しいバージョンがKeyVault上で有効になると、30分以内にアプリケーションは最新バージョンを取得します。また、環境変数でシークレットを参照している場合は自動的に再起動されます。
確かに環境変数で指定されている場合、自動的に再起動するのですが、ボリュームマウントの場合は再起動されないのではないかと思われます。(再起動されなかったように見えた)
このあたりは今後も詳細を確認する必要があります。
ただ、実際の運用では、アプリケーションリビジョンのロールバックなどを行うことを考えると明示的にバージョン名をつけるべきではないかと考えており、大きな問題にはならないのではとも思います。
おまけ
今回の話題とは直接関係ありませんが、Container Appsでmanaged identityを利用したアプリケーションを実行する場合、環境変数として AZURE_CLIENT_ID を指定しておく必要があるそうです。
AKSのWorkload Identityの場合、このあたりの環境変数は自動的に設定されていたのですが、Container Appsの場合はそうなっていませんでした。今回のシークレットと合わせてこちらも設定しておくとよいかもしれません。
最後に
いかがだったでしょうか。まだPreviewではありますが、シークレット情報を直接Bicep等に記載する必要のない本機能は非常に有用なものなので積極的に活用していきたいところですが、まだまだ情報も少ないこともあり、ドキュメント等をみても指定方法に戸惑うこともあるかと思います。そうした場合に今回の例を参考にしていただければ幸いです。
また、これまでのAzure Container Appsの記事でも様々な情報を提供しております。ぜひご活用ください。
ACS事業部のご紹介
私たちACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。 ぜひお声がけください。