Najlepsze rozwiązania dotyczące szablonów usługi ARM

W tym artykule pokazano, jak używać zalecanych rozwiązań podczas konstruowania szablonu Azure Resource Manager (szablonu usługi ARM). Te zalecenia pomagają uniknąć typowych problemów podczas wdrażania rozwiązania przy użyciu szablonu usługi ARM.

Limity szablonów

Ogranicz rozmiar szablonu do 4 MB. Limit 4 MB ma zastosowanie do końcowego stanu szablonu po jego rozwinięciu za pomocą iteracyjnych definicji zasobów oraz wartości zmiennych i parametrów. Plik parametrów jest również ograniczony do 4 MB. Jeśli całkowity rozmiar żądania jest zbyt duży, może wystąpić błąd pliku szablonu lub parametru o rozmiarze mniejszym niż 4 MB. Aby uzyskać więcej informacji na temat upraszczania szablonu w celu uniknięcia dużego żądania, zobacz Rozwiązywanie błędów związanych z przekroczeniem rozmiaru zadania.

Dostępne są również:

  • 256 parametrów
  • 256 zmiennych
  • 800 zasobów (w tym liczba kopii)
  • 64 wartości danych wyjściowych
  • 24 576 znaków w wyrażeniu szablonu

Limity szablonów można przekroczyć przy użyciu zagnieżdżonych szablonów. Aby uzyskać więcej informacji, zobacz Using linked and nested templates when deploying Azure resources (Używanie szablonów połączonych i zagnieżdżonych podczas wdrażania zasobów platformy Azure). Aby zmniejszyć liczbę parametrów, zmiennych lub danych wyjściowych, można połączyć kilka wartości w obiekt. Aby uzyskać więcej informacji, zobacz Obiekty jako parametry.

Grupa zasobów

Podczas wdrażania zasobów w grupie zasobów grupa zasobów przechowuje metadane dotyczące zasobów. Metadane są przechowywane w lokalizacji grupy zasobów.

Jeśli region grupy zasobów jest tymczasowo niedostępny, nie można zaktualizować zasobów w grupie zasobów, ponieważ metadane są niedostępne. Zasoby w innych regionach nadal będą działać zgodnie z oczekiwaniami, ale nie można ich aktualizować. Aby zminimalizować ryzyko, znajdź grupę zasobów i zasoby w tym samym regionie.

Parametry

Informacje w tej sekcji mogą być przydatne podczas pracy z parametrami.

Ogólne zalecenia dotyczące parametrów

  • Zminimalizuj użycie parametrów. Zamiast tego użyj zmiennych lub wartości literałów dla właściwości, których nie trzeba określać podczas wdrażania.

  • Użyj camel case dla nazw parametrów.

  • Użyj parametrów dla ustawień, które różnią się w zależności od środowiska, takich jak jednostka SKU, rozmiar lub pojemność.

  • Użyj parametrów dla nazw zasobów, które chcesz określić w celu łatwej identyfikacji.

  • Podaj opis każdego parametru w metadanych.

    "parameters": {
      "storageAccountType": {
        "type": "string",
        "metadata": {
          "description": "The type of the new storage account created to store the VM disks."
        }
      }
    }
    
  • Zdefiniuj wartości domyślne dla parametrów, które nie są poufne. Określając wartość domyślną, łatwiej jest wdrożyć szablon, a użytkownicy szablonu zobaczą przykład odpowiedniej wartości. Każda wartość domyślna parametru musi być prawidłowa dla wszystkich użytkowników w domyślnej konfiguracji wdrożenia.

    "parameters": {
      "storageAccountType": {
        "type": "string",
        "defaultValue": "Standard_GRS",
        "metadata": {
          "description": "The type of the new storage account created to store the VM disks."
        }
      }
    }
    
  • Aby określić opcjonalny parametr, nie używaj pustego ciągu jako wartości domyślnej. Zamiast tego należy użyć wartości literału lub wyrażenia języka, aby skonstruować wartość.

    "storageAccountName": {
       "type": "string",
       "defaultValue": "[concat('storage', uniqueString(resourceGroup().id))]",
       "metadata": {
         "description": "Name of the storage account"
       }
    }
    
  • Używaj allowedValues oszczędnie. Użyj go tylko wtedy, gdy musisz upewnić się, że niektóre wartości nie są uwzględnione w dozwolonych opcjach. Jeśli używasz zbyt allowedValues szerokiej listy, możesz zablokować prawidłowe wdrożenia, nie zachowując aktualnej listy.

  • Gdy nazwa parametru w szablonie pasuje do parametru w poleceniu wdrażania programu PowerShell, program Resource Manager rozwiąże ten konflikt nazewnictwa, dodając przyrostek FromTemplate do parametru szablonu. Jeśli na przykład do szablonu dołączysz parametr o nazwie ResourceGroupName, powoduje to konflikt z parametrem ResourceGroupName w ramach polecenia cmdlet New-AzResourceGroupDeployment. Podczas wdrażania zostanie wyświetlony monit o podanie wartości parametru ResourceGroupNameFromTemplate.

