【Azure】App Serviceでアプリケーション設定やDB接続文字列をデプロイスロットにひも付けるにはTech TIPS

AzureのApp Serviceで「運用」「ステージング」といった「デプロイスロット」をスワップする際、アプリケーション設定やDB接続文字列の一部は入れ替えずにスロットとひも付けておきたいことがある。この「デプロイスロットの設定」をリソーステンプレートに記述してデプロイする方法は?

» 2023年04月12日 05時00分 公開
[島田広道デジタルアドバンテージ]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「Tech TIPS」のインデックス

連載目次

対象:Azure App Service(サービスレベルは「Standard」「Premium」「isolated」のいずれか)、Bicep


 本Tech TIPSでは、リソーステンプレートを使ってAzure App Serviceをデプロイする際、その記述箇所がやや分かりにくい「デプロイメントの設定」について説明する。

■執筆時の各種ツール/APIのバージョン

  • Azure CLI: Ver.2.47.0
  • Bicep CLI: Ver.0.16.1
  • Bicepでのデプロイ時のAPIバージョン: 2022-03-01

ところで「デプロイスロット」とは?

 AzureのApp Serviceには、複数の「デプロイスロット」を作成する機能が備わっている(サービスレベルは「Standard」「Premium」「isolated」のいずれかが必要)。「デプロイスロット」とはWebアプリを固有のホスト名で実行できる環境のことだ。

 デフォルトの設定でApp Serviceをデプロイすると、1つの「運用スロット」が生成される。さらに「ステージング」「開発」といったデプロイスロットを追加し、それぞれに別々のホスト名を割り当てつつ、固有のWebアプリをデプロイすることが可能だ。

 また、運用スロットとステージングスロットを「スワップ」することで、ステージングスロットでテストしていた新バージョンのアプリを速やかにライブサイトで公開することもできる。スワップすることで、コンテンツ(ファイル)や多くの設定が運用とステージングの間で入れ替わることになる。

デプロイスロットのスワップ時に入れ替えたくない設定項目がある!?

 さて、このスワップの際、設定項目によってはスロット間で入れ替えたくない、つまりスロットにひも付けておきたい場合がある。

 例えばWebアプリのプログラムに対し、環境変数を介してスロットの種別を伝えるために、「アプリケーション設定」に設定項目を追加したとしよう(後述のスクリーンショットにある「SiteType」)。すると、デフォルトではスワップ時に入れ替わるため、運用(Production)スロットなのに「stage」という値が設定されてしまう。

 また、スロットごとにデータベースを変えなければいけない場合、「接続文字列」に設定してあるデータベース接続文字列も、デフォルトの設定のままスワップすると、運用スロットなのにステージング用データベースに接続されてしまうことになる。

「デプロイスロットの設定」とは?

 そこでApp Serviceには、「アプリケーション設定」「接続文字列」の設定項目ごとに、スロットにひも付ける(スワップ時に入れ替えない)ように指定する機能がある。

 Azureポータルの場合、App Serviceの[構成]−[アプリケーション設定]タブを開き、「アプリケーション設定」「接続文字列」の一覧で対象の設定項目の「名前」をクリックする。編集/追加の画面が表示されるので、そこにある[デプロイスロットの設定]チェックボックスにチェックを入れて「オン」にして、[OK]ボタンをクリックして設定を反映する。これで対象の設定項目はスワップ時に入れ替わらなくなる。

App Serviceの「アプリケーション設定」「接続文字列」にある「デプロイスロットの設定」(1/2) App Serviceの「アプリケーション設定」「接続文字列」にある「デプロイスロットの設定」(1/2)
App Serviceの「アプリケーション設定」「接続文字列」にある「デプロイスロットの設定」(2/2) App Serviceの「アプリケーション設定」「接続文字列」にある「デプロイスロットの設定」(2/2)

 上記のスクリーンショットのような設定でスワップしたときの挙動を下図に記す。

デプロイスロットでスワップされる設定項目とスワップされない項目 デプロイスロットでスワップされる設定項目とスワップされない項目

