ARM 範本最佳做法

本文將說明在建立 AZURE Resource Manager 範本時,如何使用建議的做法 (ARM 範本) 。 這些建議可協助避免使用 ARM 範本部署解決方案的常見問題。

範本限制

將範本大小限制為 4 MB。 4 MB 限制適用于範本在以反覆運算資源定義展開後的最終狀態,以及變數和參數的值。 參數檔案也限制為 4 MB。 如果要求的總大小太大,您可能會收到小於 4 MB 的範本或參數檔案錯誤。 若要進一步瞭解如何簡化範本以避免大型要求,請參閱解決超過工作 大小的錯誤

您也受限於:

  • 256 個參數
  • 256 個變數
  • 800 個資源 (包括複製計數)
  • 64 個輸出值
  • 範本運算式中的 24,576 個字元

您可以使用巢式範本超過某些範本限制。 詳細資訊,請參閱在部署 Azure 資源時使用連結 範本和巢式範本。 若要減少參數、變數或輸出的數量,您可以將多個值合併成物件。 詳細資訊,請參閱物件 做為參數

資源群組

當您將資源部署到資源群組時,資源群組會儲存資源的中繼資料。 中繼資料會儲存在資源群組的位置。

如果資源群組的區域暫時無法使用,由於中繼資料無法使用,因此無法更新資源群組中的資源。 其他地區的資源仍然會如預期運作,但無法更新。 若要將風險降到最低,請在同一地區找出您的資源群組和資源。

參數

當您使用參數時,本節的資訊 會很有説明

參數的一般建議

  • 最小化參數的使用。 請改為針對部署期間不需要指定的屬性使用變數或文字值。

  • 在參數名稱中使用山毛大小寫。

  • 針對視環境而不同的設定使用參數,例如 SKU、大小或容量。

  • 使用您想要指定之資源名稱的參數,以輕鬆識別。

  • 提供中繼資料中每個參數的描述。

    "parameters": {
      "storageAccountType": {
        "type": "string",
        "metadata": {
          "description": "The type of the new storage account created to store the VM disks."
        }
      }
    }
    
  • 定義不敏感的參數預設值。 指定預設值可以更輕鬆地部署範本,而範本的使用者會看到適當值的範例。 參數的任何預設值都必須對預設部署設定中的所有使用者有效。

    "parameters": {
      "storageAccountType": {
        "type": "string",
        "defaultValue": "Standard_GRS",
        "metadata": {
          "description": "The type of the new storage account created to store the VM disks."
        }
      }
    }
    
  • 若要指定選擇性參數,請勿使用空白字串做為預設值。 請改為使用文字值或語言運算式來建構值。

    "storageAccountName": {
       "type": "string",
       "defaultValue": "[concat('storage', uniqueString(resourceGroup().id))]",
       "metadata": {
         "description": "Name of the storage account"
       }
    }
    
  • allowedValues 謹慎使用。 只有在您必須確認某些值未包含在允許的選項時,才能使用它。 如果您使用過於廣泛,可能會封鎖有效的部署,而不要將清單保持為 allowedValues 最新狀態。

  • 當範本中的參數名稱符合 PowerShell 部署命令中的參數時,Resource Manager 會新增 Postfix FromTemplate 至範本參數,以解決此命名衝突。 例如,如果您在範本中包含名為ResourceGroupName的參數,它會與New-AzResourceGroupDeployment Cmdlet 中的ResourceGroupName參數衝突。 部署期間,系統會提示您提供 ResourceGroupNameFromTemplate 的值

參數的安全性建議

  • 一直使用使用者名稱和密碼的參數 (密碼或) 。

  • 用於 securestring 所有密碼和機密。 如果您在 JSON 物件中傳遞敏感性資料,請使用 secureObject 類型。 資源部署之後,無法讀取具有安全字串或安全物件類型的範本參數。

    "parameters": {
      "secretValue": {
        "type": "securestring",
        "metadata": {
          "description": "The value of the secret to store in the vault."
        }
      }
    }
    
  • 請勿提供使用者名稱、密碼或任何需要輸入之值的 secureString 預設值。

  • 請勿為增加應用程式攻擊面區域的屬性提供預設值。

