Microsoft Azure من الصفر إلى الاحتراف: 100 مثال بـ CLI وBicep وPython

Microsoft Azure من الصفر إلى الاحتراف: 100 مثال بـ CLI وBicep وPython

Microsoft Azure منصة سحابية لتشغيل مواقع الويب وقواعد البيانات والحاويات وخطوط معالجة البيانات وخدمات الذكاء الاصطناعي دون شراء خوادم. تأخذك هذه المقالة من أول تسجيل دخول إلى إعداد يصلح للإنتاج في 100 مثال. ستتعلم واجهة سطر أوامر Azure، ومجموعات الموارد والوسوم، والبنية التحتية كشيفرة باستخدام Bicep، وإدارة الهوية بالهويات المُدارة وRBAC، والأجهزة الافتراضية وApp Service، والحاويات وKubernetes، والتخزين بتوقيعات SAS وقواعد دورة الحياة، وSQL وCosmos DB، وFunctions بدون خوادم، والشبكات الافتراضية ونقاط النهاية الخاصة، وService Bus وEvent Hubs، والمراقبة بـ Log Analytics وApplication Insights، وKey Vault، والتحكم في التكاليف. ملاحظة صريحة: لم تُشغَّل أوامر السحابة وأمثلة SDK لأنها تحتاج إلى اشتراك في Azure. الأمثلة المعلَّمة بأنها تعمل نُفّذت على هذا الحاسوب، ويظهر ناتجها الحقيقي بعد الشيفرة.

ما الذي تحتاجه

حساب Azure باشتراك (تكفي النسخة التجريبية المجانية لمعظم الأمثلة)، وواجهة سطر أوامر Azure، وPython 3.10 أو أحدث، ومحرر شيفرة مثل Visual Studio Code مع إضافة Bicep. استخدم اشتراكًا تجريبيًا للتعلم، ولا تلصق أسرارًا حقيقية في الأوامر أو الشيفرة. بعض الموارد تُحتسب تكلفتها، لذلك احذف مجموعة الموارد التجريبية عند الانتهاء.

كيفية استخدام المثال

تستخدم أمثلة bash واجهة Azure CLI، وتستخدم أمثلة Bicep واجهة Azure CLI أو VS Code. تعمل أمثلة Python التي لا تحتاج إلى حساب Azure بالأمر python وتُظهر مخرجاتها الحقيقية. الأمثلة التي تستدعي Azure تحتاج إلى اشتراك قبل أن تعمل.

الموضوع 1: البدء مع Azure

تُنظَّم موارد Azure في اشتراكات ومجموعات موارد وموارد. تعلّم تسجيل الدخول، والتحقق من مكان تنفيذ أوامرك، واستخدام أسماء سهلة العثور عليها وحساب تكلفتها.

واجهة سطر الأوامر وتسجيل الدخول

واجهة Azure CLI أداة واحدة لكل خدمات Azure. ثبّتها، ونفّذ az login، وتحقق بالأمر az account show. تعمل الأوامر على الاشتراك الذي تختاره، لذلك أكّد الاشتراك قبل أي إنشاء أو حذف.

المناطق والتسمية

يعيش كل مورد في منطقة، فاختر المنطقة الأقرب إلى المستخدمين وتحقّق من توفر الخدمات التي تحتاجها فيها. أسماء حسابات التخزين صارمة: من 3 إلى 24 حرفًا صغيرًا وأرقامًا، وفريدة على مستوى Azure كله.

أنماط التسمية

نمط مثل rg-app-env-region-01 يحافظ على اتساق الأسماء، فيسهل على الناس العثور على الموارد وفهم تكلفتها. ابنِ الأسماء بدالة صغيرة وأعد استخدامها في كل سكربت.

رسوم توضيحية

كيف تتركّب تطبيقات Azure المعتادة: يصل المستخدمون إلى تطبيق الويب عبر موازن الحمل، ويقرأ التطبيق الأسرار من Key Vault والبيانات من قاعدة البيانات، وتتدفق السجلات والمقاييس إلى Log Analytics
كيف تتركّب تطبيقات Azure المعتادة: يصل المستخدمون إلى تطبيق الويب عبر موازن الحمل، ويقرأ التطبيق الأسرار من Key Vault والبيانات من قاعدة البيانات، وتتدفق السجلات والمقاييس إلى Log Analytics

مثال 1: تثبيت Azure CLI وتسجيل الدخول

جهّز أداة سطر الأوامر وسجّل الدخول إلى حسابك.

winget install -e --id Microsoft.AzureCLI
az --version
az login

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 2: التحقق من الاشتراك النشط

تأكد من الاشتراك الذي ستغيّره أوامرك.

az account show --output table
az account list --query "[].{name:name, id:id, default:isDefault}" --output table

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 3: إنشاء مجموعة موارد

حاوية للموارد المرتبطة في منطقة واحدة.

az group create --name rg-learn-dev --location southeastasia

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 4: عرض مناطق Azure

ابحث عن المناطق التي يمكنك النشر فيها.

az account list-locations --query "[?metadata.regionCategory=='Recommended'].name" --output tsv

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 5: التحقق من اسم حساب التخزين

تتكون الأسماء من 3 إلى 24 حرفًا صغيرًا وأرقامًا.

import re

def valid_storage_name(name):
    return re.fullmatch(r"[a-z0-9]{3,24}", name) is not None

for candidate in ("stlearndev01", "Store-1", "ab", "a" * 25):
    print(repr(candidate), valid_storage_name(candidate))

المخرجات:

'stlearndev01' True
'Store-1' False
'ab' False
'aaaaaaaaaaaaaaaaaaaaaaaaa' False

مثال 6: بناء اسم مورد وفق نمط تسمية

الأسماء المتسقة تُسهّل العثور على الموارد ومتابعة التكاليف.

def resource_name(kind, app, env, region, index=1):
    return f"{kind}-{app}-{env}-{region}-{index:02d}"

print(resource_name("rg", "shop", "dev", "sea"))
print(resource_name("app", "shop", "prod", "sea", 3))

المخرجات:

rg-shop-dev-sea-01
app-shop-prod-sea-03

الموضوع 2: مجموعات الموارد والوسوم ومخرجات CLI

تحتوي مجموعة الموارد على موارد تطبيق واحد أو بيئة واحدة. تسجّل الوسوم المالك والتكلفة، ويستطيع CLI تصفية المخرجات وتنسيقها للبشر أو للسكربتات.

مجموعات الموارد والحذف

ضع الموارد المرتبطة في مجموعة واحدة لتديرها وتحذفها معًا. يؤدي حذف المجموعة إلى إزالة كل ما بداخلها، لذلك استخدم --no-wait فقط عندما تكون متأكدًا، ولا تحذف مجموعة لم تنشئها أنت.

الوسوم للملكية والتكلفة

الوسوم أزواج مفتاح وقيمة مثل owner وcostcenter. أضفها عند إنشاء الموارد وتحقّق من الناقص منها بسكربت. تستطيع تقارير التكلفة تجميع الإنفاق حسب الوسم.

المخرجات والاستعلامات والقيم الافتراضية

استخدم --output table للبشر وjson للسكربتات. يستخدم --query صيغة JMESPath لتصفية الحقول. اضبط المجموعة والمنطقة الافتراضيتين بـ az configure حتى لا تكررهما.

مثال 7: وسم مجموعة الموارد

تسجّل الوسوم المالك ومركز التكلفة والبيئة.

az group update --name rg-learn-dev \
  --tags owner=team-a costcenter=1001 environment=dev

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 8: التحقق من الوسوم المطلوبة

اعثر على الموارد التي تفتقد الوسوم التي يحتاجها الفريق.

REQUIRED = {"owner", "costcenter", "environment"}

