وحدات Bicep

يتيح لك Bicep تنظيم عمليات التوزيع إل الوحدات النمطية. إن الوحدة النمطية هي ملف Bicep (أو قالب ARM JSON) يتم توزيعه من ملف Bicep آخر. مع الوحدات النمطية، يمكنك تحسين قابلية قراءة ملفات Bicep لديك عن طريق تغليف تفاصيل معقدة من عملية التوزيع لديك. يمكنك أيضا إعادة استخدام الوحدات النمطية بسهولة في عمليات التوزيع المختلفة.

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

تلميح

يعتبر الاختيار بين مواصفات سجل الوحدة والقالب في الغالب مسألة تفضيل. هناك بعض الأشياء التي يجب مراعاتها عند الاختيار بين الاثنين:

  • يتم دعم سجل الوحدة فقط من قبل Bicep. إذا لم تكن تستخدم Bicep بعد، فاستخدم مواصفات القالب.
  • لا يمكن توزيع المحتوى الموجود في سجل وحدة Bicep إلا من ملف Bicep آخر. يمكن توزيع مواصفات القالب مباشرةً من واجهة برمجة التطبيقات، وAzure PowerShell، وAzure CLI، ومدخل Azure. يمكنك حتى استخدام UiFormDefinition لتخصيص تجربة توزيع المدخل.
  • تتمتع Bicep ببعض الإمكانات المحدودة لتضمين عناصر المشروع الأخرى (بما في ذلك الملفات التي ليست من نوع Bicep وغير ذات قالب ARM. على سبيل المثال، نصوص PowerShell النصية ونصوص CLI وثنائيات أخرى) باستخدام الدالات loadTextContent وloadFileAsBase64. لا يمكن لمواصفات القالب حزم هذه البيانات الاصطناعية.

يتم تحويل وحدات Bicep النمطية إلى قالب Azure Resource Manager واحد مع قوالب متداخلة. لمزيد من المعلومات حول كيفية حل Bicep لملفات التكوين وكيفية دمج Bicep لملف التكوين المعرف من قبل المستخدم مع ملف التكوين الافتراضي، راجع عملية تحليل ملف التكوين وعملية دمج ملفات التكوين.

موارد التدريب

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

بناء جملة التعريف

بناء الجملة الأساسي لتعريف وحدة نمطية هو:

module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

لذا، فإن المثال البسيط في العالم الواقعي سيبدو كما يلي:

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

يمكنك أيضًا استخدام قالب ARM JSON كوحدة نمطية:

module stgModule '../storageAccount.json' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

استخدم الاسم الرمزي للإشارة إلى الوحدة النمطية في جزء آخر من ملف Bicep. على سبيل المثال، يمكنك استخدام الاسم الرمزي للحصول على الإخراج من وحدة نمطية. قد يحتوي الاسم الرمزي على a-z و A-Z و 0-9 و السفلية السفلية (_). لا يمكن أن يبدأ الاسم برقم. لا يمكن أن يكون للوحدة النمطية نفس اسم المعلمة، أو المتغير، أو المورد.

يمكن أن يكون المسار إما ملف محلي وإما ملف في سجل. يمكن أن يكون الملف المحلي إما ملف Bicep أو قالب ARM JSON. لمزيد من المعلومات، راجع ⁧⁩المسار إلى الوحدة النمطية⁧⁩.

خاصية الاسم مطلوبة. إذ يصبح هذا الاسم هو اسم مورد التوزيع المتداخل في القالب الذي تم إنشاؤه.

إذا تم توزيع وحدة ذات اسم ثابت بشكل متزامن إلى نفس النطاق، فهناك احتمال أن يتداخل توزيع واحد مع الإخراج من التوزيع الآخر. على سبيل المثال، إذا كان ملفا Bicep يستخدمان نفس الوحدة النمطية بنفس الاسم الثابت (examplemodule) ويستهدفان نفس مجموعة الموارد، فقد يظهر نشر واحد الإخراج الخطأ. إذا كنت قلقاً بشأن عمليات التوزيع المتزامنة إلى نفس النطاق، فامنح الوحدة اسماً فريداً.

يقوم المثال التالي بتسلسل اسم التوزيع إلى اسم الوحدة. إذا قمت بتوفير اسم فريد للتوزيع، يكون اسم الوحدة فريداً أيضاً.

module stgModule 'storageAccount.bicep' = {
  name: '${deployment().name}-storageDeploy'
  scope: resourceGroup('demoRG')
}

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

// deploy to different scope
module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  scope: <scope-object>
  params: {
    <parameter-names-and-values>
  }
}

للتوزيع الشرطي لوحدة نمطية، أضف تعبير if. يشبه الاستخدام توزيع مورد بشكل مشروط.