Zalecenia dotyczące zabezpieczeń parametrów

  • Zawsze używaj parametrów dla nazw użytkowników i haseł (lub wpisów tajnych).

  • Użyj securestring dla wszystkich haseł i wpisów tajnych. Jeśli przekażemy poufne dane w obiekcie JSON, użyj secureObject typu . Parametrów szablonu z zabezpieczonych ciągów lub bezpiecznych typów obiektów nie można odczytać po wdrożeniu zasobów.

    "parameters": {
      "secretValue": {
        "type": "securestring",
        "metadata": {
          "description": "The value of the secret to store in the vault."
        }
      }
    }
    
  • Nie po podaj wartości domyślnych dla nazw użytkowników, haseł ani żadnej wartości, która wymaga secureString typu.

  • Nie pozysuj wartości domyślnych dla właściwości, które zwiększają obszar obszaru ataków aplikacji.

Zalecenia dotyczące lokalizacji dla parametrów

  • Użyj parametru , aby określić lokalizację zasobów, i ustaw wartość domyślną na resourceGroup().location . Podanie parametru lokalizacji umożliwia użytkownikom szablonu określenie lokalizacji, w której mają uprawnienia do wdrażania zasobów.

    "parameters": {
       "location": {
         "type": "string",
         "defaultValue": "[resourceGroup().location]",
         "metadata": {
           "description": "The location in which the resources should be deployed."
         }
       }
    }
    
  • Nie określaj allowedValues parametru lokalizacji. Określone lokalizacje mogą nie być dostępne we wszystkich chmurach.

  • Użyj wartości parametru lokalizacji dla zasobów, które prawdopodobnie będą w tej samej lokalizacji. Takie podejście minimalizuje liczbę monitów użytkowników o podanie informacji o lokalizacji.

  • W przypadku zasobów, które nie są dostępne we wszystkich lokalizacjach, użyj oddzielnego parametru lub określ wartość lokalizacji literału.

Zmienne

Podczas pracy ze zmiennymi mogą być przydatne następujące informacje:

  • Użyj camel case dla nazw zmiennych.

  • Użyj zmiennych dla wartości, których należy użyć więcej niż raz w szablonie. Jeśli wartość jest używana tylko raz, zakodowana wartość ułatwia odczytywanie szablonu.

  • Użyj zmiennych dla wartości, które tworzysz na podstawie złożonego rozmieszczenia funkcji szablonu. Szablon jest łatwiejszy do odczytania, gdy wyrażenie złożone pojawia się tylko w zmiennych.

  • Nie można użyć funkcji odwołania w variables sekcji szablonu. Funkcja reference wyprowadza swoją wartość ze stanu środowiska uruchomieniowego zasobu. Jednak zmienne są rozpoznawane podczas wstępnej analizy szablonu. Konstruuj reference wartości, które wymagają funkcji bezpośrednio w sekcji lub resources outputs szablonu.

  • Dołącz zmienne dla nazw zasobów, które muszą być unikatowe.

  • Używanie pętli kopiowania w zmiennych w celu utworzenia powtarzanego wzorca obiektów JSON.

  • Usuń nieużywane zmienne.

