Поделиться через


Использование ссылок Key Vault в качестве параметров приложения в службе приложений Azure и Azure Functions

Примечание.

Начиная с 1 июня 2024 года только что созданные приложения службы приложений могут создать уникальное имя узла по умолчанию, использующее соглашение об именовании <app-name>-<random-hash>.<region>.azurewebsites.net. Например: myapp-ds27dh7271aah175.westus-01.azurewebsites.net. Существующие имена приложений остаются неизменными.

Дополнительные сведения см. в записи блога о создании веб-приложения с уникальным именем узла по умолчанию.

В этой статье показано, как использовать секреты из Azure Key Vault в качестве значений параметров приложения или строк подключения в приложениях Службы приложений Azure или Функций Azure.

Key Vault — это служба, которая обеспечивает централизованное управление секретами с полным контролем над политиками доступа и журналом аудита. Если параметр приложения или строка подключения является ссылкой на Key Vault, код приложения может использовать его как любой другой параметр приложения или строку подключения. Таким образом, вы можете хранить секреты отдельно от конфигурации приложения. Параметры приложения безопасно шифруются в состоянии покоя, но если вам нужны возможности для управления секретами, они должны храниться в хранилище ключей.

Предоставление приложению доступа к хранилищу ключей

Чтобы прочитать секреты из хранилища ключей, сначала необходимо создать хранилище и предоставить приложению разрешение на доступ к нему:

  1. Чтобы создать хранилище ключей, изучите краткое руководство по Key Vault.

  2. Создайте для приложения управляемое удостоверение.

    Ссылки на хранилище ключей используют удостоверение, назначаемое системой, по умолчанию, но вы можете указать удостоверение, назначаемое пользователем.

  3. Разрешите доступ на чтение к секретам в хранилище ключей для управляемого удостоверения, которое вы создали. Как это сделать, зависит от модели разрешений хранилища ключей:

Доступ к хранилищам с ограничением через сеть

Если хранилище настроено с сетевыми ограничениями, убедитесь, что у приложения есть сетевой доступ. Хранилища не должны зависеть от общедоступных исходящих IP-адресов приложения, так как IP-адрес источника конфиденциального запроса может отличаться. Вместо этого хранилище должно быть настроено для приема трафика из виртуальной сети, которую использует приложение.

  1. Убедитесь, что в приложении настроены исходящие сетевые возможности, как описано в сетевых функциях службы приложений и параметрах сети Функций Azure.

    В настоящее время приложения Linux, подключающиеся к частным конечным точкам, должны быть явно настроены для маршрутизации всего трафика через виртуальную сеть. Чтобы настроить этот параметр, выполните следующую команду:

    az webapp config set --subscription <sub> -g <group-name> -n <app-name> --generic-configurations '{"vnetRouteAllEnabled": true}'
    
  2. Убедитесь, что конфигурация хранилища разрешает доступ к сети или подсети, которую приложение использует для доступа к нему.

Обратите внимание, что даже если вы правильно настроили хранилище для приема трафика из вашей виртуальной сети, в журналах аудита хранилища все равно может отображаться неудачное событие доступа (403 - запрещено) SecretGet из общедоступного исходящего IP-адреса приложения. За этим должно последовать успешное событие SecretGet с частного IP-адреса приложения, так и задумано.

Доступ к хранилищам с использованием пользовательского удостоверения

Некоторые приложения должны ссылаться на секреты при создании, когда системное удостоверение еще недоступно. В этих случаях вы можете создать пользовательскую идентификацию и предоставить ей доступ к хранилищу заранее.

После предоставления разрешений идентификации, назначенной пользователем, выполните следующие действия.

  1. Назначьте удостоверение приложению, если вы этого еще не сделали.

  2. Настройте приложение для использования этого удостоверения при выполнении операций с Key Vault, установив свойство keyVaultReferenceIdentity в значение идентификатора ресурса назначенного пользователем удостоверения.

    identityResourceId=$(az identity show --resource-group <group-name> --name <identity-name> --query id -o tsv)
    az webapp update --resource-group <group-name> --name <app-name> --set keyVaultReferenceIdentity=${identityResourceId}
    

Этот параметр применяется ко всем ссылкам Key Vault для приложения.

Понимание поворота

Если секретная версия не указана в ссылке, приложение использует последнюю версию, которая существует в хранилище ключей. Когда новые версии становятся доступными, например с событием смены, приложение автоматически обновляется и начинает использовать последнюю версию в течение 24 часов.

