共用方式為


如何將基礎結構轉譯為 IaC 範本

服務 連線 or 可協助使用者只需按幾下滑鼠或命令,即可將計算服務連線到以備份服務為目標。 從開始使用到生產階段時,使用者也需要在 CI/CD 管線中使用基礎結構即程式代碼範本,從使用手動設定轉換到使用基礎結構即程式碼 (IaC) 範本。 在本指南中,我們會示範如何將連線的 Azure 服務轉譯為 IaC 範本。

必要條件

解決方案概觀

將基礎結構轉譯為 IaC 範本通常牽涉到兩個主要部分:布建來源和目標服務的邏輯,以及建置連線的邏輯。 若要實作布建來源和目標服務的邏輯,有兩個選項:

  • 從頭開始撰寫範本
  • 從 Azure 導出範本並加以磨練

若要實作建置連線的邏輯,有三個選項:

  • 在 應用程式組態 中使用服務 連線 或儲存組態
  • 在範本中使用服務 連線 or
  • 使用範本邏輯直接設定來源和目標服務

這些不同選項的組合可能會產生不同的解決方案。 由於 Service 連線 or 中的 IaC 限制,建議您依照下列順序實作下列解決方案。 若要套用這些解決方案,您必須瞭解 IaC 工具和範本撰寫文法。

解決方案 布建來源和目標 建置連線 適用的案例 優點 缺點
1 從頭開始撰寫 使用服務 連線 或將組態儲存在 應用程式組態 在允許即時流量之前,先對雲端資源進行實時檢查 - 範本簡單易讀
- 服務 連線 或帶來額外的值
- Service 連線 or 未引進 IaC 問題
- 需要額外的相依性,才能從 應用程式組態 讀取組態
- 檢查雲端資源活躍度的成本
2 從頭開始撰寫 使用服務 連線 or 在允許即時流量之前,先對雲端資源進行實時檢查 - 範本簡單易讀
- 服務 連線 or 帶來額外的值
- 檢查雲端資源活躍度的成本
3 從頭開始撰寫 直接在範本中設定來源和目標服務 雲端資源上沒有即時性檢查 - 範本簡單易讀 - 無法使用服務 連線 或功能
4 匯出和拋光 在 應用程式組態 中使用服務 連線 或儲存組態 在允許即時流量之前,先對雲端資源進行實時檢查 - 資源與雲端中的資源完全相同
- 服務 連線 or 帶來額外的價值
- Service 連線 or 不會引進 IaC 問題
- 需要額外的相依性,才能從 應用程式組態 讀取組態
- 檢查雲端資源活躍度的成本
- 僅支援 ARM 範本
- 了解和改進範本所需的努力
5 匯出和拋光 使用服務 連線 or 在允許即時流量之前,先對雲端資源進行實時檢查 - 資源與雲端中的資源完全相同
- 服務 連線 or 帶來額外的價值
- 檢查雲端資源活躍度的成本
- 僅支援 ARM 範本
- 了解和改進範本所需的努力
6 匯出和拋光 直接在範本中設定來源和目標服務 雲端資源上沒有即時性檢查 - 資源與雲端上的資源完全相同 - 僅支援 ARM 範本
- 努力瞭解和磨練範本
- 無法使用服務 連線 或功能

製作範本

下列各節說明如何建立 Web 應用程式和記憶體帳戶,並使用 Bicep 將它們與系統指派的身分識別連線。 它示範如何使用服務 連線 或範本邏輯來執行這項操作。

布建來源和目標服務

從頭開始撰寫

從頭開始撰寫範本是布建來源和目標服務的慣用和建議方式,因為它很容易開始使用,並讓範本變得簡單易懂。 以下是一個範例,使用最少的參數集來建立Webapp和記憶體帳戶。

// This template creates a webapp and a storage account.
// In order to make it more readable, we use only the mininal set of parameters to create the resources.

param location string = resourceGroup().location
// App Service plan parameters
param planName string = 'plan_${uniqueString(resourceGroup().id)}'
param kind string = 'linux'
param reserved bool = true
param sku string = 'B1'
// Webapp parameters
param webAppName string = 'webapp-${uniqueString(resourceGroup().id)}'
param linuxFxVersion string = 'PYTHON|3.8'
param identityType string = 'SystemAssigned'
param appSettings array = []
// Storage account parameters
param storageAccountName string = 'account${uniqueString(resourceGroup().id)}'


// Create an app service plan 
resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = {
  name: planName
  location: location
  kind: kind
  sku: {
    name: sku
  }
  properties: {
    reserved: reserved
  }
}


// Create a web app
resource appService 'Microsoft.Web/sites@2022-09-01' = {
  name: webAppName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    siteConfig: {
      linuxFxVersion: linuxFxVersion
      appSettings: appSettings
    }
  }
  identity: {
    type: identityType
  }
}


// Create a storage account
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}

匯出和拋光

如果您要布建的資源與您在雲端中布建的資源完全相同,則從 Azure 導出範本可能是另一個選項。 此方法的兩個內部部署是:資源存在於 Azure 中,而您正針對 IaC 使用 ARM 範本。 按鈕Export template通常位於側邊欄底部 Azure 入口網站。 導出的 ARM 範本會反映資源的目前狀態,包括 Service 連線 or 所設定的設定。 您通常需要知道資源屬性,以磨練導出的範本。

Azure 入口網站 的螢幕快照,其中導出 Web 應用程式的 arm 範本。

建置連線邏輯

使用服務 連線 或將組態儲存在 應用程式組態