def missing_tags(tags):
    return sorted(REQUIRED - set(tags))

print(missing_tags({"owner": "team-a", "environment": "dev"}))
print(missing_tags({"owner": "x", "costcenter": "1", "environment": "prod"}))

المخرجات:

['costcenter']
[]

مثال 9: حذف مجموعة موارد دون انتظار

أزل مجموعة كاملة من الموارد بأمر واحد.

az group delete --name rg-learn-test --yes --no-wait

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 10: اختيار أقرب منطقة حسب زمن الاستجابة

اختر المنطقة الأسرع استجابة للمستخدمين.

latency_ms = {"southeastasia": 42, "japaneast": 71, "eastus": 210, "westeurope": 185}

best = min(latency_ms, key=latency_ms.get)
print("closest region:", best, latency_ms[best], "ms")

المخرجات:

closest region: southeastasia 42 ms

مثال 11: تصفية المخرجات باستعلام JMESPath

اعرض الحقول والصفوف التي تحتاجها فقط.

az vm list \
  --query "[?powerState=='VM running'].{name:name, rg:resourceGroup}" \
  --output table

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 12: اختيار صيغة المخرجات

جدول أو JSON أو YAML بحسب المستخدم أو السكربت.

az group list --output table
az group list --output json
az group list --output yaml

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 13: التكرار على الموارد في سكربت

نفّذ أمرًا واحدًا لكل مجموعة موارد.

for rg in $(az group list --query "[].name" -o tsv); do
  echo "resource group: $rg"
done

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 14: ضبط المجموعة والمنطقة الافتراضيتين

لا تكتب الخيارات نفسها في كل أمر.

az configure --defaults group=rg-learn-dev location=southeastasia
az configure --list-defaults

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

الموضوع 3: السكربتات والأتمتة

ينبغي أن يُكتب العمل المتكرر في سكربت. تحوّل الحلقات وإعادة المحاولة وتحليل JSON الأوامر المنفردة إلى أتمتة موثوقة يستطيع خط المعالجة تشغيلها.

حلقات على الموارد

تنفّذ حلقة الصدفة أمرًا واحدًا لكل مورد في قائمة. اجعل القائمة صغيرة وتحقّق من النتيجة قبل أن تغيّر أي شيء.

تحليل مخرجات JSON

اطلب من CLI مخرجات بصيغة JSON وحلّلها بدلًا من قراءة النص. صنّف الموارد حسب نوعها لتحصل على ملخص سهل القراءة.

إعادة المحاولة والتأخير المتزايد

تحدّ واجهة Azure البرمجية من العملاء المزدحمين. أعد المحاولة بزمن انتظار متزايد، فيتعافى السكربت دون إغراق الخدمة بالطلبات.

مثال 15: تحليل مخرجات JSON من CLI

حوّل قائمة الموارد إلى ملخص.

import json

sample = """[{"name": "vm-web-01", "type": "Microsoft.Compute/virtualMachines", "location": "southeastasia"},
           {"name": "stlearn01", "type": "Microsoft.Storage/storageAccounts", "location": "southeastasia"}]"""

resources = json.loads(sample)
by_type = {}
for r in resources:
    by_type.setdefault(r["type"].split("/")[-1], []).append(r["name"])
for kind, names in sorted(by_type.items()):
    print(kind, names)

المخرجات:

storageAccounts ['stlearn01']
virtualMachines ['vm-web-01']

مثال 16: إعادة المحاولة بتأخير متزايد

انتظر أطول بعد كل طلب مُقيَّد.

import time

def call_with_retry(fn, attempts=4, base_delay=0.05):
    for n in range(attempts):
        try:
            return fn()
        except ConnectionError as e:
            if n == attempts - 1:
                raise
            delay = base_delay * (2 ** n)
            print(f"attempt {n + 1} failed ({e}); retrying in {delay:.2f}s")
            time.sleep(delay)

state = {"calls": 0}
def flaky_list():
    state["calls"] += 1
    if state["calls"] < 3:
        raise ConnectionError("throttled")
    return ["rg-learn-dev"]

print(call_with_retry(flaky_list))

المخرجات:

attempt 1 failed (throttled); retrying in 0.05s
attempt 2 failed (throttled); retrying in 0.10s
['rg-learn-dev']

مثال 17: التحقق من إصدار CLI والملحقات

أبقِ الأداة وملحقاتها محدّثة.

az version
az extension list --output table
az extension add --name containerapp --upgrade

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 18: إنشاء مبدأ خدمة بأمان

هوية تطبيق للأتمتة بأضيق نطاق ممكن.

# Store the output securely: it contains a password. Never commit it to Git.
az ad sp create-for-rbac --name sp-learn-deploy --role Contributor \
  --scopes /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

الموضوع 4: البنية التحتية كشيفرة بـ Bicep

تصف Bicep موارد Azure كشيفرة. يمكن مراجعة القالب وإصداره، ونشره بالطريقة نفسها في كل مرة، وهذا أكثر أمانًا من النقر في البوابة.

الموارد والمعاملات والمخرجات

يحدد تعريف المورد نوعه وإصدار واجهته ويضبط خصائصه. تجعل المعاملات القالب قابلًا لإعادة الاستخدام، ويمنع @secure كلمات المرور من الظهور في السجلات. تعيد المخرجات قيمًا مثل المعرّف إلى المستدعي.

الوحدات والشروط والحلقات

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

النشر بأمان

استخدم az deployment group what-if لمعاينة التغييرات قبل الإنشاء. تتجنب الأسماء المبنية بـ uniqueString التعارض بين البيئات داخل الاشتراك نفسه.

مثال 19: حساب تخزين Bicep بسيط

صِف حساب التخزين كشيفرة.

param location string = resourceGroup().location
param storageName string

resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    minimumTlsVersion: 'TLS1_2'
    allowBlobPublicAccess: false
  }
}

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 20: المعاملات والمخرجات والقيم السرية

أعد استخدام القوالب ولا تضع كلمات المرور في الملف.

@minLength(3)
@maxLength(24)
param storageName string

@allowed([
  'dev'
  'test'
  'prod'
])
param environment string = 'dev'

@secure()
param adminPassword string

output storageId string = storage.id
resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageName
  location: resourceGroup().location
  sku: { name: environment == 'prod' ? 'Standard_GRS' : 'Standard_LRS' }
  kind: 'StorageV2'
}

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 21: نشر وحدة من main.bicep

قسّم القالب الكبير إلى وحدات قابلة لإعادة الاستخدام.

// main.bicep
targetScope = 'resourceGroup'
module network './modules/network.bicep' = {
  name: 'networkDeploy'
  params: {
    prefix: 'shop-dev'
  }
}
output vnetId string = network.outputs.vnetId

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 22: موارد شرطية

أنشئ المورد في بيئة الإنتاج فقط.

param environment string

resource logs 'Microsoft.OperationalInsights/workspaces@2022-10-01' = if (environment == 'prod') {
  name: 'log-shop-prod'
  location: resourceGroup().location
  properties: {
    retentionInDays: 90
  }
}

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 23: التكرار على الحاويات في Bicep

أنشئ عدة حاويات Blob من قائمة واحدة.

param containerNames array = [
  'uploads'
  'exports'
  'backups'
]

resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' existing = {
  name: 'stlearndev01'
}

resource containers 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = [for name in containerNames: {
  name: '${storage.name}/default/${name}'
}]

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 24: أسماء فريدة بـ uniqueString

أنشئ اسمًا لا يتعارض مع أسماء أخرى في الاشتراك.

param prefix string = 'shop'

var uniqueSuffix = uniqueString(resourceGroup().id)
var storageName = toLower('st${prefix}${uniqueSuffix}')

output generatedName string = storageName

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 25: نشر ملف Bicep

أنشئ الموارد أو حدّثها من القالب.