Задержка обусловлена тем, что служба App Service кэширует значения ссылок Key Vault и обновляет их каждые 24 часа. Любое изменение конфигурации в приложении приводит к перезапуску приложения и немедленному повторному извлечению всех ссылочных секретов.

Общие сведения о параметрах исходного приложения из Key Vault

Чтобы использовать ссылку Key Vault, задайте ссылку в качестве значения параметра. Ваше приложение может ссылаться на секрет через его ключ как обычно. Изменения кода не требуются.

Совет

Большинство параметров приложения, которые используют ссылки на "Key Vault", должны быть помечены как параметры слота, поскольку для каждой среды должны существовать отдельные хранилища.

Ссылка на Key Vault имеет форму @Microsoft.KeyVault({referenceString}), где {referenceString} находится в одном из следующих форматов:

Строка ссылки Описание
SecretUri=<secretUri> Полный URI секрета в плоскости данных в хранилище должен быть SecretUri; например, https://myvault.vault.azure.net/secrets/mysecret. При необходимости включите версию, например https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931.
VaultName=<vaultName>;SecretName=<secretName>;SecretVersion=<secretVersion> Значение VaultName обязательно и является именем хранилища. Значение SecretName обязательно и должно быть использовано в качестве имени секрета. Значение SecretVersion является необязательным, но при наличии указывает версию секрета для использования.

Например, полная ссылка без определенной версии будет выглядеть следующим образом:

@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret)

Еще один вариант:

@Microsoft.KeyVault(VaultName=myvault;SecretName=mysecret)

Соображения по подключению Azure Files

Приложения могут использовать WEBSITE_CONTENTAZUREFILECONNECTIONSTRING параметр приложения для подключения Azure Files в качестве файловой системы. Эта настройка содержит проверку для валидации, чтобы убедиться, что приложение может быть корректно запущено.

Платформа использует общую папку содержимого в службе "Файлы Azure" и принимает имя по умолчанию, если не указано иное с помощью параметра WEBSITE_CONTENTSHARE. Для любых запросов, изменяющих эти параметры, платформа проверяет, существует ли эта общая папка содержимого. Если общий доступ к контенту не существует, платформа пытается создать его. Если платформа не может найти или создать общий доступ к содержимому, она блокирует запрос.

При использовании ссылок Key Vault в этих настройках проверка по умолчанию завершается ошибкой, так как секрет не может быть определён во время обработки входящего запроса. Чтобы избежать этой проблемы, можно пропустить проверку, установив WEBSITE_SKIP_CONTENTSHARE_VALIDATION на 1. Этот параметр указывает службе приложений обходить все проверки и не создавать общую папку содержимого для вас. Необходимо заранее создать общий доступ к содержимому.

Внимание

Если пропустить проверку и либо строка подключения, либо общая папка содержимого недопустима, приложение не запустится правильно и будет выдавать ошибки HTTP 500.

При создании приложения попытка монтирования общего доступа к содержимому может завершиться ошибкой, так как разрешения управляемого удостоверения не предоставляются, или не настроена интеграция виртуальной сети. Вы можете отложить настройку файлов Azure до конца в шаблоне развертывания, чтобы обеспечить это поведение. Дополнительные сведения см. в статье о развертывании Azure Resource Manager далее в этой статье. В этом случае Служба приложений использует файловую систему по умолчанию до настройки Azure Files, и файлы не копируются. Необходимо убедиться, что попытки развертывания не выполняются в течение временного интервала до подключения Файлов Azure.

Рекомендации по инструментированию Application Insights

Приложения могут использовать APPINSIGHTS_INSTRUMENTATIONKEY параметры приложения или APPLICATIONINSIGHTS_CONNECTION_STRING параметры приложения для интеграции с Application Insights.

Опыт работы с Службой приложений Azure и Функциями Azure также использует эти параметры для отображения данных телеметрии из ресурса. Если эти значения извлекаются из Key Vault, эти функции становятся недоступными, и необходимо работать напрямую с ресурсом Application Insights для просмотра телеметрии. Однако эти значения не считаются секретами, поэтому их можно настроить непосредственно вместо использования ссылок Key Vault.

Развертывание Azure Resource Manager