Wersja interfejsu API

Ustaw właściwość na zakodowaną wersję interfejsu apiVersion API dla typu zasobu. Podczas tworzenia nowego szablonu zalecamy użycie najnowszej wersji interfejsu API dla typu zasobu. Aby określić dostępne wartości, zobacz informacje o szablonie.

Jeśli szablon działa zgodnie z oczekiwaniami, zalecamy kontynuowanie korzystania z tej samej wersji interfejsu API. Korzystając z tej samej wersji interfejsu API, nie musisz martwić się o istotne zmiany, które mogą zostać wprowadzone w nowszych wersjach.

Nie używaj parametru dla wersji interfejsu API. Właściwości i wartości zasobów mogą się różnić w zależności od wersji interfejsu API. Funkcja IntelliSense w edytorze kodu nie może określić prawidłowego schematu, gdy wersja interfejsu API jest ustawiona na parametr. Jeśli przekażemy wersję interfejsu API, która nie pasuje do właściwości w szablonie, wdrożenie nie powiedzie się.

Nie używaj zmiennych dla wersji interfejsu API.

Zależności zasobów

Podczas podejmowania decyzji o tym, jakie zależności należy ustawić, należy stosować się do następujących wytycznych:

  • Użyj funkcji i przekaż nazwę zasobu, aby ustawić niejawną zależność między zasobami, które reference muszą współużytkować właściwość. Nie dodawaj jawnego elementu, jeśli już zdefiniowano dependsOn niejawną zależność. Takie podejście zmniejsza ryzyko wystąpienia niepotrzebnych zależności. Aby uzyskać przykład ustawiania niejawnej zależności, zobacz funkcje odwołania i listy.

  • Ustaw zasób podrzędny jako zależny od jego zasobu nadrzędnego.

  • Zasoby z elementem warunku ustawionym na wartość false są automatycznie usuwane z kolejności zależności. Ustaw zależności tak, jakby zasób był zawsze wdrażany.

  • Pozwól zależnościom na tworzenie kaskad bez ich jawnego ustawiania. Na przykład maszyna wirtualna zależy od wirtualnego interfejsu sieciowego, a interfejs sieci wirtualnej zależy od sieci wirtualnej i publicznych adresów IP. W związku z tym maszyna wirtualna jest wdrażana po wszystkich trzech zasobach, ale nie należy jawnie ustawiać maszyny wirtualnej jako zależnej od wszystkich trzech zasobów. Takie podejście wyjaśnia kolejność zależności i ułatwia później zmianę szablonu.

  • Jeśli wartość można określić przed wdrożeniem, spróbuj wdrożyć zasób bez zależności. Jeśli na przykład wartość konfiguracji wymaga nazwy innego zasobu, może nie być potrzebna zależność. Te wskazówki nie zawsze działają, ponieważ niektóre zasoby weryfikują istnienie innego zasobu. Jeśli wystąpi błąd, dodaj zależność.

Zasoby