az deployment group create \
  --resource-group rg-learn-dev \
  --template-file main.bicep \
  --parameters storageName=stlearndev01 environment=dev

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 26: معاينة التغييرات بـ what-if

اعرف أولًا ما الذي سيضيفه النشر أو يغيّره أو يحذفه.

az deployment group what-if \
  --resource-group rg-learn-dev \
  --template-file main.bicep \
  --parameters storageName=stlearndev01

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

الموضوع 5: الهوية والتحكم في الوصول

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

الهويات المُدارة

الهوية المُدارة حساب تديره Azure لتطبيقك، فيحصل التطبيق على رموز دون تخزين سر. استخدم الهويات المُسندة للمستخدم عندما تشارك عدة موارد هوية واحدة.

RBAC وأقل الصلاحيات

يربط إسناد الدور هوية بدور ضمن نطاق، مثل حساب تخزين واحد. فضّل الأدوار المدمجة التي تناسب المهمة، ولا تنشئ دورًا مخصصًا إلا عندما لا يناسب أي دور.

مبادئ الخدمة والرموز

مبدأ الخدمة هوية للأتمتة، وكلمة مروره سر، لذلك احفظه في خزنة خط المعالجة. الرمز سلسلة موقّعة لها وقت انتهاء، ويمكن قراءة هذا الوقت من حمولتها.

مثال 27: هوية مُدارة يحددها المستخدم

هوية يستخدمها التطبيق دون تخزين كلمة مرور.

param location string = resourceGroup().location

resource appIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: 'id-shop-dev'
  location: location
}

output principalId string = appIdentity.properties.principalId

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 28: منح صلاحية القراءة عبر RBAC

امنح الهوية الدور اللازم فقط.

PRINCIPAL_ID=$(az identity show --name id-shop-dev --resource-group rg-learn-dev --query principalId -o tsv)
az role assignment create \
  --assignee-object-id "$PRINCIPAL_ID" \
  --assignee-principal-type ServicePrincipal \
  --role "Storage Blob Data Reader" \
  --scope /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev/providers/Microsoft.Storage/storageAccounts/stlearndev01

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 29: تسجيل دخول خط الأنابيب بمبدأ خدمة

تسجّل الأتمتة الدخول بالأسرار الموجودة في خط الأنابيب.

az login --service-principal \
  --username "$AZURE_CLIENT_ID" \
  --password "$AZURE_CLIENT_SECRET" \
  --tenant "$AZURE_TENANT_ID"

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 30: فحص تعيينات الأدوار

راجع من يستطيع فعل ماذا على المورد.

assignments = [
    {"principal": "id-shop-dev", "role": "Storage Blob Data Reader", "scope": "stlearndev01"},
    {"principal": "sp-learn-deploy", "role": "Contributor", "scope": "rg-learn-dev"},
    {"principal": "id-shop-dev", "role": "Key Vault Secrets User", "scope": "kv-shop-dev"},
]

def roles_for(principal):
    return sorted(a["role"] for a in assignments if a["principal"] == principal)

print(roles_for("id-shop-dev"))
print(roles_for("nobody"))

المخرجات:

['Key Vault Secrets User', 'Storage Blob Data Reader']
[]

مثال 31: تسجيل الدخول على VM بهويته المُدارة

تحصل الآلة الافتراضية على رمز دون كلمة مرور.

az login --identity
az account show --query "user.assignedIdentityInfo" -o tsv

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 32: قراءة انتهاء صلاحية رمز JWT

يحمل الرمز وقت انتهاء الصلاحية في حمولته.

import base64
import json

def jwt_payload(token):
    part = token.split(".")[1]
    part += "=" * (-len(part) % 4)
    return json.loads(base64.urlsafe_b64decode(part))

payload = {"aud": "https://management.azure.com/", "exp": 1767225600, "upn": "[email protected]"}
raw = base64.urlsafe_b64encode(json.dumps(payload).encode()).decode().rstrip("=")
token = f"header.{raw}.signature"

claims = jwt_payload(token)
print("audience:", claims["aud"])
print("expires at unix time:", claims["exp"])

المخرجات:

audience: https://management.azure.com/
expires at unix time: 1767225600

مثال 33: دور مخصص بأقل الصلاحيات

اسمح بإجراء واحد فقط على نطاق واحد.

{
  "Name": "Blob Uploader",
  "IsCustom": true,
  "Description": "Can upload blobs to one storage account only.",
  "Actions": [],
  "DataActions": [
    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write"
  ],
  "AssignableScopes": [
    "/subscriptions/<subscription-id>/resourceGroups/rg-learn-dev"
  ]
}

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 34: إنشاء الدور المخصص

سجّل تعريف الدور في الاشتراك.

az role definition create --role-definition @blob-uploader.json

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

الموضوع 6: الحوسبة: الأجهزة الافتراضية وApp Service

تشغّل Azure شيفرتك على أجهزة افتراضية أو منصات مُدارة. تزيل App Service معظم أعمال الخوادم، بينما يمنحك الجهاز الافتراضي تحكمًا كاملًا في نظام التشغيل.

الأجهزة الافتراضية ومجموعات التوسيع

للجهاز الافتراضي حجم وصورة وأقراص وواجهة شبكة. تشغّل مجموعة التوسيع أجهزة متطابقة وتضيف إليها أو تُزيل منها حسب الطلب. أطفئ أجهزة التطوير ليلًا لتوفير المال.

خطط App Service وتطبيقات الويب

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

قرارات التوسيع التلقائي

تقارن قواعد التوسيع مقياسًا مثل متوسط CPU بعتبات، فتضيف مثيلًا أو تحذفه. تمنع فترة التهدئة النظام من التذبذب بين الأحجام.

مثال 35: إنشاء جهاز Linux افتراضي

شغّل آلة افتراضية بالحجم والصورة المختارين.

az vm create \
  --resource-group rg-learn-dev \
  --name vm-web-01 \
  --image Ubuntu2204 \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 36: عرض أحجام الأجهزة الافتراضية والأقراص

تحقق من السعة والتخزين قبل تغيير الحجم.

az vm list-sizes --location southeastasia --output table | head -n 10
az vm disk list --resource-group rg-learn-dev --output table

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 37: مجموعة قياس الأجهزة الافتراضية

أجهزة متطابقة تتوسع وتنكمش معًا.

resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2023-09-01' = {
  name: 'vmss-web'
  location: resourceGroup().location
  sku: {
    name: 'Standard_B2s'
    capacity: 2
  }
  properties: {
    upgradePolicy: { mode: 'Rolling' }
    // osProfile, networkProfile and storageProfile go here
  }
}

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 38: الإيقاف التلقائي لجهاز تطوير

أوقف جهاز الاختبار كل ليلة لتوفير التكلفة.

az vm auto-shutdown --resource-group rg-learn-dev --name vm-web-01 --time 2100

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 39: إنشاء خطة App Service وتطبيق ويب

استضف تطبيق ويب على خوادم Linux مُدارة.

az appservice plan create --name plan-shop-dev --resource-group rg-learn-dev --sku B1 --is-linux
az webapp create --name app-shop-dev-01 --resource-group rg-learn-dev \
  --plan plan-shop-dev --runtime "PYTHON:3.12"

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 40: نشر الشيفرة من ملف zip

ارفع حزمة التطبيق إلى تطبيق الويب.

zip -r app.zip . -x "*.git*"
az webapp deploy --resource-group rg-learn-dev --name app-shop-dev-01 \
  --src-path app.zip --type zip

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 41: إعدادات التطبيق وفتحة التجهيز

اختبر الإصدار الجديد قبل وصوله إلى المستخدمين.

az webapp config appsettings set --resource-group rg-learn-dev --name app-shop-dev-01 \
  --settings ENVIRONMENT=dev LOG_LEVEL=info
