VSTS Build Pipeline: не удается подключиться к хранилищу ключей Azure. - PullRequest
0 голосов
/ 16 октября 2018

Я пытаюсь использовать VSTS (теперь Azure DevOps) для создания конвейера CI / CD.Для моего конвейера сборки у меня есть очень базовая настройка, включающая выполнение шагов восстановления, сборки, тестирования и публикации.

Для моего шага тестирования у меня настроено выполнение двух тестовых проектов - одного проекта модульного тестирования и одного проекта интеграционного тестирования.У меня есть настройка политики доступа к Key Vault, чтобы обеспечить доступ как к себе, так и к Azure Devops.Когда я запускаю свои тесты локально с помощью Visual Studio, поскольку я вошел в ту же учетную запись, которая имеет доступ к хранилищу ключей Azure, я могу выполнить тесты без каких-либо ошибок.

Мое приложение настроено для доступа к хранилищу ключей, используя следующую настройку:

 public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((ctx, builder) =>
            {
                var keyVaultEndpoint = GetKeyVaultEndpoint();

                if (!string.IsNullOrEmpty(keyVaultEndpoint))
                {
                    var azureServiceTokenProvider = new AzureServiceTokenProvider();
                    var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
                    builder.AddAzureKeyVault(keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
                }
            }
        )
            .UseStartup<Startup>();

Когда я запускаю конвейер сборки, я использую экземпляр Hosted VS2017 для сборки моего проекта.Все работает, кроме интеграционных тестов, которые пытаются получить доступ к хранилищу ключей.Я использую следующие пакеты:

  • Microsoft.Azure.Services.AppAuthentication - упрощает выборку токенов доступа для сценариев проверки подлинности между службами.
  • Microsoft.Azure.KeyVault - содержит методы взаимодействия с Key Vault.
  • Microsoft.Extensions.Configuration.AzureKeyVault - содержит
    Расширения IConfiguration для хранилища ключей Azure

Я следовал этому руководству https://docs.microsoft.com/en-us/azure/key-vault/tutorial-web-application-keyvault донастроить хранилище ключей и интегрировать его в мое приложение.

Я просто пытаюсь заставить мою сборку работать, убедившись, что и модульные, и интеграционные тесты пройдены.Я еще не развернул его в службе приложений.Модульные тесты запускаются без проблем, так как я издеваюсь над различными сервисами.Мой интеграционный тест не пройден с сообщениями об ошибках ниже.Как получить тестовый доступ к хранилищу ключей?Нужно ли добавлять какие-либо специальные политики доступа в мое хранилище ключей для размещенной сборки VS2017?Не уверен, что делать, поскольку я не вижу ничего, что выделяется.

Build

Ниже приведена трассировка стека для ошибки:

    2018-10-16T00:37:04.6202055Z Test run for D:\a\1\s\SGIntegrationTests\bin\Release\netcoreapp2.1\SGIntegrationTests.dll(.NETCoreApp,Version=v2.1)
    2018-10-16T00:37:05.3640674Z Microsoft (R) Test Execution Command Line Tool Version 15.8.0
    2018-10-16T00:37:05.3641588Z Copyright (c) Microsoft Corporation.  All rights reserved.
    2018-10-16T00:37:05.3641723Z 
    2018-10-16T00:37:06.8873531Z Starting test execution, please wait...
    2018-10-16T00:37:51.9955035Z [xUnit.net 00:00:40.80]     SGIntegrationTests.HomeControllerShould.IndexContentTypeIsTextHtml [FAIL]
    2018-10-16T00:37:52.0883568Z Failed   SGIntegrationTests.HomeControllerShould.IndexContentTypeIsTextHtml
    2018-10-16T00:37:52.0884088Z Error Message:
    2018-10-16T00:37:52.0884378Z  Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException : Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/63cd8468-5bc3-4c0a-a6f8-1e314d696937. Exception Message: Tried the following 3 methods to get an access token, but none of them worked.
    2018-10-16T00:37:52.0884737Z Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/63cd8468-5bc3-4c0a-a6f8-1e314d696937. Exception Message: Tried to get token using Managed Service Identity. Access token could not be acquired. MSI ResponseCode: BadRequest, Response: {"error":"invalid_request","error_description":"Identity not found"}
    2018-10-16T00:37:52.0884899Z Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/63cd8468-5bc3-4c0a-a6f8-1e314d696937. Exception Message: Tried to get token using Visual Studio. Access token could not be acquired. Visual Studio Token provider file not found at "C:\Users\VssAdministrator\AppData\Local\.IdentityService\AzureServiceAuth\tokenprovider.json"
    2018-10-16T00:37:52.0885142Z Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/63cd8468-5bc3-4c0a-a6f8-1e314d696937. Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. Process took too long to return the token.
    2018-10-16T00:37:52.0885221Z 
    2018-10-16T00:37:52.0885284Z Stack Trace:
    2018-10-16T00:37:52.0885349Z    at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.GetAccessTokenAsyncImpl(String authority, String resource, String scope)
    2018-10-16T00:37:52.0885428Z    at Microsoft.Azure.KeyVault.KeyVaultCredential.PostAuthenticate(HttpResponseMessage response)
    2018-10-16T00:37:52.0885502Z    at Microsoft.Azure.KeyVault.KeyVaultCredential.ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    2018-10-16T00:37:52.0886831Z    at Microsoft.Azure.KeyVault.KeyVaultClient.GetSecretsWithHttpMessagesAsync(String vaultBaseUrl, Nullable`1 maxresults, Dictionary`2 customHeaders, CancellationToken cancellationToken)
    2018-10-16T00:37:52.0886887Z    at Microsoft.Azure.KeyVault.KeyVaultClientExtensions.GetSecretsAsync(IKeyVaultClient operations, String vaultBaseUrl, Nullable`1 maxresults, CancellationToken cancellationToken)
    2018-10-16T00:37:52.0886935Z    at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.LoadAsync()
    2018-10-16T00:37:52.0887000Z    at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.Load()
    2018-10-16T00:37:52.0887045Z    at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
    2018-10-16T00:37:52.0887090Z    at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
    2018-10-16T00:37:52.0887269Z    at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
    2018-10-16T00:37:52.0887324Z    at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
    2018-10-16T00:37:52.0887371Z    at Microsoft.AspNetCore.TestHost.TestServer..ctor(IWebHostBuilder builder, IFeatureCollection featureCollection)
    2018-10-16T00:37:52.0887433Z    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateServer(IWebHostBuilder builder)
    2018-10-16T00:37:52.0887477Z    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
    2018-10-16T00:37:52.0887525Z    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)

Обновление

Я нашел только 1 связанный пост с этой проблемой: https://social.msdn.microsoft.com/Forums/en-US/0bac778a-283a-4be1-bc75-605e776adac0/managed-service-identity-issue?forum=windowsazurewebsitespreview. Но пост связан с развертыванием приложения в лазурном слоте.Я просто пытаюсь построить свое приложение в конвейере сборки.

Я все еще пытаюсь решить эту проблему и не уверен, каков наилучший способ обеспечить требуемый доступ.


Обновление 2

Я до сих пор не нашел решения для этого.Я заблудился о том, как заставить мой конвейер выполнить мой тест без проблем.Я видел, что на конвейере выпуска у вас есть варианты запуска тестов тоже.Но они, похоже, занимают файлы .dll, и мой файл сброса конвейера сборки содержит только веб-приложение (я не вижу ни одного из опубликованных файлов сброса тестовых проектов).Не уверен, что это вообще возможно.


Обновление 3

Мне удалось заставить его работать, используя последний вариант, представленный здесь: https://docs.microsoft.com/en-us/azure/key-vault/service-to-service-authentication#connection-string-support

Я пробовал другие способы использования сертификата, но когда в строке подключения указывается {CurrentUser}, конвейер сборки завершается неудачно.Он работает на моей локальной машине, но не в конвейере сборки.

Чтобы заставить его работать, мне пришлось сделать три вещи:

  • Войдите в Azure.Настройка новой регистрации приложения в Azure AD
  • В новой регистрации приложения AD создайте новый секретный ключ клиента enter image description here
  • Предоставьте доступ к новому приложению ADк вашему хранилищу ключей.Зайдите в свои политики доступа к хранилищу ключей и добавьте приложение, созданное вами в AD, с доступом для чтения к вашим секретам.enter image description here

  • Изменил мой вызов на AzureServiceTokenProvier () в моем Program.cs файл следующим образом:

     var azureServiceTokenProvider = new AzureServiceTokenProvider("connectionString={your key vault endpoint};RunAs=App;AppId={your app id that you setup in Azure AD};TenantId={your azure subscription};AppKey={your client secret key}")
    

Обратите внимание, что ваш клиентский секрет должен быть правильно отформатирован.Приложение регистрации (превью) генерирует случайный секретный ключ.Иногда этот ключ не работает в строке подключения (выдает ошибку как неправильно отформатированный).Либо попробуйте сгенерировать свой собственный ключ в версии предварительного просмотра регистрации приложения, либо сгенерируйте новый ключ и повторите попытку.

После этого я смог успешно запустить интеграционный тест в конвейере сборки и создать выпуск длямое веб-приложение в Azure.Я не удовлетворен этим подходом, потому что, хотя он работает, он показывает секретное значение в самом коде.Управлять идентификацией службы не нужно, чтобы включить из-за вышеупомянутого подхода.Я чувствую, что это очень плохо в этом отношении.

Должен быть лучший способ, чем этот.Один из вариантов - не запускать тест интеграции в конвейере сборки.Не уверен, что это правильный подход.Я все еще надеюсь, что кто-то сможет предоставить лучший подход к этому или объяснить, подходит ли мой подход для использования.

Ответы [ 3 ]

0 голосов
/ 26 октября 2018

Не следует выполнять интеграционный тест проверки подлинности для Azure KeyVault в рамках сборки Azure DevOps Pipelines, поскольку вы используете размещенные по умолчанию агенты DevOps Azure.

По умолчанию в конвейерах AzO DevOps используются основные размещенные агенты по умолчанию.и эти размещенные агенты недоступны из вашей подписки Azure.Это неудивительно, поскольку эти размещенные агенты являются общими агентами для всех общих потребностей сборки, включая сборку / компиляцию, выполнение модульных тестов, получение тестовых покрытий, и все эти задачи не имеют других дополнительных функций, таких как ActiveDirectory, база данных и другие.фактическая проверка подлинности / запросы другой стороне, например проверка подлинности для любого Azure Keyvault.Поэтому эти агенты по умолчанию не зарегистрированы в вашей подписке Azure.

Если вы хотите успешно провести интеграционные тесты для этих особых нужд, вам нужно создать свои собственные агенты для сборки и выпуска Azure DevOps Pipelines.Поэтому нет другого способа заставить агент по умолчанию AzOv DevOps запускать ваши тесты аутентификации KeyVault, кроме создания собственных агентов и настройки ваших DevOps Azure для использования ваших собственных агентов.

Чтобы создать собственных агентов, обратитесь кэта документация от Microsoft:

https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=vsts#install

ОБНОВЛЕНИЕ 29 октября 2018 :

Для большей ясности я также отвечу на ваше "Обновление 3"«Обходной путь.Нет никаких гарантий, что ваш обходной путь будет хорошо работать, когда Microsoft обновит размещенный по умолчанию агент Azure DevOps.Поэтому мне также нужно добавить еще один момент: не рекомендуется использовать интеграционный тест, который опирается на другую сторону за пределами вашей сборки Azure DevOps Pipelines, такую ​​как подключение к серверу базы данных или использование внешних аутентификаций (даже в Azure KeyVault) внутриваш CI, особенно если вы используете размещенные по умолчанию агенты Microsoft.

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

0 голосов
/ 03 июля 2019

Используйте конвейерную задачу Azure CLI для успешного запуска интеграционных тестов, для которых требуются секреты KeyVault, без раскрытия каких-либо секретов в управлении исходным кодом:

  1. Создайте Сервисное соединение с субъектом-службой в вашем проекте Azure DevOps.

  2. Дайте основному Получите и Список разрешенийв хранилище в Azure.

  3. Запустите интеграционные тесты внутри задачи CLI Azure :

    - task: AzureCLI@1
      inputs:
        azureSubscription: 'Your Service Connection Name'
        scriptLocation: 'inlineScript'
        inlineScript: 'dotnet test --configuration $(buildConfiguration) --logger trx'
    

    Это работает, потому что тесты будут выполнятьсяв контексте azure cli, где AzureServiceTokenProvider пытается извлечь токен, прежде чем он выйдет из строя .Azure CLI обрабатывает проверку подлинности и очищает, когда задача выполнена.

0 голосов
/ 24 октября 2018

Сам столкнулся с точно такой же проблемой.Я продвинулся немного дальше, изменив код, добавив строку подключения к AzureServiceTokenProvider (переданный по умолчанию параметр - ноль).Хотя я до сих пор не получил его полноценную работу, может быть, поскольку пользователь Azure DevOps может иметь или не иметь требуемого доступа к KeyVault, но у меня не было возможности углубиться в него.Надеемся, что здесь опубликовано лучшее решение.

Обновление Мы добавили пользователя Build в Azure AD, а затем добавили его в Политики доступа в KeyVault для пользователя.Предоставление только Get Access (Наш тест только проверял, сможет ли он собрать секрет).Тесты успешно пройдены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...