При автоматизации развертываний ресурсов с помощью шаблонов Azure Resource Manager может потребоваться выполнить последовательность зависимостей в определенном порядке, чтобы эта функция работала. Не забудьте задать параметры приложения как отдельный ресурс, а не использовать свойство siteConfig в определении приложения. Сначала необходимо определить приложение, чтобы с ним было создано назначаемое системой удостоверение и могло использоваться в политике доступа.

Следующий псевдо-шаблон является примером того, как может выглядеть приложение-функция:

{
    //...
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageAccountName')]",
            //...
        },
        {
            "type": "Microsoft.Insights/components",
            "name": "[variables('appInsightsName')]",
            //...
        },
        {
            "type": "Microsoft.Web/sites",
            "name": "[variables('functionAppName')]",
            "identity": {
                "type": "SystemAssigned"
            },
            //...
            "resources": [
                {
                    "type": "config",
                    "name": "appsettings",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('storageConnectionStringName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('appInsightsKeyName'))]"
                    ],
                    "properties": {
                        "AzureWebJobsStorage": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringName')).secretUriWithVersion, ')')]",
                        "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringName')).secretUriWithVersion, ')')]",
                        "APPINSIGHTS_INSTRUMENTATIONKEY": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('appInsightsKeyName')).secretUriWithVersion, ')')]",
                        "WEBSITE_ENABLE_SYNC_UPDATE_SITE": "true"
                        //...
                    }
                },
                {
                    "type": "sourcecontrols",
                    "name": "web",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.Web/sites/config', variables('functionAppName'), 'appsettings')]"
                    ],
                }
            ]
        },
        {
            "type": "Microsoft.KeyVault/vaults",
            "name": "[variables('keyVaultName')]",
            //...
            "dependsOn": [
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ],
            "properties": {
                //...
                "accessPolicies": [
                    {
                        "tenantId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.tenantId]",
                        "objectId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.principalId]",
                        "permissions": {
                            "secrets": [ "get" ]
                        }
                    }
                ]
            },
            "resources": [
                {
                    "type": "secrets",
                    "name": "[variables('storageConnectionStringName')]",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
                    ],
                    "properties": {
                        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),'2019-09-01').key1)]"
                    }
                },
                {
                    "type": "secrets",
                    "name": "[variables('appInsightsKeyName')]",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
                    ],
                    "properties": {
                        "value": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2019-09-01').InstrumentationKey]"
                    }
                }
            ]
        }
    ]
}

Примечание.

В этом примере развертывание системы контроля версий зависит от настроек приложения. Эта зависимость обычно небезопасна, так как обновление параметров приложения ведет себя асинхронно. Однако, поскольку мы включили WEBSITE_ENABLE_SYNC_UPDATE_SITE параметр приложения, обновление синхронно. Развертывание системы контроля версий начнется только после полного обновления параметров приложения. Дополнительные параметры приложения описаны в разделе Переменные среды и параметры приложения в службе приложений Azure.

Устранение неполадок со ссылками Key Vault

Если ссылка не устранена должным образом, вместо нее используется строка ссылки (например, @Microsoft.KeyVault(...)). Эта ситуация может привести к возникновению ошибок в приложении, так как ожидается секрет с другим значением.

Не удается устранить проблему, как правило, из-за неправильной настройки политики доступа к Key Vault. Однако причиной может также быть то, что секрет больше не существует, или ссылка содержит синтаксическую ошибку.

Если синтаксис правильный, можно поискать другие причины ошибки, проверив текущее состояние разрешения на портале. Перейдите в раздел "Параметры приложения " и выберите "Изменить " для ссылки. В диалоговом окне редактирования отображаются сведения о состоянии, включая любые ошибки. Если сообщение о состоянии не отображается, это означает, что синтаксис недопустим и не распознается как ссылка на Key Vault.

Для получения дополнительных сведений можно также использовать один из встроенных детекторов.

Чтобы использовать детектор для службы приложений, выполните следующие действия.

  1. На портале перейдите к приложению.
  2. Выберите Диагностика и решение проблем.
  3. Выберите "Доступность и производительность>Сбой веб-приложения".
  4. В поле поиска выполните поиск и выберите Key Vault Application Settings Diagnostics.

Чтобы использовать детектор функций Azure, выполните следующие действия.

  1. На портале перейдите к приложению.
  2. Перейдите к функциям платформы.
  3. Выберите Диагностика и решение проблем.
  4. Выберите Доступность и производительность>Функция приложения не работает или сообщает об ошибках.
  5. Выберите диагностику параметров приложения Key Vault.