// conditional deployment
module <symbolic-name> '<path-to-file>' = if (<condition-to-deploy>) {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

لتوزيع أكثر من مثيل واحد لوحدة نمطية، أضف تعبير for. يمكنك استخدام batchSize مصمم لتحديد ما إذا كانت المثيلات موزعة بشكل تسلسلي أو بالتوازي. للمزيد من المعلومات، راجع تكرار حلقي في Bicep.

// iterative deployment
@batchSize(int) // optional decorator for serial deployment
module <symbolic-name> '<path-to-file>' = [for <item> in <collection>: {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}]

مثل الموارد، يتم توزيع الوحدات النمطية بالتوازي ما لم تعتمد على وحدات نمطية أو موارد أخرى. عادة، لا تحتاج إلى تعيين التبعيات إذ يتم تحديدها ضمنيا. إذا كنت بحاجة إلى تعيين تبعية صريحة، يمكنك إضافة dependsOn إلى تعريف الوحدة النمطية. لمعرفة المزيد حول التبعيات، راجع تبعيات الموارد.

module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
  dependsOn: [
    <symbolic-names-to-deploy-before-this-item>
  ]
}

المسار إلى الوحدة النمطية

يمكن أن يكون ملف الوحدة إما ملفًا محليًا أو ملفًا خارجيًا. يمكن أن يكون الملف الخارجي في مواصفات القالب أو سجل وحدة Bicep. تظهر جميع هذه الخيارات أدناه.

الملف المحلي

إذا كانت الوحدة النمطية ملفاً محلياً، فقدّم مساراً نسبياً إلى هذا الملف. يجب تحديد جميع المسارات في Bicep باستخدام فاصل الدليل المائل للأمام (/) لضمان تناسق التحويل البرمجي عبر الأنظمة الأساسية. حرف (\) المائل للخلف في Windows غير مدعوم. يمكن أن تحتوي المسارات على مسافات.

على سبيل المثال، لتوزيع ملف يصل إلى مستوى واحد في الدليل من ملفك الرئيسي، استخدم:

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

ملف في السجل

سجل الوحدة النمطية العامة

يتم استضافة سجل الوحدة النمطية العامة في سجل حاوية Microsoft (MCR). يتم تخزين تعليمة برمجية المصدر والوحدات النمطية في GitHub. لعرض الوحدات النمطية المتوفرة وإصداراتها، راجع فهرس الوحدة النمطية لسجل Bicep.

The screenshot of public module registry.

حدد الإصدارات لرؤية الإصدارات المتاحة. يمكنك أيضا تحديد التعليمات البرمجية المصدر لمشاهدة التعليمات البرمجية المصدر للوحدة النمطية، وفتح ملفات Readme.

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

للارتباط بوحدة تسجيل عامة، حدد مسار الوحدة بالصيغة التالية:

module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
  • br/public هو الاسم المستعار لسجل الوحدة العامة. تم تعريف هذا الاسم المستعار مسبقاً في التكوين الخاص بك.
  • مسار الملف يمكن أن يحتوي على مقاطع يمكن فصلها بواسطة الحرف /.
  • تُستخدم العلامة لتحديد إصدار للوحدة النمطية.

على سبيل المثال:

module hw 'br/public:samples/hello-world:1.0.2' = {
  name: 'helloWorld'
  params: {
    name: 'John Dole'
  }
}

إشعار

br/public هو الاسم المستعار للسجل العام. يمكن كتابتها أيضاً باسم

module <symbolic-name> 'br:mcr.microsoft.com/bicep/<file-path>:<tag>' = {}

سجل الوحدة الخاصة

إذا أجريت توزيع وحدة نمطية إلى سجل، يمكنك الارتباط بتلك الوحدة النمطية. ضع اسماً لسجل حاوية Azure ومساراً للوحدة النمطية. حدد مسار الوحدة النمطية باستخدام بناء الجملة التالي:

