Share via


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

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

Служба Azure 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. Убедитесь, что конфигурация хранилища разрешает доступ к сети или подсети, которую приложение использует для доступа к нему.

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

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

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

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

  2. Настройте приложение для использования этого удостоверения для ссылочных операций хранилища ключей, задав 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}
    

Этот параметр применяется ко всем ссылкам на хранилище ключей для приложения.

Rotation

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

Параметры исходного приложения из хранилища ключей

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

Совет

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

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

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

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

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

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

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

Рекомендации по подключению службы "Файлы Azure"

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

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

Внимание

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

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

Рекомендации по инструментированию Аналитика приложений

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

Развертывание 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.

Устранение неполадок со ссылками на хранилище ключей

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

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

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

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

Использование детектора для Службы приложений

  1. На портале перейдите к вашему приложению.
  2. Выберите Диагностика и решение проблем.
  3. Выберите Availability and Performance (Доступность и производительность), а затем — Web app down (Отключение веб-приложений).
  4. В поле поиска найдите и выберите приложение Key Vault Параметры диагностики.

Использование детектора для Функций Azure

  1. На портале перейдите к вашему приложению.
  2. Перейдите к Функциям платформы.
  3. Выберите Диагностика и решение проблем.
  4. Выберите Availability and Performance (Доступность и производительность), а затем — Function app down or reporting errors (Приложение-функция не работает или уведомляет об ошибках).
  5. Выберите приложение Key Vault Параметры диагностику.