az webapp deployment slot create --resource-group rg-learn-dev --name app-shop-dev-01 --slot staging

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 42: قرارات التوسع حسب المعالج

أضف نسخًا عند الازدحام وأزلها عند الهدوء.

def scale_decision(cpu_samples, instances, minimum=1, maximum=5):
    average = sum(cpu_samples) / len(cpu_samples)
    if average > 75 and instances < maximum:
        return instances + 1, f"scale out (avg CPU {average:.0f}%)"
    if average < 25 and instances > minimum:
        return instances - 1, f"scale in (avg CPU {average:.0f}%)"
    return instances, f"hold (avg CPU {average:.0f}%)"

print(scale_decision([82, 90, 78], 2))
print(scale_decision([10, 12, 15], 2))
print(scale_decision([40, 45, 50], 2))

المخرجات:

(3, 'scale out (avg CPU 83%)')
(1, 'scale in (avg CPU 12%)')
(2, 'hold (avg CPU 45%)')

الموضوع 7: الحاويات: السجل وContainer Apps وKubernetes

تجمع الحاوية التطبيق مع كل ما يحتاجه. تخزّن Azure الصور في سجل، وتشغّلها في Container Apps أو Kubernetes بحسب درجة التحكم التي تحتاجها.

سجل حاويات Azure

السجل مخزن خاص للصور. ابنِ الصورة في Azure باستخدام az acr build حتى لا يعتمد البناء على حاسوبك، ثم ادفع النتيجة إلى السجل.

Container Apps وAKS

تشغّل Container Apps الحاويات دون إدارة مجموعة، وتتقلص إلى الصفر. وAKS هو Kubernetes المُدار للأنظمة الكبيرة. يستطيع AKS سحب الصور من سجلّك بهويته المُدارة، فلا تحتاج إلى كلمة مرور.

الوسوم والتنظيف

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

مثال 43: إنشاء سجل حاويات

مكان خاص لتخزين صور الحاويات.

az acr create --resource-group rg-learn-dev --name acrshopdev01 --sku Basic
az acr login --name acrshopdev01

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 44: بناء صورة ودفعها

ابنِ الصورة في Azure واحفظها في السجل.

az acr build --registry acrshopdev01 --image shop-api:1.0.0 .
az acr repository show-tags --name acrshopdev01 --repository shop-api -o table

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 45: تشغيل تطبيق حاوية

شغّل الحاوية دون إدارة الخوادم.

az containerapp env create --name cae-shop-dev --resource-group rg-learn-dev --location southeastasia
az containerapp create --name ca-shop-api --resource-group rg-learn-dev \
  --environment cae-shop-dev \
  --image acrshopdev01.azurecr.io/shop-api:1.0.0 \
  --target-port 8080 --ingress external --min-replicas 0 --max-replicas 3

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 46: إنشاء مجموعة AKS

مجموعة Kubernetes مُدارة تسحب الصور من سجلّك.

az aks create \
  --resource-group rg-learn-dev \
  --name aks-shop-dev \
  --node-count 2 \
  --enable-managed-identity \
  --attach-acr acrshopdev01 \
  --generate-ssh-keys
az aks get-credentials --resource-group rg-learn-dev --name aks-shop-dev

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 47: النشر على Kubernetes

طبّق البيان وانتظر اكتمال الإطلاق.

kubectl apply -f deployment.yaml
kubectl rollout status deployment/shop-api
kubectl get pods -l app=shop-api

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 48: بيان نشر Kubernetes

صِف الحاويات المصغّرة وعدد النسخ والموارد.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: shop-api
  template:
    metadata:
      labels:
        app: shop-api
    spec:
      containers:
        - name: shop-api
          image: acrshopdev01.azurecr.io/shop-api:1.0.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: 100m
              memory: 128Mi

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 49: توليد وسم للصورة

ضع على كل صورة وسمًا يتضمن الإصدار والتاريخ والالتزام.

from datetime import date

def image_tag(version, commit, when):
    short = commit[:7]
    return f"{version}-{when.strftime('%Y%m%d')}-{short}"

print(image_tag("1.4.2", "9f3c1ab7e54d0a12", date(2026, 1, 15)))

المخرجات:

1.4.2-20260115-9f3c1ab

مثال 50: حذف الصور القديمة بمهمة

احذف الصور غير الموسومة وفق جدول لتوفير التخزين.

az acr task create --name purge-old-images --registry acrshopdev01 \
  --cmd "acr purge --filter 'shop-api:.*' --ago 30d --untagged" \
  --schedule "0 1 * * *" --context /dev/null

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

الموضوع 8: التخزين: Blob والطوابير والتحكم في الوصول

تحتفظ حسابات التخزين بالملفات والرسائل والجداول. أمّن الوصول بـ Entra ID، واستخدم روابط SAS قصيرة العمر عندما تحتاج إلى المشاركة، ودع قواعد دورة الحياة تنقل البيانات القديمة إلى مستويات أرخص.

Blob ومسارات التسمية

تحتفظ حاويات Blob بالملفات. استخدم مسارات تتضمن الجهاز والتاريخ لتعرض أو تحذف بيانات يوم معين بسرعة. أبقِ الوصول العام مغلقًا ما لم يكن المحتوى عامًا فعلًا.

توقيعات الوصول المشترك

يمنح رابط SAS وصولًا محدودًا لفترة قصيرة. امنح الصلاحيات الضرورية فقط، مثل القراءة، واختر أقصر مدة صلاحية تصلح للعمل.

قواعد دورة الحياة والطوابير

تنقل قواعد دورة الحياة الـ Blob إلى مستويات cool أو archive، وتحذفها بعد عدد محدد من الأيام. تحتفظ الطوابير بالرسائل للعاملين في الخلفية، فلا تحجب مهمة بطيئة طلب الويب.

مثال 51: إنشاء حساب تخزين

إعدادات افتراضية آمنة: TLS 1.2 ومنع الوصول العام إلى Blob.

az storage account create \
  --name stlearndev01 \
  --resource-group rg-learn-dev \
  --location southeastasia \
  --sku Standard_LRS \
  --kind StorageV2 \
  --min-tls-version TLS1_2 \
  --allow-blob-public-access false

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 52: مسارات Blob مقسمة حسب التاريخ

نظّم الرفعات حسب الجهاز والتاريخ لتبقى الاستعلامات سريعة.

from datetime import datetime

def blob_path(device, when, filename):
    return f"telemetry/{device}/{when:%Y/%m/%d}/{when:%H%M%S}-{filename}"

print(blob_path("sensor-7", datetime(2026, 1, 15, 8, 30, 5), "batch.json"))

المخرجات:

telemetry/sensor-7/2026/01/15/083005-batch.json

مثال 53: رفع Blob

انسخ ملفًا إلى حاوية باستخدام CLI.

az storage container create --name uploads --account-name stlearndev01 --auth-mode login
az storage blob upload --account-name stlearndev01 --container-name uploads \
  --name reports/2026-01.csv --file ./report.csv --auth-mode login

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 54: الرفع من Python مع Entra ID

استخدم هوية Azure بدلًا من مفتاح الحساب.

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

client = BlobServiceClient(
    account_url="https://stlearndev01.blob.core.windows.net",
    credential=DefaultAzureCredential(),
)
blob = client.get_blob_client(container="uploads", blob="reports/2026-01.csv")
with open("report.csv", "rb") as data:
    blob.upload_blob(data, overwrite=True)

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 55: إنشاء SAS قصير العمر

رابط ينتهي ويمنح صلاحية القراءة فقط.

EXPIRY=$(date -u -d "+1 hour" '+%Y-%m-%dT%H:%MZ')
az storage blob generate-sas --account-name stlearndev01 --container-name uploads \
  --name reports/2026-01.csv --permissions r --expiry "$EXPIRY" --auth-mode login --as-user --output tsv

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 56: وصف أذونات SAS