參數的位置建議

  • 使用參數來指定資源的位置,然後將預設值設為 resourceGroup().location 。 提供位置參數可讓範本的使用者指定他們有權部署資源的位置。

    "parameters": {
       "location": {
         "type": "string",
         "defaultValue": "[resourceGroup().location]",
         "metadata": {
           "description": "The location in which the resources should be deployed."
         }
       }
    }
    
  • 不要指定 allowedValues 位置參數。 您指定的位置可能無法在所有雲端使用。

  • 針對可能位於相同位置的資源使用位置參數值。 此方法可最小化使用者要求提供位置資訊的時間。

  • 針對並非所有位置都可用的資源,請使用個別參數或指定文字位置值。

變數

當您使用變數時,下列資訊 會很有説明

  • 針對變數名稱使用山毛大小寫。

  • 針對您需要在範本中多次使用的值使用變數。 如果值只使用一次,硬編碼值會讓範本更容易閱讀。

  • 針對您從複雜的範本函數相片順序所建構的值使用變數。 當複雜的運算式只出現在變數中時,您的範本更容易閱讀。

  • 您無法使用 範本區 的參照函數。 函數 reference 會從資源的執行時間狀態衍生其值。 不過,變數在範本初始剖析期間會解決。 直接在範本的 reference 或 區段中建構 resourcesoutputs 需要函數的值。

  • 為必須是唯一的資源名稱包含變數。

  • 在變數 中使用複製迴圈 來建立重複的 JSON 物件模式。

  • 移除未使用的變數。

API 版本

apiVersion 屬性設定為資源類型的硬編碼 API 版本。 建立新範本時,建議您為資源類型使用最新的 API 版本。 若要判斷可用的值,請參閱 範本參照

當您的範本如預期運作時,建議您繼續使用相同的 API 版本。 使用相同的 API 版本,您不必擔心會中斷在較新版本中引入的變更。

請勿使用 API 版本的參數。 資源屬性和值會因 API 版本而異。 當 API 版本設定為參數時,程式碼編輯器中的 IntelliSense 無法判斷正確的架構。 如果您傳遞的 API 版本與範本中的屬性不相符,部署將會失敗。

請勿使用 API 版本的變數。

資源相依性

決定要設定 哪些相依 性時,請使用下列指導方針:

  • 使用 reference 函數並傳遞資源名稱,以設定需要共用屬性的資源之間的隱含相依性。 當您已經定義隱含相依性時,請勿新增 dependsOn 明確元素。 此方法可以減少不必要的相依性風險。 有關設定隱含相依性範例,請參閱 參照和清單函數

  • 將子資源設定為依存于其父資源。

  • 設定為 false 的條件 元素資源會自動從相依順序中移除。 設定相依性,就像一直部署資源一樣。

  • 讓相依性串聯,而不明確設定。 例如,您的虛擬機器取決於虛擬網路介面,而虛擬網路介面則取決於虛擬網路和公用 IP 位址。 因此,虛擬機器會部署在所有三個資源之後,但不要明確地將虛擬機器設定為依存于這三個資源。 此方法會厘清相依順序,並方便日後變更範本。

  • 如果在部署前可以決定值,請嘗試部署資源而不具有相依性。 例如,如果組組值需要另一個資源的名稱,您可能不需要相依性。 此指引不一定一定能夠使用,因為有些資源會驗證其他資源是否存在。 如果您收到錯誤,請新增相依性。

資源