Podczas pracy z zasobami mogą być przydatne następujące informacje:

  • Aby ułatwić innym współautorom zrozumienie przeznaczenia zasobu, określ dla comments każdego zasobu w szablonie.

    "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.",
          ...
      }
    ]
    
  • Jeśli używasz publicznego punktu końcowego w szablonie (na przykład publicznego punktu końcowego usługi Azure Blob Storage), nie koduj przestrzeni nazw. Użyj funkcji reference , aby dynamicznie pobrać przestrzeń nazw. Tej metody można użyć do wdrożenia szablonu w różnych środowiskach publicznych przestrzeni nazw bez konieczności ręcznego zmieniania punktu końcowego w szablonie. Ustaw wersję interfejsu API na tę samą wersję, która jest używana dla konta magazynu w szablonie.

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

    Jeśli konto magazynu jest wdrażane w tym samym szablonie, który tworzysz, a nazwa konta magazynu nie jest współużytkowana z innym zasobem w szablonie, nie musisz określać przestrzeni nazw dostawcy ani elementu , gdy odwołujesz się do apiVersion zasobu. W poniższym przykładzie pokazano uproszczoną składnię.

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

    Można również odwoływać się do istniejącego konta magazynu, które znajduje się w innej grupie zasobów.

    "diagnosticsProfile": {
      "bootDiagnostics": {
        "enabled": "true",
        "storageUri": "[reference(resourceId(parameters('existingResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('existingStorageAccountName')), '2019-06-01').primaryEndpoints.blob]"
      }
    }
    
  • Przypisz publiczne adresy IP do maszyny wirtualnej tylko wtedy, gdy jest to wymagane przez aplikację. Aby nawiązać połączenie z maszyną wirtualną na potrzeby debugowania lub do celów administracyjnych lub zarządzania, należy użyć reguł NAT dla ruchu przychodzącego, bramy sieci wirtualnej lub serwera przeskoku.

    Aby uzyskać więcej informacji na temat nawiązywania połączenia z maszynami wirtualnymi, zobacz:

  • Właściwość domainNameLabel publicznych adresów IP musi być unikatowa. Wartość domainNameLabel musi mieć od 3 do 63 znaków i być zgodne z regułami określonymi przez to wyrażenie regularne: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$ . Ponieważ funkcja generuje ciąg o długości uniqueString 13 znaków, dnsPrefixString parametr jest ograniczony do 50 znaków.

    "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))]"
    }
    
  • Po dodaniu hasła do niestandardowego rozszerzenia skryptu użyj commandToExecute właściwości we właściwości 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'))]"
      }
    }
    

    Uwaga

    Aby upewnić się, że wpisy tajne są szyfrowane, gdy są przekazywane jako parametry do maszyn wirtualnych i rozszerzeń, użyj właściwości protectedSettings odpowiednich rozszerzeń.

  • Określ jawne wartości właściwości, które mają wartości domyślne, które mogą zmieniać się w czasie. Jeśli na przykład wdrażasz klaster usługi AKS, możesz określić lub pominąć kubernetesVersion właściwość . Jeśli go nie określisz, klaster zostanie domyślnie określony jako wersja pomocnicza N-1 i najnowsza poprawka. W przypadku wdrażania klastra przy użyciu szablonu usługi ARM to domyślne zachowanie może nie być takie, jakiego oczekujesz. Ponowne wdanie szablonu może spowodować nieoczekiwane uaktualnienie klastra do nowej wersji usługi Kubernetes. Zamiast tego rozważ określenie jawnego numeru wersji, a następnie ręczne jego zmianę, gdy wszystko będzie gotowe do uaktualnienia klastra.

Korzystanie z zestawu narzędzi testowych

Zestaw narzędzi testowych szablonu usługi ARM to skrypt, który sprawdza, czy szablon używa zalecanych rozwiązań. Jeśli szablon nie jest zgodny z zalecanymi rozwiązaniami, zwraca listę ostrzeżeń z sugerowanymi zmianami. Zestaw narzędzi testowych może pomóc ci dowiedzieć się, jak zaimplementować najlepsze rozwiązania w szablonie.

Po zakończeniu pracy z szablonem uruchom zestaw narzędzi testowych, aby sprawdzić, czy istnieją sposoby na ulepszenie jego implementacji. Aby uzyskać więcej informacji, zobacz Use ARM template test toolkit (Korzystanie z zestawu narzędzi do testowania szablonu usługi ARM).

Następne kroki

  • Aby uzyskać informacje o strukturze pliku szablonu, zobacz Understand the structure and syntax of ARM templates (Opis struktury i składni szablonów usługi ARM).
  • Aby uzyskać zalecenia dotyczące sposobu tworzenia szablonów, które działają we wszystkich środowiskach chmury platformy Azure, zobacz Develop ARM templates for cloud consistency (Tworzenie szablonów usługi ARM dla spójności w chmurze).