اشرح ما الذي يسمح به توقيع الوصول المشترك ولمدة كم.

from datetime import datetime, timedelta, timezone

def describe_sas(permissions, expiry):
    names = {"r": "read", "w": "write", "d": "delete", "c": "create"}
    allowed = ", ".join(names[p] for p in permissions)
    left = expiry - datetime(2026, 1, 15, 8, 0, tzinfo=timezone.utc)
    return f"allows {allowed} for {int(left.total_seconds() // 60)} minutes"

print(describe_sas("rw", datetime(2026, 1, 15, 9, 0, tzinfo=timezone.utc)))

المخرجات:

allows read, write for 60 minutes

مثال 57: قواعد دورة حياة Blob

انقل البيانات القديمة إلى تخزين أرخص ثم احذفها.

{
  "rules": [
    {
      "enabled": true,
      "name": "archive-telemetry",
      "type": "Lifecycle",
      "definition": {
        "filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["telemetry/"] },
        "actions": {
          "baseBlob": {
            "tierToCool": { "daysAfterModificationGreaterThan": 30 },
            "delete": { "daysAfterModificationGreaterThan": 365 }
          }
        }
      }
    }
  ]
}

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 58: طابور التخزين لمهام الخلفية

ضع المهام في طابور ودع العمّال يعالجونها لاحقًا.

az storage queue create --name jobs --account-name stlearndev01 --auth-mode login
az storage message put --queue-name jobs --content "resize:photo-42" \
  --account-name stlearndev01 --auth-mode login

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

الموضوع 9: قواعد البيانات: Azure SQL وCosmos DB

تقدّم Azure قاعدة بيانات علائقية مُدارة وقاعدة بيانات NoSQL موزعة عالميًا. اتصل بالهوية بدلًا من كلمات المرور، واستخدم المعاملات في الاستعلامات دائمًا.

Azure SQL

Azure SQL قاعدة بيانات SQL Server مُدارة. فعّل مصادقة Microsoft Entra ID ونقاط النهاية الخاصة، فتصبح قاعدة البيانات بلا كلمة مرور محفوظة وبلا عنوان عام.

الاستعلامات ذات المعاملات

مرّر مدخلات المستخدم كمعاملات، ولا تدمج النص في SQL أبدًا. تعامل قاعدة البيانات المدخلات كبيانات، فيمنع ذلك حقن SQL.

Cosmos DB ومفاتيح التقسيم

يخزّن Cosmos DB مستندات JSON في حاويات. يحدد مفتاح التقسيم طريقة توزيع البيانات على الأجهزة. المفتاح الذي له قيم كثيرة مختلفة، مثل معرّف العميل، يحافظ على توازن الحمل.

مثال 59: خادم وقاعدة بيانات Azure SQL

قاعدة بيانات علائقية مُدارة مع شبكة خاصة.

az sql server create --name sql-shop-dev-01 --resource-group rg-learn-dev \
  --location southeastasia --enable-public-network false --enable-ad-only-auth \
  --external-admin-principal-type User --external-admin-name [email protected]
az sql db create --resource-group rg-learn-dev --server sql-shop-dev-01 \
  --name shopdb --service-objective S0

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 60: الاتصال بـ Azure SQL دون كلمة مرور

مصادقة Entra ID بدلًا من كلمة مرور مخزّنة.

import pyodbc

conn = pyodbc.connect(
    "Driver={ODBC Driver 18 for SQL Server};"
    "Server=tcp:sql-shop-dev-01.database.windows.net,1433;"
    "Database=shopdb;Encrypt=yes;"
    "Authentication=ActiveDirectoryDefault;"
)
cursor = conn.cursor()
cursor.execute("SELECT TOP 5 name FROM sys.tables")
print([row.name for row in cursor.fetchall()])

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 61: استعلامات بمعاملات

مرّر القيم كمعاملات حتى لا يغيّر الإدخال الاستعلام.

import sqlite3

conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE orders (id INTEGER, customer TEXT, total REAL)")
conn.executemany("INSERT INTO orders VALUES (?, ?, ?)",
                 [(1, "ana", 120.0), (2, "ben", 75.5)])

customer = "ana' OR '1'='1"          # hostile input stays a plain value
rows = conn.execute("SELECT id, total FROM orders WHERE customer = ?", (customer,)).fetchall()
print("matches:", rows)
conn.close()

المخرجات:

matches: []

مثال 62: إنشاء حاوية Cosmos DB

قاعدة بيانات موزعة عالميًا بمفتاح تقسيم.

az cosmosdb create --name cosmos-shop-dev-01 --resource-group rg-learn-dev \
  --locations regionName=southeastasia failoverPriority=0
az cosmosdb sql database create --account-name cosmos-shop-dev-01 --resource-group rg-learn-dev \
  --name shop
az cosmosdb sql container create --account-name cosmos-shop-dev-01 --resource-group rg-learn-dev \
  --database-name shop --name orders --partition-key-path "/customerId"

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 63: كتابة عنصر في Cosmos DB

خزّن مستند JSON في الحاوية.

from azure.cosmos import CosmosClient
from azure.identity import DefaultAzureCredential

client = CosmosClient("https://cosmos-shop-dev-01.documents.azure.com:443/", DefaultAzureCredential())
container = client.get_database_client("shop").get_container_client("orders")
container.upsert_item({"id": "o-1001", "customerId": "ana", "total": 120.0})

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 64: توزيع العناصر بتجزئة مفتاح التقسيم

المفتاح الجيد يوزّع البيانات بالتساوي عبر الأقسام.

import hashlib

def partition_for(key, partitions=4):
    digest = hashlib.sha256(key.encode("utf-8")).hexdigest()
    return int(digest, 16) % partitions

counts = [0, 0, 0, 0]
for customer in ["ana", "ben", "chai", "dao", "eve", "fon", "gus", "hana"]:
    counts[partition_for(customer)] += 1
print("items per partition:", counts)

المخرجات:

items per partition: [4, 1, 1, 2]

الموضوع 10: بدون خوادم مع Azure Functions

تشغّل Azure Functions أجزاء صغيرة من الشيفرة عندما يحدث شيء: طلب HTTP أو مؤقت أو رسالة في طابور. تدفع مقابل التنفيذ، ولا تدير الخوادم.

المحفزات والربطات

المحفز هو ما يبدأ الدالة، مثل طلب HTTP أو مؤقت. تربط الـ Bindings الدالة بخدمات أخرى، مثل الكتابة إلى طابور، فيقل كود الاتصال المطلوب.

المؤقتات وجداول cron

يستخدم محفز المؤقت تعبير NCRONTAB من ستة حقول، والثواني في البداية. التعبير 0 */5 * * * * يعمل كل خمس دقائق.

المعالجة المتماثلة الفعالية

قد تسلّم الطوابير الرسالة نفسها أكثر من مرة. سجّل المعرّفات التي عالجتها وتخطَّ المكررات، فلا يُحتسب على العميل مرتين عند تشغيل المهمة مرتين.

مثال 65: إنشاء تطبيق دوال

شيفرة بلا خادم على خطة الاستهلاك.

az storage account create --name stfuncshopdev01 --resource-group rg-learn-dev --sku Standard_LRS
az functionapp create --name func-shop-dev-01 --resource-group rg-learn-dev \
  --storage-account stfuncshopdev01 --consumption-plan-location southeastasia \
  --runtime python --runtime-version 3.12 --functions-version 4 --os-type Linux

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 66: دالة تُطلق بطلب HTTP

شغّل الشيفرة عند وصول طلب ويب.

import azure.functions as func

app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)

