Архитектура виртуальной сети 2 — конвейеры развертывания


Резюме

Эта статья является частью 2 цикла статей об архитектуре виртуальных сетей. Я поделюсь деталями всего конвейера в примере шаблона api-management-vnet.

  • Архитектура виртуальной сети 1 — Нужна ли мне виртуальная сеть?
  • Архитектура виртуальной сети 2 — конвейеры развертывания
  • Архитектура виртуальной сети 3 — Частная конечная точка хранилища ключей
  • Архитектура виртуальной сети 4 — Частная конечная точка базы данных SQL
  • Архитектура виртуальной сети 5 — Частная конечная точка службы приложений
  • Архитектура виртуальной сети 6 — Частная конечная точка сервисной шины
  • Архитектура виртуальной сети 7 — Самостоятельно размещаемый агент

TOC

  • Обзор
  • Архитектура
  • Трубопроводы
    • Обзор двух конвейеров
    • pipeline-base.yml
    • pipeline-vnet1.yml
    • pipeline-vnet2.yml

Обзор

Образец шаблона api-management-vnet включает два сценария — 1) базовая архитектура без виртуальной сети, 2) архитектура виртуальной сети. Обе архитектуры используют одни и те же службы Azure, описанные ниже.

Используемые в обеих архитектурах

  • Azure Pipelines: Развертывание инфраструктуры, сборка и развертывание кода, сборка и развертывание агента self-hosted, выполнение интеграционных тестов путем отправки запросов REST API.
  • Azure API Management: Платформа для управления API, которые в данном шаблоне работают на Azure App Service.
  • Azure App Service: Служба хостинга веб-интерфейсов API.
  • Azure Functions: Служба бессерверного хостинга, на которой выполняются коды.
  • Azure SQL: SQL Server в облаке Azure.
  • Azure Key Vault: Служба управления секретами, которая хранит ключи и сертификаты, доступные из других служб Azure.
  • Azure Service Bus: брокер сообщений в облаке Azure с очередью сообщений и темами pub-sub.

Только в архитектуре виртуальной сети

  • Azure Application Gateway: Балансировщик нагрузки веб-трафика, который в этом шаблоне работает как шлюз архитектуры виртуальной сети.

Архитектура

Обе архитектуры имеют одинаковые темы Web API, Functions, Database и Service Bus. Azure Pipelines проводит те же интеграционные тесты, отправляя API-запросы в тему Web API и Service Bus. В архитектуре виртуальной сети есть два важных отличия от базовой архитектуры.

  • Шлюз приложений находится перед API Management. К API Management и App Service нельзя получить доступ из интернета, а только через Application Gateway. Таким образом, конечная точка API отличается.

  • В первом конвейере создается self-hosted агент, который развертывается внутри подсети виртуальной сети. Второй конвейер работает на этом агенте, поэтому он может получить доступ к частным конечным точкам App Service и Service Bus.

Базовая архитектура

Архитектура виртуальной сети

Конвейеры

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

Обзор двух конвейеров

Базовая архитектура имеет только pipeline-base.yml, а архитектура виртуальных сетей включает pipeline-vnet1.yml и pipeline-vnet2.yml. Первый конвейер архитектуры виртуальной сети развертывает ресурсы Azure без частных конечных точек и создает саморазмещающийся агент, а второй конвейер работает на саморазмещающемся агенте и развертывает и устанавливает частные точки для ресурсов. В конце второго конвейера выполняются интеграционные тесты внутри виртуальной сети.

pipeline-base.yml

Шаг 1. В файле keyvault-secret.yml конвейер создает хранилище ключей, если оно не существует, и передает секреты, вводимые из переменных Azure Pipelines, поэтому вам не нужно хранить эти секреты в переменных Azure Pipeline, но после второго раза конвейер автоматически определяет переменную конвейера и загружает секреты из существующего хранилища ключей. Эта техника описана в разделе Управление секретами Azure Pipelines с помощью Key Vault.