module <symbolic-name> 'br:<registry-name>.azurecr.io/<file-path>:<tag>' = {
  • br هو اسم مخطط السجل Bicep.
  • مسار الملف يُدعى repository في سجل حاوية Azure. يمكن أن يحتوي مسار الملف على مقاطع يفصل بينها حرف /.
  • تُستخدم العلامة لتحديد إصدار للوحدة النمطية.

على سبيل المثال:

module stgModule 'br:exampleregistry.azurecr.io/bicep/modules/storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

عند الرجوع إلى وحدة نمطية في سجل، يقوم ملحق Bicep في تعليمات Visual Studio البرمجية تلقائياً باستدعاء bicep restore لنسخ الوحدة النمطية الخارجية إلى ذاكرة التخزين المؤقت المحلية. يستغرق الأمر بضع لحظات لاستعادة وحدة نمطية خارجية. إذا لم يعمل التحسس الذكي للوحدة النمطية على الفور، فانتظر حتى تكتمل عملية الاستعادة.

يمكن أن يكون المسار الكامل لوحدة نمطية في السجل طويلا. بدلاً من توفير المسار الكامل في كل مرّة تريد فيها استخدام الوحدة النمطية، يمكنك تكوين الأسماء المستعارة في ملف bicepconfig.json. تساعد الأسماء المستعارة في تيسير الرجوع إلى الوحدة النمطية. على سبيل المثال، باستخدام اسم مستعار، يمكنك اختصار المسار إلى:

module stgModule 'br/ContosoModules:storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

تم تحديد الاسم المستعار لسجل الوحدة العامة مسبقاً:

module hw 'br/public:samples/hello-world:1.0.2' = {
  name: 'helloWorld'
  params: {
    name: 'John Dole'
  }
}

يمكنك تجاوز الاسم المستعار العام في ملف bicepconfig.json.

ملف في مواصفات القالب

بعد إنشاء مواصفات قالب، يمكنك الارتباط بمواصفات القالب هذه في إحدى الوحدات. حدد مواصفات القالب بالتنسيق التالي:

module <symbolic-name> 'ts:<sub-id>/<rg-name>/<template-spec-name>:<version>' = {

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

module <symbolic-name> 'ts/<alias>:<template-spec-name>:<version>' = {

تقوم الوحدة التالية بتوزيع مواصفات قالب لإنشاء حساب تخزين. يتم تعريف مجموعة الموارد والاشتراك لمواصفات القالب في الاسم المستعار المسمى ContosoSpecs.

module stgModule 'ts/ContosoSpecs:storageSpec:2.0' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

المعلمات

تتطابق المعلمات التي تضعها في تعريف الوحدة النمطية مع المعلمات الموجودة في ملف Bicep.

يحتوي مثال Bicep التالي على ثلاث معلمات: storagePrefix وstorageSKU والموقع. تحتوي المعلمة storageSKU على قيمة افتراضية وبالتالي لا يلزم عليك وضع قيمة لتلك المعلمة أثناء التوزيع.

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2021-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

لاستخدام المثال السابق كوحدة نمطية، ضع قِيَما لتلك المعلمات.

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

تعيين نطاق الوحدة النمطية

عند تعريف وحدة نمطية، يمكنك تعيين نطاق وحدة نمطية يختلف عن نطاق الملف Bicep المتضمن. استخدم خاصية scope لإعداد نطاق الوحدة النمطية. عند عدم توفير خاصية النطاق، يتم توزيع الوحدة النمطية في نطاق الهدف الأصل.

ينشئ ملف Bicep التالي مجموعة موارد وحساب تخزين في مجموعة الموارد تلك. يتم توزيع الملف إلى اشتراك، ولكن يُحدّد نطاق الوحدة النمطية إلى مجموعة الموارد الجديدة.

// set the target scope for this file
targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

param location string = deployment().location

var resourceGroupName = '${namePrefix}rg'

resource newRG 'Microsoft.Resources/resourceGroups@2021-04-01' = {
  name: resourceGroupName
  location: location
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: newRG
  params: {
    storagePrefix: namePrefix
    location: location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

يوزّع المثال التالي حسابات التخزين إلى مجموعتي موارد مختلفتين. يجب أن تكون مجموعتا الموارد هاتان موجودتين بالفعل.

targetScope = 'subscription'

resource firstRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup1'
}

resource secondRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup2'
}

module storage1 '../create-storage-account/main.bicep' = {
  name: 'westusdeploy'
  scope: firstRG
  params: {
    storagePrefix: 'stg1'
    location: 'westus'
  }
}

module storage2 '../create-storage-account/main.bicep' = {
  name: 'eastusdeploy'
  scope: secondRG
  params: {
    storagePrefix: 'stg2'
    location: 'eastus'
  }
}

تعيين خاصية النطاق إلى كائن نطاق صالح. إذا كان ملف Bicep لديك يوزع مجموعة موارد أو اشتراك أو مجموعة إدارة، يمكنك تعيين نطاق الوحدة النمطية إلى الاسم الرمزي لذلك المورد. أو يمكنك استخدام وظائف النطاق للحصول على نطاق صالح.

هذه الوظائف هي:

يستخدم المثال التالي الدالة وظيفة managementGroup لإعداد النطاق.

param managementGroupName string

module mgDeploy 'main.bicep' = {
  name: 'deployToMG'
  scope: managementGroup(managementGroupName)
}

الإخراج

يمكنك الحصول على القيم من وحدة نمطية واستخدامها في ملف Bicep الرئيسي. للحصول على قيمة إخراج من وحدة نمطية، استخدم خاصية outputs في كائن الوحدة النمطية.

يُنشئ المثال الأول حساب تخزين ويقوم بإرجاع نقاط النهاية الأساسية.

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2021-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

عند استخدامها كوحدة نمطية، يمكنك الحصول على قيمة الإخراج هذه.

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

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