استخدام مراجع تكوين التطبيق ل App Service وAzure Functions

يوضح لك هذا الموضوع كيفية التعامل مع بيانات التكوين في تطبيق App Service وAzure Functions دون الحاجة إلى أي تغييرات في التعليمات البرمجية. Azure App Configuration هي خدمة لإدارة تكوين التطبيق مركزيًا. بالإضافة إلى ذلك، إنها أداة تدقيق فعالة لقيم التكوين الخاصة بك بمرور الوقت أو الإصدارات.

منح تطبيقك حق الوصول إلى App Configuration

لبدء استخدام مراجع App Configuration في App Service، ستحتاج أولاً إلى مخزن App Configuration، وتوفر إذن التطبيق للوصول إلى قيم مفتاح التكوين في المتجر.

  1. أنشئ مخزن App Configuration باتباع التشغيل السريع لـ App Configuration.

  2. قم بإنشاء هوية مُدارة لتطبيقك.

    ستستخدم مراجع App Configuration الهوية المعينة لنظام التطبيق افتراضيًا، ولكن يمكنك تحديد هوية معينة من قبل المستخدم.

  3. مكن الهوية التي تم إنشاؤها حديثًا للحصول على المجموعة الصحيحة من أذونات الوصول في مخزن App Configuration. حدث تعيينات الأدوار لمخزنك. ستقوم بتعيين دور App Configuration Data Reader لهذه الهوية، محدد النطاق عبر المورد.

الوصول إلى مخزن App Configuration بهوية معينة من قبل المستخدم

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

بمجرد منحك أذونات للهوية المعينة من قبل المستخدم، اتبع الخطوات التالية:

  1. عيّن الهوية لتطبيقك إذا لم تكن قد قمت بذلك بالفعل.

  2. بادر بتهيئة التطبيق لاستخدام هذه الهوية للعمليات المرجعية لـ App Configuration من خلال تعيين الخاصية keyVaultReferenceIdentity على معرّف المورد للهوية المعينة من قبل المستخدم. على الرغم من أن الخاصية تحتوي على keyVault في الاسم، سيتم تطبيق الهوية على مراجع App Configuration أيضًا.

    userAssignedIdentityResourceId=$(az identity show -g MyResourceGroupName -n MyUserAssignedIdentityName --query id -o tsv)
    appResourceId=$(az webapp show -g MyResourceGroupName -n MyAppName --query id -o tsv)
    az rest --method PATCH --uri "${appResourceId}?api-version=2021-01-01" --body "{'properties':{'keyVaultReferenceIdentity':'${userAssignedIdentityResourceId}'}}"
    

سيتم تطبيق هذا التكوين على جميع المراجع من App.

منح تطبيقك حق الوصول إلى خزائن المفاتيح المشار إليها

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

إشعار

يجب عدم الخلط بين مفهوم مراجع Azure App Configuration Key Vault ومفهوم مراجع App Service وAzure Functions Key Vault. قد يستخدم تطبيقك أي تركيبة من هذه، ولكن هناك بعض الاختلافات المهمة التي يجب ملاحظتها. إذا كان المخزن الخاص بك بحاجة إلى تقييد الشبكة أو كنت بحاجة إلى تحديث التطبيق بشكل دوري إلى أحدث الإصدارات، ففكر في استخدام نهج App Service وAzure Functions المباشر بدلا من استخدام مرجع تكوين التطبيق.

  1. حدد الهوية التي استخدمتها لمرجع App Configuration. يجب منح الوصول إلى المخزن لنفس الهوية.

  2. إنشاء نهج وصول في Key Vault لتلك الهوية. قم بتمكين "الحصول" على إذن سري لهذا النهج. لا تقم بتكوين إعدادات "التطبيق المصرح به" أو applicationId، لأن هذا لا يتوافق مع هوية مُدارة.

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

مرجع App Configuration هو من النموذج @Microsoft.AppConfiguration({referenceString})، حيث {referenceString} يتم استبداله أدناه:

أجزاء سلسلة مرجعية ‏‏الوصف
Endpoint=endpoint; نقطة النهاية هي الجزء المطلوب من السلسلة المرجعية. يجب أن تحتوي قيمة نقطة النهاية على عنوان URL لمورد App Configuration الخاص بك.
Key=keyName; يشكل المفتاح الجزء المطلوب من السلسلة المرجعية. يجب أن تكون قيمة المفتاح هي اسم المفتاح الذي تريد تعيينه لإعداد App.
Label=label جزء التسمية اختياري في السلسلة المرجعية. يجب أن تكون التسمية قيمة التسمية للمفتاح المحدد في المفتاح

على سبيل المثال، قد يبدو المرجع الكامل مع Label كما يلي،