Шаг 2. azure-resource.yml развертывает ресурсы Azure с main.bicep.

  • Вам необходимо указать секретные переменные, обработанные в предыдущем шаге Key Vault. Если у вас есть больше секретных переменных для улучшения, необходимо добавить переменные здесь.
- job: AzureResourceDeployment
    variables:
    - template: ./variables.yml
    - name: SqlPass
      value: $[ stageDependencies.KeyVault.SQL_PASS.outputs['SQL_PASS.SQL_PASS'] ]
    - name: AadSecretClient
      value: $[ stageDependencies.KeyVault.AAD_SECRET_CLIENT.outputs['AAD_SECRET_CLIENT.AAD_SECRET_CLIENT'] ]
Вход в полноэкранный режим Выход из полноэкранного режима
  • Развертывание Azure API Management занимает около одного часа. Чтобы избежать ошибки тайм-аута, он указывает timeout: 0. Однако я иногда обнаруживал ошибки и после одного часа. Если вы столкнулись с ошибкой тайм-аута, вы можете просто повторно запустить конвейер, и вы увидите, что после этого все пойдет гладко.
- job: AzureResourceDeployment
    timeoutInMinutes: 0
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 3. sql.yml развертывает схему базы данных SQL с файлом .dacpac, созданным проектом WeatherDB SQL.

Шаг 4. func.yml развертывает .NET C# код ServicebusListener в Azure Functions.

Шаг 5. webapi.yml развертывает .NET C# код проекта WeatherAPI в Azure App Service. Кроме того, он определяет API в API Management и генерирует swagger.json и развертывает его в API Management.

- task: DotNetCoreCLI@2
  displayName: dotnet new tool-manifest
  inputs:
    command: custom
    custom: new
    arguments: tool-manifest
    workingDirectory: ${{ parameters.apiProjectDirectory }}
- task: DotNetCoreCLI@2
  displayName: dotnet tool install
  inputs:
    command: custom
    custom: tool
    arguments: install Swashbuckle.AspNetCore.Cli --version $(SWASHBUCKLE_VERSION)
    workingDirectory: ${{ parameters.apiProjectDirectory }}
- task: DotNetCoreCLI@2
  displayName: dotnet swagger tofile
  inputs:
    command: custom
    custom: swagger
    arguments: tofile --output ${{ parameters.swaggerPath }} ${{ parameters.apiDllPath }} $(SWAGGER_VERSION)
    workingDirectory: ${{ parameters.apiProjectDirectory }}
- task: AzureCLI@2
  displayName: Deploy API to API Management
  inputs:
    azureSubscription: ${{ parameters.azureSvcName }}
    scriptType: bash
    scriptLocation: inlineScript
    inlineScript: |
      az apim api import -g $(RESOURCE_GROUP_NAME) 
        --service-name $(API_MANAGEMENT_NAME) 
        --api-id $(API_NAME) 
        --path /$(API_NAME) 
        --specification-format OpenApiJson 
        --specification-path ${{ parameters.swaggerPath }} 
        --service-url $(API_MANAGEMENT_SERVICE_URL)
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 6. integration-test-powershell.yml выполняет интеграционные тесты для развернутых Web API и функций.

  • С помощью приведенного ниже сценария powershell он извлекает токен OAuth2.0 из Azure Active Directory, чтобы затем прикрепить его при отправке REST-запроса к API Management. Поскольку агент Azure Pipelines отправляет запрос с помощью автоматизации, он следует потоку Client Credential Flow OAuth2.0. Этот поток OAuth2.0 объясняется в разделе Конфигурация приложения Azure AD для Web API.