@app.route(route="hello", methods=["GET"])
def hello(req: func.HttpRequest) -> func.HttpResponse:
    name = req.params.get("name", "world")
    return func.HttpResponse(f"Hello, {name}!", status_code=200)

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 67: دالة مؤقت بجدول cron

شغّل الشيفرة كل خمس دقائق دون خادم.

import logging
import azure.functions as func

app = func.FunctionApp()

@app.timer_trigger(schedule="0 */5 * * * *", arg_name="timer", run_on_startup=False)
def every_five_minutes(timer: func.TimerRequest) -> None:
    logging.info("checking sensors")

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 68: التشغيل التالي لتعبير cron

احسب موعد التشغيل التالي للجدول.

def next_minutes(expression, current_minute):
    field = expression.split()[1]           # minute field, for example */5
    step = int(field.removeprefix("*/"))
    return step - (current_minute % step) if current_minute % step else step

for minute in (0, 3, 12, 14):
    print(f"at minute {minute:2d}: next run in {next_minutes('0 */5 * * * *', minute)} min")

المخرجات:

at minute  0: next run in 5 min
at minute  3: next run in 2 min
at minute 12: next run in 3 min
at minute 14: next run in 1 min

مثال 69: نشر تطبيق الدوال

انشر شيفرة Python إلى Azure Functions.

func azure functionapp publish func-shop-dev-01 --python

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 70: دالة تُطلق من طابور

عالج كل رسالة واكتب النتيجة في طابور آخر.

import azure.functions as func

app = func.FunctionApp()

@app.queue_trigger(arg_name="msg", queue_name="jobs", connection="AzureWebJobsStorage")
@app.queue_output(arg_name="out", queue_name="done", connection="AzureWebJobsStorage")
def process(msg: func.QueueMessage, out: func.Out[str]) -> None:
    out.set(f"processed:{msg.get_body().decode('utf-8')}")

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 71: معالجة الرسائل بمبدأ عدم التكرار

عالج الرسالة مرة واحدة حتى لو وصلت مرتين.

processed_ids = set()

def handle(message):
    if message["id"] in processed_ids:
        return "skipped duplicate"
    processed_ids.add(message["id"])
    return f"processed {message['id']}"

events = [{"id": "e1"}, {"id": "e2"}, {"id": "e1"}]
for event in events:
    print(handle(event))

المخرجات:

processed e1
processed e2
skipped duplicate

مثال 72: مراجع Key Vault في إعدادات التطبيق

حمّل السر إلى التطبيق دون نسخه.

az functionapp config appsettings set --name func-shop-dev-01 --resource-group rg-learn-dev \
  --settings "[email protected](VaultName=kv-shop-dev;SecretName=db-password)"

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

الموضوع 11: الشبكات: الشبكات الافتراضية وNSGs ونقاط النهاية الخاصة

الشبكة الافتراضية شبكتك الخاصة داخل Azure. تفصل الشبكات الفرعية الطبقات، وتحدّ قواعد الأمان حركة المرور، وتُبقي نقاط النهاية الخاصة الخدمات بعيدة عن الإنترنت العام.

الشبكات الافتراضية والشبكات الفرعية

اختر نطاق عناوين مثل 10.10.0.0/16، ثم قسّمه إلى شبكات فرعية للويب والبيانات. تحتجز Azure خمسة عناوين في كل شبكة فرعية، فالشبكة /24 تعطي 251 عنوانًا قابلًا للاستخدام.

مجموعات أمان الشبكة

مجموعة أمان الشبكة قائمة من قواعد السماح والرفض ذات الأولوية. اسمح بالمنافذ التي تحتاجها فقط، مثل 443 لـ HTTPS، واحجب الباقي افتراضيًا.

نقاط النهاية الخاصة وDNS

تعطي نقطة النهاية الخاصة الخدمة عنوان IP خاصًا داخل شبكتك. تجعل منطقة DNS الخاصة اسم الخدمة يُحل إلى ذلك العنوان، فلا تحتاج التطبيقات إلى تغيير في الشيفرة.

مثال 73: الشبكة الافتراضية والشبكات الفرعية

شبكة خاصة بشبكات فرعية منفصلة للويب والبيانات.

az network vnet create --name vnet-shop-dev --resource-group rg-learn-dev \
  --address-prefix 10.10.0.0/16 --subnet-name snet-web --subnet-prefix 10.10.1.0/24
az network vnet subnet create --vnet-name vnet-shop-dev --resource-group rg-learn-dev \
  --name snet-data --address-prefixes 10.10.2.0/24

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 74: قاعدة مجموعة أمان الشبكة

اسمح بـ HTTPS فقط من الإنترنت.

az network nsg create --name nsg-web --resource-group rg-learn-dev
az network nsg rule create --nsg-name nsg-web --resource-group rg-learn-dev \
  --name allow-https --priority 100 --direction Inbound --access Allow \
  --protocol Tcp --destination-port-ranges 443 --source-address-prefixes Internet

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 75: نقطة نهاية خاصة للتخزين

صِل إلى حساب التخزين من داخل شبكتك فقط.

az network private-endpoint create --name pe-storage --resource-group rg-learn-dev \
  --vnet-name vnet-shop-dev --subnet snet-data \
  --private-connection-resource-id $(az storage account show -n stlearndev01 -g rg-learn-dev --query id -o tsv) \
  --group-id blob --connection-name conn-storage

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 76: منطقة DNS خاصة

حلّ أسماء نقاط النهاية الخاصة داخل الشبكة الافتراضية.

az network private-dns zone create --resource-group rg-learn-dev \
  --name privatelink.blob.core.windows.net
az network private-dns link vnet create --resource-group rg-learn-dev \
  --zone-name privatelink.blob.core.windows.net --name link-shop \
  --virtual-network vnet-shop-dev --registration-enabled false

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 77: موازن حمل عام

وزّع حركة المرور الواردة على عدة آلات افتراضية.

az network public-ip create --name pip-lb --resource-group rg-learn-dev --sku Standard
az network lb create --name lb-shop --resource-group rg-learn-dev --sku Standard \
  --public-ip-address pip-lb --backend-pool-name be-web
az network lb probe create --lb-name lb-shop --resource-group rg-learn-dev \
  --name probe-https --protocol Tcp --port 443

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 78: حاسبة حجم الشبكة الفرعية

احسب عدد العناوين القابلة للاستخدام في كتلة CIDR.

import ipaddress

def usable_hosts(cidr):
    net = ipaddress.ip_network(cidr)
    return net.num_addresses - 5          # Azure reserves 5 addresses in every subnet

for block in ("10.10.1.0/24", "10.10.2.0/27", "10.10.0.0/16"):
    print(block, usable_hosts(block))

المخرجات:

10.10.1.0/24 251
10.10.2.0/27 27
10.10.0.0/16 65531

الموضوع 12: الرسائل والبث: Service Bus وEvent Hubs

تتواصل الخدمات عبر الرسائل. يُستخدم Service Bus للرسائل التجارية الموثوقة، ويُستخدم Event Hubs للتدفقات عالية الحجم مثل القياسات عن بُعد.

طوابير Service Bus

يحتفظ الطابور بالرسائل حتى يكملها المستقبِل. أكمل الرسالة بعد معالجتها فقط، فإذا تعطل النظام تحدث إعادة محاولة بدلًا من ضياع الطلب. الرسائل التي تفشل أكثر من اللازم تنتقل إلى طابور الرسائل الميتة.

Event Hubs والأقسام

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

الاختيار بينهما

استخدم Service Bus عندما يهم كل رسالة وتحتاج إلى معالجتها تمامًا كما هو مقصود. استخدم Event Hubs عندما تجمع أحداثًا بكميات كبيرة ويمكنك معالجتها بالترتيب داخل القسم.

مثال 79: طابور Service Bus

