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


Используйте ссылки Key Vault в качестве параметров приложения в Служба приложений Azure, Функции Azure и Azure Logic Apps (стандартный)

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

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

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

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

  1. Создайте хранилище ключей, следуя краткому руководству Key Vault.

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

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

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

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

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

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

    За исключением приложений-функций, работающих в плане потребления Flex, приложения Linux, подключающиеся к частным конечным точкам, должны быть явно настроены для маршрутизации всего трафика через виртуальную сеть. При выполнении в плане потребления Flex эта маршрутизация выполняется автоматически, а дополнительная конфигурация не требуется. Выполните следующую команду, чтобы настроить маршрутизацию виртуальной сети, задав vnetRouteAllEnabled значение true:

    az webapp config set --resource-group <group-name>  --subscription <subscription> --name <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 в приложении.

Совет

Если вы хотите вернуть использование назначенного системой удостоверения для вашего приложения, задайте значение SystemAssigned вместо идентификатора ресурса.

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

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

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

Чтобы принудительно разрешить ссылки на Key Vault вашего приложения, сделайте аутентифицированный POST-запрос к конечной точке API https://management.azure.com/[Resource ID]/config/configreferences/appsettings/refresh?api-version=2022-03-01.

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

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

Совет

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

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

Строка ссылки Описание
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> Значение VaultName обязательно и является именем хранилища. Значение SecretName обязательно и должно быть использовано в качестве имени секрета. Значение SecretVersion является необязательным, но при наличии указывает версию секрета для использования.

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

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

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

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

Соображения по монтированию Файлы Azure

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

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

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

Внимание

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

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

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

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

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

Для App Service и Функции 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

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

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

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

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

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

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

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

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