$clientSecret = Get-AzKeyVaultSecret -VaultName $env:KEYVAULT_NAME -Name $env:KVSECRET_NAME_AADCLIENT -AsPlainText
$authorizeUri = "https://login.microsoftonline.com/${{ parameters.aadTenantId }}/oauth2/v2.0/token"
$body = 'grant_type=client_credentials' + `
'&client_id=${{ parameters.aadAppidClient }}' + `
'&client_secret=' + $clientSecret + `
'&scope=api://${{ parameters.aadAppidBackend }}/.default'
$token = (Invoke-RestMethod -Method Post -Uri $authorizeUri -Body $body).access_token
Вход в полноэкранный режим Выход из полноэкранного режима
  • В базовой архитектуре нет Application Gateway, и конечная точка находится в API Management. Маршрут /Weatherforecast служит для GET и POST данных в Azure SQL Databse, а /Weatherforecast/message — для отправки сообщения в тему Service Bus, которая запускает Azure Functions и вставляет запись в SQL Database.
parameters:
  url: https://$(API_MANAGEMENT_NAME).azure-api.net
Вход в полноэкранный режим Выход из полноэкранного режима
$Uri = "${{ parameters.url }}/$env:API_NAME/Weatherforecast"
$UriMessage = "${{ parameters.url }}/$env:API_NAME/Weatherforecast/message"
Вход в полноэкранный режим Выход из полноэкранного режима

pipeline-vnet1.yml

pipeline-vnet1.yml включает в себя следующие шаги.

  • Сохранение секретов из переменных Pipeline в Key Vault
  • Сгенерируйте SSL-сертификат для бэкенд-пула шлюза приложений
  • Развертывание служб Azure
  • Постройте саморазмещаемый агент
  • Развертывание проектов в App Service, Functions и SQL Database
  • Выполнить интеграционные тесты

После выполнения этого конвейера некоторые ресурсы, такие как App Service, Key Vault, SQL Database, Functions и Service Bus, не защищены в виртуальной сети. Только Application Gateway и API Management подключены к виртуальной сети и находятся в ней. Самостоятельный агент создан и развернут на Azure Container Instances и готов к использованию.

Шаг 1. cert-appgateway.yml генерирует и устанавливает в Key Vault SSL-сертификат для бэкэнд-пула API Management. В Key Vault требуется предоставить право доступа для Azure Pipeliens Microsoft hosted agent.

Set-AzKeyVaultAccessPolicy -VaultName $env:KEYVAULT_NAME -PermissionsToCertificates get,create -ObjectId ${{ parameters.aadObjectidSvc }}
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 2. keyvault-secret.yml — это тот же шаблон, что использовался в базовой архитектуре. На этот раз он добавляет секретную переменную AZP_TOKEN, которая необходима для развертывания агента на хостинге. Как получить персональный токен доступа, описано в разделе Getting-started.

Шаг 3. azure-resource.yml развертывает ресурсы Azure с main1.bicep. Все виртуальные сети и подсети развертываются на этот раз с помощью VirtualNetwork.bicep. Все диапазоны IP-адресов виртуальных сетей определены в файле main.parameters.json.

Шаг 4. restart-appgateway.yml перезапускает Application Gateway. Я столкнулся с ошибками без перезапуска Application Gateway. Согласно документации Microsoft Updates to the DNS entries of the backend pool, при изменении DNS записей для backend pool необходимо перезапустить Application Gateway. В развертывании ресурса Azure с PrivateDns1.bicep создается запись DNS A для API Management. Затем необходимо перезапустить Application Gateway.

resource PrivateDnsAApim 'Microsoft.Network/privateDnsZones/A@2020-06-01' = {
  name: '${PrivateDnsApim.name}/${ApiManagementName}'
  properties: {
    ttl: 3600
    aRecords: [
      {
        ipv4Address: ApiManagementPrivateIPAddress
      }
    ]
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 5. self-hosted-agent.yml создает и развертывает self-hosted agent на базе Linux.

  • Начиная с августа 2022 года, вы можете запускать self-hosted agent на базе Windows в контейнере docker, но контейнерные экземпляры Azure на базе Windows не могут быть развернуты в виртуальной сети, согласно документации Microsoft Deploy container instances in an Azure virtual network. Самостоятельный агент на базе Windows необходим для развертывания проектов SQL Database, но пока часть сборки самостоятельного агента Windows закомментирована.

  • Контейнерное приложение self-hosted agent определяется в Dockerfile.

  • После того как образ контейнера будет помещен в Azure Container Registry, развертывание на Azure Container Instance реализуется в linux-agent.bicep.

Шаг 6. sql.yml такой же, как использовался в конвейере Base, и развертывает схему базы данных SQL с файлом .dacpac, созданным проектом WeatherDB SQL.

Шаг 7. func.yml аналогичен используемому в конвейере Base и развертывает .NET C# код ServicebusListener в Azure Functions.

Шаг 8. webapi.yml аналогичен используемому в конвейере Base и развертывает .NET C# код проекта WeatherAPI в Azure App Service, определяет API в API Management и генерирует swagger.json и развертывает его в API Management.

Шаг 9. integration-test-powershell.yml такой же, как использовался в конвейере Base, и выполняет интеграционные тесты для развернутых Web API и Functions.

pipeline-vnet2.yml

pipeline-vnet2.yml включает следующие шаги.

  • Выполнение интеграционных тестов перед установкой частных конечных точек
  • Развертывание и установка частных конечных точек
  • Выполнение интеграционных тестов для частных конечных точек
  • Развертывание проектов в App Service и Functions с частными конечными точками с помощью self-hosted агента
  • Выполнение интеграционных тестов для развертывания кода через частные конечные точки.

Этот конвейер развертывает и устанавливает частные конечные точки, поэтому все службы Azure защищены виртуальной сетью. Вы больше не сможете развернуть новое программное обеспечение на App Service и Functions, поскольку им запрещен доступ через Интернет. Агент self-hosted, работающий на Azure Container Instance, находится внутри виртуальной сети и способен создавать и развертывать новое программное обеспечение.

Вы можете увидеть, как этот конвейер использует self-hosted agent, указав пул, как показано ниже. Все описанные ниже шаги могут быть выполнены на агенте на базе Linux.

pool:
  name: Default
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг 1. integration-test-bash.yml выполняет интеграционные тесты перед развертыванием и настройкой частных конечных точек. Самостоятельно размещаемый агент основан на Linux, и этот интеграционный тест написан в сценариях bash. Получение токена Azure Active Directory OAuth2.0 с помощью bash-скрипта описано ниже.

clientSecret=$(az keyvault secret show --vault-name $(KEYVAULT_NAME) --name $(KVSECRET_NAME_AADCLIENT) --query value -o tsv)
authorizeUri="https://login.microsoftonline.com/${{ parameters.aadTenantId }}/oauth2/v2.0/token"
token=$(curl -X POST $authorizeUri -d "client_id=${{ parameters.aadAppidClient }}&grant_type=client_credentials&scope=api://${{ parameters.aadAppidBackend }}/.default&client_secret=$clientSecret" | jq ".access_token" | tr -d ")
Вход в полноэкранный режим Выйти из полноэкранного режима

Шаг 2. private-endpoints.yml развертывает ресурсы Azure, связанные с частными конечными точками с main2.bicep. Все диапазоны IP-адресов виртуальных сетей определены в файле main.parameters.json.

Шаг 3. restart-appgateway.yml перезапускает Application Gateway. Он должен быть выполнен по той же причине, что и V-net pipeline 1, поскольку добавляются частные записи DNS A для Key Vault, App Service, SQL Database, Funtions и Service Bus.

Шаг 4. integration-test-bash.yml выполняет интеграционные тесты после установки частных конечных точек. Этот шаг позволяет убедиться, что все конфигурации частных конечных точек развернуты правильно.

Шаг 5. func.yml — тот же, что используется в конвейере Base, но на этот раз выполняется на self-hosted агенте. Функции больше не доступен публичный IP, и она должна быть подключена через частный IP внутри виртуальной сети.

Шаг 6. webapi.yml такой же, как и в Base pipeline, но на этот раз выполняется на self-hosted агенте. Служба App Service больше не имеет доступного публичного IP, и она должна быть подключена через частный IP внутри виртуальной сети.

Шаг 7. integration-test-bash.yml выполняет интеграционные тесты, чтобы убедиться, что развертывание кода в App Service и Funtions правильно выполнено через self-hosted агента.

Оцените статью
devanswers.ru
Добавить комментарий