當您使用資源時,下列資訊會 很有説明

  • 若要協助其他參與者瞭解資源的用途,請為範本 comments 中的每個資源指定。

    "resources": [
      {
        "name": "[variables('storageAccountName')]",
        "type": "Microsoft.Storage/storageAccounts",
        "apiVersion": "2019-06-01",
        "location": "[resourceGroup().location]",
        "comments": "This storage account is used to store the VM disks.",
          ...
      }
    ]
    
  • 如果您在範本中使用公用端點 (例如 Azure Blob 儲存空間公用端點) ,請勿對命名空間進行硬編碼。 使用 reference 函數來動態地取回命名空間。 您可以使用這個方法將範本部署到不同的公用命名空間環境,而不需要手動變更範本中的端點。 將 API 版本設定為您用於範本中儲存帳戶的相同版本。

    "diagnosticsProfile": {
      "bootDiagnostics": {
        "enabled": "true",
        "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').primaryEndpoints.blob]"
      }
    }
    

    如果儲存空間帳戶部署在您建立相同的範本中,而且該儲存空間帳戶的名稱未與範本中的另一個資源分享,則不需要指定提供者命名空間或參照資源時。 apiVersion 下列範例顯示簡化的語法。

    "diagnosticsProfile": {
      "bootDiagnostics": {
        "enabled": "true",
        "storageUri": "[reference(variables('storageAccountName')).primaryEndpoints.blob]"
      }
    }
    

    您也可以參照其他資源群組中現有的儲存空間帳戶。

    "diagnosticsProfile": {
      "bootDiagnostics": {
        "enabled": "true",
        "storageUri": "[reference(resourceId(parameters('existingResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('existingStorageAccountName')), '2019-06-01').primaryEndpoints.blob]"
      }
    }
    
  • 只有在應用程式需要時,才將公用 IP 位址指派給虛擬機器。 若要連接到虛擬機器 (或) 管理目的,請使用內入 NAT 規則、虛擬網路閘道或跳箱。

    若要進一步連接到虛擬機器,請參閱:

  • 公用 domainNameLabel IP 位址的屬性必須是唯一的。 值 domainNameLabel 必須介於 3 到 63 個字元之間,並遵循此正則運算式指定的規則: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$ . 由於 uniqueString 函數會產生長度為 13 個字元的字串,因此 dnsPrefixString 參數限制為 50 個字元。

    "parameters": {
      "dnsPrefixString": {
        "type": "string",
        "maxLength": 50,
        "metadata": {
          "description": "The DNS label for the public IP address. It must be lowercase. It should match the following regular expression, or it will raise an error: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$"
        }
      }
    },
    "variables": {
      "dnsPrefix": "[concat(parameters('dnsPrefixString'),uniquestring(resourceGroup().id))]"
    }
    
  • 當您新增密碼至自訂腳本副檔名時,請使用 commandToExecute 屬性中的 protectedSettings 屬性。

    "properties": {
      "publisher": "Microsoft.Azure.Extensions",
      "type": "CustomScript",
      "typeHandlerVersion": "2.0",
      "autoUpgradeMinorVersion": true,
      "settings": {
        "fileUris": [
          "[concat(variables('template').assets, '/lamp-app/install_lamp.sh')]"
        ]
      },
      "protectedSettings": {
        "commandToExecute": "[concat('sh install_lamp.sh ', parameters('mySqlPassword'))]"
      }
    }
    

    注意

    若要確保當機密以參數形式傳遞至虛擬機器和副檔名時,機密會經過加密,請使用相關 protectedSettings 副檔名的屬性。

  • 指定具有預設值的屬性明確值,這些值可能會隨著時間而變更。 例如,如果您要部署 AKS 群集,您可以指定或省略 kubernetesVersion 屬性。 如果您未指定,則組會預設為 N-1 次要版本和最新修補程式。 當您使用 ARM 範本部署群集時,此預設行為可能並非您預期。 重新部署範本可能會導致該組意外升級至新的 Kubernetes 版本。 請改為考慮指定明確的版本號碼,然後在準備好升級您的群集時手動變更。

使用測試控管套件

ARM 範本測試控管套件是一個腳本,可檢查範本是否使用建議的做法。 如果您的範本不符合建議的做法,它會返回包含建議變更的警告清單。 測試控管套件可協助您瞭解如何在範本中實做最佳做法。

完成範本之後,請執行測試控管箱,看看是否有方法可以改進其實現。 詳細資訊,請參閱使用 ARM 範本測試控管套件

下一個步驟

  • 有關範本檔案結構的資訊,請參閱瞭解 ARM 範本的結構 和語法
  • 若要瞭解如何建立在所有 Azure 雲端環境中均能工作的範本的建議,請參閱開發 ARM 範本,確保雲端一致性