【Bicep】デプロイ時に特定のアプリケーション設定/接続文字列をスロットにひも付けるには

 それでは、リソーステンプレートを使ってApp Serviceをデプロイする場合、どのように「デプロイスロットの設定」をリソーステンプレートにを記せばよいのだろうか?

 「アプリケーション設定」そのものは以下のいずれかのリソースに記述する。

  • Microsoft.Web/sites」リソースの「properties」−「siteConfig」−「appSettings
  • Microsoft.Web/sites/config」かつ「name: 'web'」のリソースの「properties」−「appSettings

 「接続文字列」は以下のいずれかに記述する。

  • Microsoft.Web/sites」リソースの「properties」−「siteConfig」−「connectionStrings
  • Microsoft.Web/sites/config」かつ「name: 'web'」のリソースの「properties」−「connectionStrings

 となると、「デプロイスロットの設定」も上記リソースに記述すればよさそうに思える。

 しかし実際には、以下のように別のリソースに記述しなければならない。

  • Microsoft.Web/sites/config」かつ「name: 'slotConfigNames'」のリソースの「properties」−「appSettingNames」または「connectionStringNames

 以下にBicepでのリソーステンプレートの例を記す(前述のスクリーンショットや図に合わせている)。まずは「アプリケーション設定」を変数「appSettings」に、また「接続文字列」を「connectionStrings」にそれぞれ代入している。このとき、スロットにひも付けるかどうかを表す「sticky」というプロパティを追加している。

// ライブ: prod、ステージング: stage、開発: dev
param appEnv string = 'prod'

// アプリケーション設定
var appSettings = [
  {
    name: 'APIKey'
    value: 'aaaaBBBBccccDDDD'
    sticky: false // スロットにひも付けない
  }
  {
    name: 'SiteType'
    value: appEnv
    sticky: true // スロットにひも付ける
  }
]

// 接続文字列
var dbServer = '<DBサーバのFQDN>'
var auditDBConnStr = 'mysql:host=${dbServer};dbname=auditdb,user,password'
// ↓のデータベース名はスロットごとに変えたいので、スロットとのひも付けが必要
var mainDBConnStr = 'mysql:host=${dbServer};dbname=maindb_${appEnv},user,password'
var connectionStrings = [
  {
    connectionString: auditDBConnStr
    name: 'AuditDB'
    type: 'MySql'
    sticky: false // スロットにひも付けない
  }
  {
    connectionString: mainDBConnStr
    name: 'MainDB'
    type: 'MySql'
    sticky: true // スロットにひも付ける
  }
]

【Bicep】アプリケーション設定と接続文字列の定義(例)

 リソースを生成する際には、「for」構文で変数「appSettings」「connectionStrings」の内容を列挙している。「Microsoft.Web/sites/config」かつ「name: 'slotConfigNames'」のリソースにおいては、論理演算子「<条件式> ? <真の値> : <偽の値>」も併用して、「sticky」が真である項目のみ、その「name」を列挙している。

param location string = resourceGroup().location

// リソース生成: App Service本体
resource webApp 'Microsoft.Web/sites@2022-03-01' = {
  name: '<アプリ名>'
  location: location
  properties: { serverFarmId: <App Serviceプランのリソース>.id }
}

// リソース生成: App ServiceのWeb設定
resource webConfig 'Microsoft.Web/sites/config@2022-03-01' = {
  parent: webApp // 親となるApp Serviceのリソース
  name: 'web' // 必ず「web」とする
  properties: {
    // stickyに関係なく全項目を列挙
    appSettings: [for appSet in appSettings: {
      name: appSet.name
      value: appSet.value
      // ここにstickyは記さない
    }]
    connectionStrings: [for connStr in connectionStrings: {
      connectionString: connStr.connectionString
      name: connStr.name
      type: connStr.type
      // ここにstickyは記さない
    }]
  }
}

// リソース生成: App Serviceのデプロイスロット設定
resource slotConfig 'Microsoft.Web/sites/config@2022-03-01' = {
  parent: webApp // 親となるApp Serviceのリソース
  name: 'slotConfigNames' // 必ず「slotConfigNames」とする
  properties: {
    // stickyが真である項目だけ、そのnameを列挙
    appSettingNames: [for appSet in appSettings: appSet.sticky ? appSet.name : null]
    connectionStringNames: [for connStr in connectionStrings: connStr.sticky ? connStr.name : null]
  }
}

【Bicep】App Serviceとその設定に関するリソースの生成(例)
App Serviceプランおよびステージングスロット自体のリソース生成は省略しているので、適宜追加していただきたい。

 注意が必要なのは、「デプロイスロットの設定」をスロットのリソースに対して設定できないという点だ(する必要もない)。「name: 'slotConfigNames'」の親(「parent」の値)は「Microsoft.Web/sites」のリソースに限られ、スロットである「Microsoft.Web/sites/slots」のリソースは設定できない(強行するとエラーになる)。

 「name: 'slotConfigNames'」のリソースでは、「azureStorageConfigNames」というプロパティでストレージアカウントとスロットのひも付けも設定できる。詳しくはMicrosoft Learnのレファレンスを参照していただきたい。

「Tech TIPS」のインデックス

Tech TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。