使用 應用程式組態 來儲存組態自然支援 IaC 案例。 因此,建議您盡可能使用此方法來建置您的 IaC 範本。

如需簡單的入口網站指示,請參閱此 應用程式組態 教學課程。 若要將這項功能新增至 bicep 檔案,請在服務 連線 or 承載中新增 應用程式組態 標識符。

resource webApp 'Microsoft.Web/sites@2022-09-01' existing = {
  name: webAppName
}

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
  name: storageAccountName
}

resource appConfiguration 'Microsoft.AppConfiguration/configurationStores@2023-03-01' existing = {
  name: appConfigurationName
}

resource serviceConnector 'Microsoft.ServiceLinker/linkers@2022-05-01' = {
  name: connectorName
  scope: webApp
  properties: {
    clientType: 'python'
    targetService: {
      type: 'AzureResource'
      id: storageAccount.id
    }
    authInfo: {
      authType: 'systemAssignedIdentity'
    }
    configurationInfo: {
      configurationStore: {
        appConfigurationId: appConfiguration.id
      }
    }
  }
}

使用服務 連線 or

如果使用 Service 連線 or 在來源與目標服務之間建立連線,如果服務 連線 或 IaC 限制對您的案例並不重要,則建議使用方式。 服務 連線 or 可讓範本更簡單,也提供額外的元素,例如連線健康情況驗證,如果您直接透過範本邏輯建置連線,則不會有此驗證。

// The template builds a connection between a webapp and a storage account 
// with a system-assigned identity using Service Connector

param webAppName string = 'webapp-${uniqueString(resourceGroup().id)}'
param storageAccountName string = 'account${uniqueString(resourceGroup().id)}'
param connectorName string = 'connector_${uniqueString(resourceGroup().id)}'

// Get an existing webapp
resource webApp 'Microsoft.Web/sites@2022-09-01' existing = {
  name: webAppName
}

// Get an existig storage
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
  name: storageAccountName
}

// Create a Service Connector resource for the webapp 
// to connect to a storage account using system identity
resource serviceConnector 'Microsoft.ServiceLinker/linkers@2022-05-01' = {
  name: connectorName
  scope: webApp
  properties: {
    clientType: 'python'
    targetService: {
      type: 'AzureResource'
      id: storageAccount.id
    }
    authInfo: {
      authType: 'systemAssignedIdentity'
    }
  }
}

如需建立服務 連線 or 資源時所需的屬性和值格式,請檢查如何提供正確的參數。 您也可以在 Azure 入口網站 中建立服務 連線 or 資源時預覽並下載 ARM 範本以供參考。

Azure 入口網站 的螢幕快照,其中導出服務連接器資源的arm範本。

使用範本邏輯

針對服務 連線 或 IaC 限制很重要的案例,請考慮使用範本邏輯直接建置連線。 下列範本示範如何使用系統指派的身分識別,將記憶體帳戶連線到 Web 應用程式。

// The template builds a connection between a webapp and a storage account 
// with a system-assigned identity without using Service Connector

param webAppName string = 'webapp-${uniqueString(resourceGroup().id)}'
param storageAccountName string = 'account${uniqueString(resourceGroup().id)}'
param storageBlobDataContributorRole string  = 'ba92f5b4-2d11-453d-a403-e96b0029c9fe'

// Get an existing webapp
resource webApp 'Microsoft.Web/sites@2022-09-01' existing = {
  name: webAppName
}

// Get an existing storage account
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
  name: storageAccountName
}

// Operation: Enable system-assigned identity on the source service
// No action needed as this is enabled when creating the webapp

// Operation: Configure the target service's endpoint on the source service's app settings
resource appSettings 'Microsoft.Web/sites/config@2022-09-01' = {
  name: 'appsettings'
  parent: webApp
  properties: {
    AZURE_STORAGEBLOB_RESOURCEENDPOINT: storageAccount.properties.primaryEndpoints.blob
  }
}

// Operation: Configure firewall on the target service to allow the source service's outbound IPs
// No action needed as storage account allows all IPs by default

// Operation: Create role assignment for the source service's identity on the target service
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  scope: storageAccount
  name: guid(resourceGroup().id, storageBlobDataContributorRole)
  properties: {
    roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', storageBlobDataContributorRole)
    principalId: webApp.identity.principalId
  }
}

直接使用範本邏輯建置連線時,請務必瞭解 Service 連線 or 對每種驗證類型所做的作業,因為範本邏輯相當於服務 連線 或後端作業。 下表顯示您需要針對每種驗證類型轉譯為範本邏輯的作業詳細數據。

驗證類型 服務 連線 or 作業
秘密 / 連線 ion 字串 - 在來源服務的應用程式設定上設定目標服務的 連接字串
- 在目標服務上設定防火牆以允許來源服務的輸出IP
系統指派的受控識別 - 在來源服務的應用程式設定上設定目標服務的端點
- 在目標服務上設定防火牆以允許來源服務的輸出IP
- 在來源服務上啟用系統指派的身分識別
- 在目標服務上建立來源服務身分識別的角色指派
使用者指派的受控識別 - 在來源服務的應用程式設定上設定目標服務的端點
- 在目標服務上設定防火牆以允許來源服務的輸出IP
- 將使用者指派的身分識別系結至來源服務
- 在目標服務上建立使用者指派身分識別的角色指派
服務主體 - 在來源服務的應用程式設定上設定目標服務的端點
- 在來源服務的應用程式設定上設定服務主體的 appId 和秘密
- 在目標服務上設定防火牆以允許來源服務的輸出IP
- 在目標服務上建立服務主體的角色指派