مشاركة عبر


وحدات العضلة ذات الرأسين

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

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

Tip

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

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

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

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

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

@<decorator>(<argument>)
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. لمزيد من المعلومات، راجع المسار إلى وحدة نمطية.

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

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

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

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

عدم توفير أي اسم وحدة نمطية صحيح أيضا. سيتم إنشاء GUID كاسم الوحدة النمطية.

module stgModule 'storageAccount.bicep' = {
  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 إلى تعريف الوحدة النمطية. لمعرفة المزيد حول التبعيات، راجع تبعيات الموارد في Bicep.

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'
  }
}

ملف في السجل

هناك سجلات وحدة عامة وخاصة.

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

Note

يتم إيقاف الوحدات النمطية غير المصدقة من Azure من سجل الوحدة النمطية العامة.

الوحدات النمطية التي تم التحقق منها من Azure هي وحدات نمطية مسبقة الإنشاء ومقدمة الاختبار ومتحقق منها مسبقا يمكنك استخدامها لنشر الموارد على Azure. قام موظفو Microsoft بإنشاء هذه الوحدات النمطية وامتلاكها. تم تصميمها لتبسيط وتسريع عملية النشر لموارد وتكوينات Azure الشائعة. تتوافق الوحدات النمطية أيضا مع أفضل الممارسات مثل Azure Well-Architected Framework.

استعرض وحدات Bicep النمطية لمشاهدة قائمة الوحدات النمطية المتوفرة. حدد الأرقام المميزة في لقطة الشاشة التالية للانتقال مباشرة إلى طريقة العرض التي تمت تصفيتها:

لقطة شاشة تعرض الوحدات النمطية التي تم التحقق منها من Azure.

تعرض قائمة الوحدة النمطية أحدث إصدار. حدد رقم الإصدار للاطلاع على قائمة بالإصدارات المتوفرة.

لقطة شاشة تعرض إصدارات الوحدات النمطية التي تم التحقق منها من Azure.

للارتباط بوحدة نمطية عامة، حدد مسار الوحدة النمطية باستخدام بناء الجملة التالي:

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

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

module storage 'br/public:avm/res/storage/storage-account:0.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

Note

الاسم المستعار للوحدات النمطية العامة هو 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 Container Registry. يمكن أن يحتوي مسار الملف على مقاطع مفصولة / بالحرف .
  • tag: يستخدم لتحديد إصدار للوحدة النمطية.

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

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

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

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

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

يحتوي سجل الوحدة النمطية العامة على اسم مستعار معرف مسبقا:

module storage 'br/public:avm/res/storage/storage-account:0.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

يمكنك تجاوز الاسم المستعار العام في ملف 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'
  }
}

استخدم الديكور

تتم كتابة المحسنات بالتنسيق @expression ويتم وضعها فوق إعلانات الوحدة النمطية. يعرض الجدول التالي المحسنات المتوفرة للوحدات النمطية:

Decorator Argument Description
batchSize none إعداد مثيلات للنشر بشكل تسلسلي.
description string توفير أوصاف للوحدة النمطية.

يوجد مصممي الديكور في sys namespace. إذا كنت بحاجة إلى تمييز مصمم ديكور عن عنصر آخر يحمل نفس الاسم، فاكتب في مقدمة مصمم الديكور sys. على سبيل المثال، إذا كان ملف Bicep يتضمن معلمة باسم description، فيجب إضافة sys مساحة الاسم عند استخدام description مصمم الديكور.

BatchSize

يمكنك تطبيق @batchSize() فقط على مورد أو تعريف وحدة نمطية يستخدم تعبيراfor.

بشكل افتراضي، يتم نشر الوحدات النمطية بالتوازي. عند إضافة مصمم @batchSize(int)، يمكنك توزيع المثيلات بشكل تسلسلي.

@batchSize(3)
module storage 'br/public:avm/res/storage/storage-account:0.11.1' = [for storageName in storageAccounts: {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}]

لمزيد من المعلومات، راجع التوزيع على دفعات.

Description

لإضافة شرح، أضف وصفا لإعلانات الوحدة النمطية. على سبيل المثال:

@description('Create storage accounts referencing an AVM.')
module storage 'br/public:avm/res/storage/storage-account:0.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

يمكنك استخدام نص بتنسيق Markdown لنص الوصف.

Parameters

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

يحتوي مثال Bicep التالي على ثلاث معلمات: storagePrefixو storageSKUو.location 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@2025-06-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@2025-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 لإعداد نطاق الوحدة النمطية. عند عدم توفير الخاصية 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@2025-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@2025-04-01' existing = {
  name: 'demogroup1'
}

resource secondRG 'Microsoft.Resources/resourceGroups@2025-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'
  }
}

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

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

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

param managementGroupName string

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

Output

يمكنك الحصول على القيم من وحدة نمطية واستخدامها في ملف 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@2025-06-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@2025-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 0.35.1 والإصدارات الأحدث، @secure() يمكن تطبيق مصمم الديكور على مخرجات الوحدة النمطية لوضع علامة عليها على أنها حساسة، ما يضمن عدم عرض قيمها في السجلات أو محفوظات التوزيع. يكون هذا مفيدا عندما تحتاج الوحدة النمطية إلى إرجاع بيانات حساسة، مثل مفتاح تم إنشاؤه أو سلسلة اتصال، إلى ملف Bicep الأصل دون المخاطرة بالتعرض. لمزيد من المعلومات، راجع المخرجات الآمنة.

هوية الوحدة

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

param identityId string

module mod './module.bicep' = {
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${identityId}': {}
    }
  }
  name: 'mod'
  params: {
    keyVaultUri: 'keyVaultUri'
    identityId: identityId
  }
}
  • لتمرير قيمة حساسة إلى وحدة نمطية، استخدم الدالة getSecret .