أفضل ممارسات نموذج ARM

توضح لك هذه المقالة كيفية استخدام الممارسات الموصى بها عند إنشاء قالب Azure Resource Manager (قالب ARM). تساعدك هذه التوصيات في تجنب المشكلات الشائعة عند استخدام قالب ARM لتوزيع حل.

حدود النموذج

حدد حجم القالب الخاص بك إلى 4 ميغابايت، وكل تعريف مورد إلى 1 ميغابايت. تنطبق الحدود على الحالة النهائية للقالب بعد توسيعه باستخدام تعريفات الموارد التكرارية وقيم المتغيرات والمعلمات. ملف المعلمة يقتصر أيضاً على 4 ميغابايت. قد يظهر لك خطأ في قالب أو ملف معلمة أقل من 4 ميغابايت، إذا كان الحجم الإجمالي للطلب كبيرًا جدًا. لمزيد من المعلومات حول كيفية تبسيط النموذج الخاص بك لتجنب الطلبات الكبيرة، راجع حل أخطاء حجم المهمة التي تم تجاوزها.

أنت مقيد أيضاً بـ:

  • 256 معلمة
  • 256 متغيراً
  • 800 من الموارد (بما في ذلك عدد النسخ)
  • 64 قيم الإخراج
  • 10 مواقع فريدة لكل نطاق مجموعة اشتراك/مستأجر/إدارة
  • 24576 حرفاً في تعبير قالب

يمكنك تجاوز بعض حدود القالب باستخدام قالب متداخل. لمزيد من المعلومات، راجع استخدام القوالب المرتبطة والمتداخلة عند توزيع موارد 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 في القالب الخاص بك، فإنها تتعارض مع معلمة ResourceGroupName في cmdlet New-AzResourceGroupDeployment. أثناء التوزيع، يُطلب منك تقديم قيمة لـ 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 لمعلمة الموقع. قد لا تكون المواقع التي تحددها متاحة في كل السحب.

  • استخدم قيمة معلمة الموقع للموارد التي من المحتمل أن تكون في نفس الموقع. يقلل هذا الأسلوب من عدد المرات التي يُطلب فيها من المستخدمين توفير معلومات الموقع.

  • بالنسبة إلى الموارد غير المتاحة في جميع المواقع، استخدم معلمة منفصلة أو حدد قيمة الموقع الحرفية.

المتغيرات

يمكن أن تكون المعلومات التالية مفيدة عند التعامل مع المتغيرات:

  • استخدم حالة الجمل لأسماء المتغيرات.

  • استخدم المتغيرات للقيم التي تحتاج إلى استخدامها أكثر من مرة في قالب. إذا تم استخدام قيمة مرة واحدة فقط، فإن القيمة المشفرة تسهّل قراءة القالب الخاص بك.

  • استخدم المتغيرات للقيم التي تنشئها من ترتيب معقد لوظائف القالب. يسهل قراءة القالب الخاص بك عندما يظهر التعبير المعقد في المتغيرات فقط.

  • لا يمكنك استخدام الوظيفة المرجع في قسم variables من النموذج. تستمد الدالة reference قيمتها من حالة وقت تشغيل المورد. ومع ذلك، يتم حل المتغيرات أثناء التحليل الأولي للقالب. أنشئ القيم التي تحتاج إلى وظيفة reference مباشرةً في قسم resources أو outputs من النموذج.

  • قم بتضمين متغيرات لأسماء الموارد التي يجب أن تكون فريدة.

  • استخدم حلقة نسخ في المتغيرات لإنشاء نمط متكرر لعناصر JSON.

  • إزالة المتغيرات غير المستخدمة.

إصدار واجهة برمجة التطبيقات

قم بتعيين الخاصية apiVersion إلى إصدار API مشفر بشكل ثابت لنوع المورد. عند إنشاء نموذج جديد، نوصيك باستخدام أحدث إصدار من واجهة برمجة التطبيقات لنوع المورد. لتحديد القيم المتاحة، راجع مرجع القالب.

عندما يعمل النموذج كما هو متوقع، نوصيك بالاستمرار في استخدام إصدار API نفسه. باستخدام نفس إصدار API، لا داعي للقلق بشأن كسر التغييرات التي قد يتم تقديمها في الإصدارات الأحدث.

لا تستخدم معلمة لإصدار API. يمكن أن تختلف خصائص وقيم الموارد حسب إصدار API. لا يمكن لـ IntelliSense في محرر التعليمات البرمجية تحديد المخطط الصحيح عند تعيين إصدار API على معلمة. إذا قمت بتمرير إصدار 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.",
          ...
      }
    ]
    

    إذا خُزن قالب ARM في ملف .jsonc، تُدعم التعليقات التي تستخدم بناء الجملة //، كما هو موضح هنا.

    "resources": [
      {
        // This storage account is used to store the VM disks.
        "name": "[variables('storageAccountName')]",
        "type": "Microsoft.Storage/storageAccounts",
        "apiVersion": "2019-06-01",
        "location": "[resourceGroup().location]",
          ...
      }
    ]
    

    لمزيد من المعلومات حول التعليقات وبيانات التعريف، راجع فهم بناء جملة قوالب ARM وبنيتها.

  • إذا كنت تستخدم نقطة نهاية عامة في القالب الخاص بك (مثل نقطة نهاية عامة لتخزين )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 جديد بشكل غير متوقع. بدلاً من ذلك، ضع في اعتبارك تحديد رقم إصدار صريح ثم تغييره يدوياً عندما تكون جاهزاً لترقية نظامك.

التعليقات

بالإضافة إلى الخاصية comments، تُدعم التعليقات التي تستخدم بناء الجملة //. لمزيد من المعلومات حول التعليقات وبيانات التعريف، راجع فهم بناء جملة قوالب ARM وبنيتها. يمكنك اختيار حفظ ملفات JSON التي تحتوي على تعليقات // باستخدام ملحق الملف .jsonc، للإشارة إلى أن ملف JSON يحتوي على تعليقات. تقبل خدمة ARM أيضًا التعليقات في أي ملف JSON بما في ذلك ملفات المعلمات.

أدوات Visual Studio Code ARM

يعد العمل مع قوالب ARM أسهل بكثير مع أدوات Azure Resource Manager (ARM) لـ Visual Studio Code. يوفر هذا الملحق دعم اللغة ومقتطفات الموارد والإكمال التلقائي للمورد لمساعدتك في إنشاء قوالب Azure Resource Manager والتحقق من صحتها. لمعرفة المزيد وتثبيت الملحق، راجع أدوات Azure Resource Manager (ARM).

استخدم مجموعة أدوات الاختبار

مجموعة أدوات اختبار قالب ARM عبارة عن برنامج نصي يتحقق مما إذا كان النموذج الخاص بك يستخدم الممارسات الموصى بها. عندما لا يتوافق النموذج الخاص بك مع الممارسات الموصى بها، فإنه يقوم بإرجاع قائمة من التحذيرات مع التغييرات المقترحة. يمكن أن تساعدك مجموعة أدوات الاختبار في تعلم كيفية تنفيذ أفضل الممارسات في القالب الخاص بك.

بعد الانتهاء من القالب الخاص بك، قم بتشغيل مجموعة أدوات الاختبار لمعرفة ما إذا كانت هناك طرق يمكنك من خلالها تحسين تنفيذها. لمزيد من المعلومات، راجع استخدام مجموعة أدوات اختبار نموذج ARM.

الخطوات التالية