@Microsoft.AppConfiguration(Endpoint=https://myAppConfigStore.azconfig.io; Key=myAppConfigKey; Label=myKeysLabel)​

بدلاً من ذلك دون أي Label:

@Microsoft.AppConfiguration(Endpoint=https://myAppConfigStore.azconfig.io; Key=myAppConfigKey)​

يؤدي أي تغيير في التكوين إلى التطبيق ينتج عنه إعادة تشغيل موقع إلى إعادة إحضار فورية لجميع قيم المفاتيح المشار إليها من متجر App Configuration.

إشعار

التحديث التلقائي/إعادة جلب هذه القيم عند تحديث قيم المفاتيح في تكوين التطبيق، غير مدعوم حاليا.

إعدادات التطبيق المصدر من App Config

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

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

تلميح

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

اعتبارات خاصة بتركيب ملفات Azure

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

إذا كنت تستخدم مراجع App Configuration لهذا الإعداد، سيفشل اختبار التحقق هذا افتراضيًا، حيث لا يمكن حل الاتصال نفسه أثناء معالجة الطلب الوارد. لتجنب هذه المشكلة، يمكنك تخطي عملية التحقق من خلال تعيين WEBSITE_SKIP_CONTENTSHARE_VALIDATION على "1". سيؤدي هذا الإعداد إلى تجاوز جميع عمليات التحقق، ولن يتم إنشاء مشاركة المحتوى لك. يجب عليك التأكد من إنشائه مسبقًا.

تنبيه

إذا تخطيت التحقق وكانت سلسلة الاتصال أو مشاركة المحتوى غير صالحة، فلن يتمكن التطبيق من البدء بشكل صحيح وسيعرض فقط أخطاء HTTP 500.

كجزء من إنشاء الموقع، من الممكن أيضًا أن تفشل محاولة تحميل مشاركة المحتوى بسبب عدم نشر أذونات الهوية المُدارة أو عدم إعداد تكامل الشبكة الظاهرية. يمكنك تأجيل إعداد Azure Files حتى وقت لاحق في قالب التوزيع لاستيعاب ذلك. راجع توزيع Azure Resource Manager لمعرفة المزيد. ستستخدم App Service نظام ملفات افتراضيًا حتى يتم إعداد Azure Files ولا يتم نسخ الملفات، لذلك ستحتاج إلى التأكد من عدم حدوث محاولات توزيع أثناء الفترة المؤقتة قبل تحميل Azure Files.

استخدام Azure Resource Manager

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

فيما يلي مثال على قالب صوري لتطبيق الوظائف مع مراجع App Configuration:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "roleNameGuid": {
            "type": "string",
            "defaultValue": "[newGuid()]",
            "metadata": {
                "description": "A new GUID used to identify the role assignment"
            }
        }
    },
    "variables": {
        "functionAppName": "DemoMBFunc",
        "appConfigStoreName": "DemoMBAppConfig",
        "resourcesRegion": "West US2",
        "appConfigSku": "standard",
        "FontNameKey": "FontName",
        "FontColorKey": "FontColor",
        "myLabel": "Test",
        "App Configuration Data Reader": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '516239f1-63e1-4d78-a4de-a74fb236a071')]"
    },
    "resources": [
        {
            "type": "Microsoft.Web/sites",
            "name": "[variables('functionAppName')]",
            "apiVersion": "2021-03-01",
            "location": "[variables('resourcesRegion')]",
            "identity": {
                "type": "SystemAssigned"
            },
            //...
            "resources": [
                {
                    "type": "config",
                    "name": "appsettings",
                    "apiVersion": "2021-03-01",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))]"
                    ],
                    "properties": {
                        "WEBSITE_FONTNAME": "[concat('@Microsoft.AppConfiguration(Endpoint=', reference(resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))).endpoint,'; Key=',variables('FontNameKey'),'; Label=',variables('myLabel'), ')')]",
                        "WEBSITE_FONTCOLOR": "[concat('@Microsoft.AppConfiguration(Endpoint=', reference(resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))).endpoint,'; Key=',variables('FontColorKey'),'; Label=',variables('myLabel'), ')')]",
                        "WEBSITE_ENABLE_SYNC_UPDATE_SITE": "true"
                        //...
                    }
                },
                {
                    "type": "sourcecontrols",
                    "name": "web",
                    "apiVersion": "2021-03-01",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.Web/sites/config', variables('functionAppName'), 'appsettings')]"
                    ]
                }
            ]
        },
        {
            "type": "Microsoft.AppConfiguration/configurationStores",
            "name": "[variables('appConfigStoreName')]",
            "apiVersion": "2019-10-01",
            "location": "[variables('resourcesRegion')]",
            "sku": {
                "name": "[variables('appConfigSku')]"
            },
            //...
            "dependsOn": [
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ],
            "properties": {
            },
            "resources": [
                {
                    "type": "keyValues",
                    "name": "[variables('FontNameKey')]",
                    "apiVersion": "2021-10-01-preview",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))]"

                    ],
                    "properties": {
                        "value": "Calibri",
                        "contentType": "application/json"
                    }
                },
                {
                    "type": "keyValues",
                    "name": "[variables('FontColorKey')]",
                    "apiVersion": "2021-10-01-preview",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))]"

                    ],
                    "properties": {
                        "value": "Blue",
                        "contentType": "application/json"
                    }
                }
            ]
        },
        {
            "scope": "[resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))]",
            "type": "Microsoft.Authorization/roleAssignments",
            "apiVersion": "2020-04-01-preview",
            "name": "[parameters('roleNameGuid')]",
            "properties": {
                "roleDefinitionId": "[variables('App Configuration Data Reader')]",
                "principalId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.principalId]",
                "principalType": "ServicePrincipal"
            }
        }
    ]
}

إشعار

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

استكشاف أخطاء مراجع App Configuration وإصلاحها

إذا لم يتم حل المرجع بشكل صحيح، فسيتم استخدام القيمة المرجعية بدلاً من ذلك. بالنسبة لإعدادات التطبيق، سيتم إنشاء متغير بيئة له قيمته بناء الجملة @Microsoft.AppConfiguration(...). قد يتسبب ذلك في حدوث خطأ، حيث كان التطبيق يتوقع قيمة تكوين بدلاً من ذلك.

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

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