مراسلة موثوقة بين التطبيقات مع الرسائل الميتة.

az servicebus namespace create --name sb-shop-dev --resource-group rg-learn-dev --location southeastasia --sku Standard
az servicebus queue create --namespace-name sb-shop-dev --resource-group rg-learn-dev \
  --name orders --max-delivery-count 5 --dead-lettering-on-message-expiration true

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 80: إرسال رسالة Service Bus

ضع طلبًا في الطابور من Python.

from azure.identity import DefaultAzureCredential
from azure.servicebus import ServiceBusClient, ServiceBusMessage

with ServiceBusClient("sb-shop-dev.servicebus.windows.net", DefaultAzureCredential()) as client:
    with client.get_queue_sender("orders") as sender:
        sender.send_messages(ServiceBusMessage('{"orderId": "o-1001"}'))

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 81: استلام الرسالة وإكمالها

احذف الرسالة فقط بعد معالجتها بنجاح.

from azure.identity import DefaultAzureCredential
from azure.servicebus import ServiceBusClient

with ServiceBusClient("sb-shop-dev.servicebus.windows.net", DefaultAzureCredential()) as client:
    with client.get_queue_receiver("orders", max_wait_time=5) as receiver:
        for msg in receiver:
            print(str(msg))
            receiver.complete_message(msg)     # removes it only after processing succeeded

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 82: Event Hubs للقياسات عن بُعد

تدفق يستقبل ملايين الأحداث في الثانية.

az eventhubs namespace create --name evhns-shop-dev --resource-group rg-learn-dev --location southeastasia --sku Standard
az eventhubs eventhub create --name telemetry --namespace-name evhns-shop-dev --resource-group rg-learn-dev \
  --partition-count 4 --message-retention 1

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 83: إرسال دفعات إلى Event Hubs

اجمع الأحداث في دفعات لتحسين الكفاءة.

import json
from azure.eventhub import EventData, EventHubProducerClient
from azure.identity import DefaultAzureCredential

producer = EventHubProducerClient(
    fully_qualified_namespace="evhns-shop-dev.servicebus.windows.net",
    eventhub_name="telemetry",
    credential=DefaultAzureCredential(),
)
with producer:
    batch = producer.create_batch()
    batch.add(EventData(json.dumps({"device": "sensor-7", "temp_c": 21.5})))
    producer.send_batch(batch)

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 84: تقسيم الرسائل بحسب الحد الأقصى للحجم

اجعل كل دفعة أقل من الحجم الأقصى.

def make_batches(messages, limit_bytes=60):
    batches, current, size = [], [], 0
    for msg in messages:
        n = len(msg.encode("utf-8"))
        if current and size + n > limit_bytes:
            batches.append(current)
            current, size = [], 0
        current.append(msg)
        size += n
    if current:
        batches.append(current)
    return batches

events = [f'{{"id": {i}, "temp": 21.{i}}}' for i in range(6)]
for number, batch in enumerate(make_batches(events), start=1):
    print("batch", number, len(batch), "messages")

المخرجات:

batch 1 2 messages
batch 2 2 messages
batch 3 2 messages

الموضوع 13: المراقبة: Log Analytics وApplication Insights والتنبيهات

لا يمكنك إصلاح ما لا تراه. تجمع Azure Monitor السجلات والمقاييس، ويتيح لك Log Analytics الاستعلام عنها بـ KQL، وتخبر التنبيهات الفريق عندما تحدث مشكلة.

Log Analytics وKQL

تخزّن مساحة عمل Log Analytics السجلات من موارد كثيرة. تصفّي لغة Kusto هذه السجلات وتلخّصها وترسم مخططاتها، مثل عدّ الأعطال في كل ساعة.

Application Insights

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

تنبيهات بلا إنذارات كاذبة

ينطلق تنبيه المقياس عندما يتجاوز قياس عتبة. اشترط أن يستمر الشرط عبر عدة عينات متتالية، حتى لا توقظ قمة واحدة مهندس المناوبة.

مثال 85: مساحة عمل Log Analytics

مكان مركزي للاستعلام عن سجلات كل الموارد.

az monitor log-analytics workspace create --resource-group rg-learn-dev \
  --workspace-name log-shop-dev --location southeastasia --retention-time 30

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 86: استعلام KQL للأخطاء

احسب الطلبات الفاشلة في كل ساعة بلغة Kusto.

AppRequests
| where TimeGenerated > ago(24h)
| where Success == false
| summarize failures = count() by bin(TimeGenerated, 1h), ResultCode
| order by TimeGenerated desc

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 87: إعدادات التشخيص

أرسل سجلات المنصة والمقاييس إلى مساحة العمل.

az monitor diagnostic-settings create \
  --name diag-storage \
  --resource /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev/providers/Microsoft.Storage/storageAccounts/stlearndev01 \
  --workspace log-shop-dev \
  --logs '[{"category":"StorageRead","enabled":true}]' \
  --metrics '[{"category":"Transaction","enabled":true}]'

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 88: قياسات Application Insights

تتبّع الطلبات والأحداث المخصصة من شيفرة Python.

from opentelemetry import trace
from azure.monitor.opentelemetry import configure_azure_monitor

configure_azure_monitor(connection_string="InstrumentationKey=<key>;IngestionEndpoint=https://southeastasia-1.in.applicationinsights.azure.com/")
tracer = trace.get_tracer("shop")
with tracer.start_as_current_span("checkout") as span:
    span.set_attribute("order.total", 120.0)

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 89: تنبيه مقياس عند بطء الاستجابة

أبلغ فريق المناوبة عندما يصبح الـ API بطيئًا.

az monitor metrics alert create --name alert-slow-api --resource-group rg-learn-dev \
  --scopes /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev/providers/Microsoft.Web/sites/app-shop-dev-01 \
  --condition "avg HttpResponseTime > 2" --window-size 5m --evaluation-frequency 1m \
  --action /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev/providers/microsoft.insights/actionGroups/ag-oncall

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 90: تنبيه بعد عدة قيم سيئة متتالية

تجنب الإنذارات الكاذبة بطلب سلسلة من القراءات السيئة.

def should_alert(samples, threshold=2.0, required=3):
    streak = 0
    for value in samples:
        streak = streak + 1 if value > threshold else 0
        if streak >= required:
            return True
    return False

print(should_alert([1.0, 2.5, 2.7, 2.9, 1.1]))
print(should_alert([2.5, 1.0, 2.5, 2.5, 1.0]))

المخرجات:

True
False

الموضوع 14: الأمان: Key Vault والأسرار وحماية التهديدات

تنتمي الأسرار إلى خزنة، لا إلى الشيفرة أو السجلات. يخزّنها Key Vault مع التحكم في الوصول، ويراقب Defender for Cloud موارد الاشتراك بحثًا عن التهديدات.

Key Vault والوصول

يخزّن Key Vault الأسرار والمفاتيح والشهادات. استخدم التحكم في الوصول القائم على الأدوار، وامنح كل تطبيق صلاحية قراءة الأسرار التي يحتاجها فقط، وسجّل كل وصول.

قراءة الأسرار بأمان

يستخدم DefaultAzureCredential الهوية المُدارة داخل Azure وتسجيل دخولك على حاسوبك، فيعمل الكود نفسه في المكانين. لا تطبع السر أبدًا، ولا تكتبه في السجل.

Defender for Cloud

يقيّم Defender for Cloud وضعك الأمني ويفعّل حماية التهديدات للأجهزة الافتراضية والتخزين وKey Vault. راجع توصياته بانتظام.

مثال 91: Key Vault وسر

خزّن كلمة المرور في خزنة مع التحكم في الوصول.

az keyvault create --name kv-shop-dev --resource-group rg-learn-dev --location southeastasia \
  --enable-rbac-authorization true
az keyvault secret set --vault-name kv-shop-dev --name db-password --value "$DB_PASSWORD"

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 92: قراءة سر من Python

استخدم DefaultAzureCredential لجلب السر.

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

client = SecretClient(vault_url="https://kv-shop-dev.vault.azure.net/", credential=DefaultAzureCredential())
password = client.get_secret("db-password").value
# use the value, never print it

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 93: إخفاء الأسرار من السجلات

أخفِ كلمات المرور والمفاتيح قبل كتابة أي شيء.

import re

def redact(text):
    text = re.sub(r"(password|secret|token)=\S+", r"\1=***", text, flags=re.IGNORECASE)
    text = re.sub(r"(AccountKey=)[^;\s]+", r"\1***", text)
    return text

print(redact("connecting with password=hunter2 to host"))
print(redact("AccountKey=abc123==;EndpointSuffix=core.windows.net"))

المخرجات:

connecting with password=*** to host
AccountKey=***;EndpointSuffix=core.windows.net

مثال 94: خطط Defender for Cloud

فعّل الحماية من التهديدات للأجهزة الافتراضية والتخزين وKey Vault.

az security pricing create --name VirtualMachines --tier Standard
az security pricing create --name StorageAccounts --tier Standard
az security pricing create --name KeyVaults --tier Standard

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

الموضوع 15: DevOps والتكلفة والحوكمة

تحتاج الأنظمة الإنتاجية إلى خط معالجة قابل للتكرار، وحد للإنفاق، وقواعد يجب أن يلتزم بها كل مورد جديد. تُبقي هذه الممارسات Azure موثوقًا وميسور التكلفة مع توسع الفريق.

خطوط المعالجة والتراجع

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

الميزانيات وتقديرات التكلفة

تحدد الميزانية حدًا شهريًا وترسل تنبيهات قبل الوصول إليه. قدّر التكلفة من الساعات والتخزين، ثم قارنها بالفاتورة الفعلية، وصدّر تقارير يومية.

Azure Policy

تفحص السياسة الموارد وفق قاعدة، مثل اشتراط وسم المالك. يمنع أثر الرفض إنشاء موارد غير متوافقة، فيفرض المعايير التي اتفقتم عليها.

مثال 95: خط أنابيب Azure DevOps

اختبر عند كل دفع وانشر تطبيق الويب من main.

trigger:
  branches:
    include: [main]

pool:
  vmImage: ubuntu-latest

steps:
  - task: UsePythonVersion@0
    inputs:
      versionSpec: '3.12'
  - script: pip install -r requirements.txt && pytest
    displayName: Test
  - task: AzureWebApp@1
    inputs:
      azureSubscription: sc-shop-dev
      appName: app-shop-dev-01
      package: '$(System.DefaultWorkingDirectory)'

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 96: ميزانية شهرية

حدد سقف إنفاق وأرسل تنبيهًا قبل الوصول إليه.

az consumption budget create --budget-name budget-dev --amount 200 \
  --category Cost --time-grain Monthly \
  --start-date 2026-01-01 --end-date 2026-12-31 \
  --resource-group rg-learn-dev

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 97: تقدير الفاتورة الشهرية

حوّل ساعات الاستخدام والتخزين إلى تكلفة تقريبية.

def monthly_cost(hours_per_day, hourly_rate, storage_gb, storage_rate, days=30):
    compute = hours_per_day * days * hourly_rate
    storage = storage_gb * storage_rate
    return round(compute + storage, 2)

print(monthly_cost(10, 0.05, 120, 0.02))
print(monthly_cost(24, 0.05, 120, 0.02))

المخرجات:

17.4
38.4

مثال 98: تصدير بيانات التكلفة

أرسل تقارير التكلفة اليومية إلى حساب التخزين.

az costmanagement export create --name daily-costs \
  --scope "/subscriptions/<subscription-id>/resourceGroups/rg-learn-dev" \
  --storage-account-id /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev/providers/Microsoft.Storage/storageAccounts/stlearndev01 \
  --storage-container exports --timeframe MonthToDate --recurrence Daily \
  --recurrence-period from=2026-01-01T00:00:00Z to=2026-12-31T00:00:00Z

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مثال 99: قرار التراجع عن النشر

استخدم معدل الأخطاء والتأخير لتقرر التراجع.

def should_roll_back(error_rate, previous_error_rate, latency_ms, latency_limit=800):
    if error_rate > 0.05:
        return True, "error rate above 5 percent"
    if error_rate > previous_error_rate * 2 and error_rate > 0.01:
        return True, "error rate doubled since the last release"
    if latency_ms > latency_limit:
        return True, "latency above limit"
    return False, "healthy"

print(should_roll_back(0.02, 0.01, 300))
print(should_roll_back(0.07, 0.01, 300))

المخرجات:

(False, 'healthy')
(True, 'error rate above 5 percent')

مثال 100: فرض الوسوم عبر Azure Policy

ارفض الموارد الجديدة التي لا تحمل وسم المالك.

az policy definition create --name require-owner-tag --display-name "Require owner tag" \
  --rules '{"if":{"field":"tags[owner]","exists":"false"},"then":{"effect":"deny"}}' --mode Indexed
az policy assignment create --name require-owner --policy require-owner-tag \
  --scope /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev

*لم يُشغَّل هذا المثال هنا لأنه يحتاج إلى اشتراك Azure أو أدوات Azure.*

مشروع تدريبي: تطبيق ويب آمن مع تخزين ومراقبة

ابنِ إعدادًا صغيرًا وآمنًا واحدًا يستخدم أفكارًا من عدة أقسام. اكتب Bicep والسكربتات بنفسك أولًا، ثم قارنها بالأمثلة. احذف مجموعة الموارد عند الانتهاء لتجنب الرسوم.

1. أنشئ مجموعة موارد بوسمَي owner وenvironment، وتحقق من الوسوم الناقصة بسكربت.

2. اكتب قالب Bicep لحساب تخزين يستخدم TLS 1.2 ولا يسمح بالوصول العام إلى Blob، وعاين التغييرات بـ what-if قبل النشر.

3. أنشئ هوية مُدارة مُسندة للمستخدم، وامنحها دور Storage Blob Data Reader على حساب التخزين فقط.

4. انشر تطبيق ويب يقرأ Blob بهويته المُدارة، وأضف تنبيهًا عندما يبقى متوسط زمن الاستجابة أعلى من ثانيتين.

5. أنشئ ميزانية عند 80 بالمئة من حدك الشهري، ثم احذف مجموعة الموارد وتأكد من الحذف في البوابة.

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

بعد ذلك، ادرس إرشادات هندسة Azure، واحصل على شهادة قائمة على الأدوار مثل AZ-900 أو AZ-104، وتدرّب على خطوط معالجة البنية التحتية باستخدام GitHub Actions أو Azure DevOps. نفّذ كل الأوامر في اشتراك تجريبي أولًا، واقرأ وثائق الخدمة للإصدار الذي تنشره.

الخلاصة

تصبح Azure منصة احترافية عندما تصفها بالشيفرة، وتؤمّنها بالهويات بدلًا من كلمات المرور، وتراقبها، وتتحكم في تكلفتها. عبر 100 مثال، غطت هذه المقالة واجهة Azure CLI ومجموعات الموارد والوسوم والسكربتات وBicep والهوية وRBAC والأجهزة الافتراضية وApp Service والحاويات وKubernetes والتخزين وقواعد البيانات وFunctions بدون خوادم والشبكات والرسائل والمراقبة وKey Vault والأمان وDevOps مع حوكمة التكلفة. ابنِ تطبيق الويب الآمن في المشروع التدريبي، وغيّر إعدادًا واحدًا في كل مرة لتتعلم كيف يعمل كل جزء.