Другое

Исправление ошибки Bicep в Azure Developer CLI в конвейерах

Исправление ошибок проверки Bicep в Azure Developer CLI при развертывании проектов .NET Aspire в конвейерах. Узнайте, почему порт 5001 не работает и как правильно настроить конечные точки HTTPS для Azure Container Apps.

Почему Azure Developer CLI сообщает об ошибке недопустимого Bicep для моего проекта .NET Aspire при запуске в конвейерах?

Я столкнулся с проблемой Azure Developer CLI при развертывании моего проекта .NET Aspire через Azure DevOps Pipelines. Конвейер завершается ошибкой на этапе “Generate infrastructure bicep” (Генерация инфраструктуры Bicep) со следующим сообщением об ошибке:

ERROR: generating infra/ folder: configuring ingress for resource eriksens-api: Binding https can't be mapped to main ingress because it has port 5001 defined. main ingress only supports port 443 for https scheme.

Описание проблемы

Моя цель - запускать конвейер при возникновении триггера, генерировать инфраструктуру, развертывать ее, развертывать приложения в моем проекте .NET Aspire в Azure Container Apps (ACA) и настраивать внешний ingress.

Я сталкиваюсь с тремя разными сценариями:

  1. Конвейер завершается ошибкой на этапе “Generate infrastructure bicep”
  2. Конвейер успешно выполняется, но ingress настроен как внутренний
  3. Конвейер успешно выполняется с внешним ingress, но API не может найти HTTPS-сертификат

Детали конфигурации

Конфигурация AppHost program.cs

csharp
var externalApi = builder.AddProject<Projects.Eriksens_Api_EriksenExternal>(ServiceNames.EriksensExternalApiServiceName)
    .WithExternalHttpEndpoints()
    .AddCustomEnvironmentVariables();

// В нелокальных средах:
externalApi
    .WithHttpsEndpoint(port: 5001, targetPort: 8080)
    .WithExternalHttpEndpoints();

Конфигурация конвейера

Конвейер использует Azure Developer CLI (azd) версии 1.20.3 и включает следующие ключевые этапы:

  • Установка azd
  • Настройка аутентификации
  • Генерация инфраструктуры Bicep (где возникает ошибка)
  • Развертывание инфраструктуры
  • Развертывание приложения

Наблюдаемое поведение

  • При локальном запуске azd infra gen работает без проблем
  • При запуске в конвейерах возникает ошибка с портом 5001
  • Если я меняю порт на 443, как предлагает сообщение об ошибке, приложение не может найти сертификат
  • Если я удаляю конфигурацию WithHttpsEndpoint, оно развертывается, но с внутренним ingress

Вопрос

Что вызывает у Azure Developer CLI сообщение об ошибке недопустимого Bicep при использовании порта 5001 для HTTPS-эндпоинтов в средах конвейеров, и как я могу настроить мой проект .NET Aspire для корректной работы с внешним ingress и HTTPS в Azure DevOps Pipelines?

Azure Developer CLI сообщает об недопустимом Bicep для вашего проекта .NET Aspire в конвейерах, поскольку вход в Azure Container Apps поддерживает только порт 443 для HTTPS-трафика, но ваша конфигурация использует порт 5001. Это ограничение применяется при генерации Bicep в средах конвейеров, где проверка строже, чем при локальной разработке.

Содержание

Понимание основной причины

Основная проблема связана с архитектурой входа (ingress) Azure Container Apps (ACA). Как объясняется в документации Microsoft Learn, “ваш конечный точка входа приложения всегда доступна на порту 443”. Это фундаментальное ограничение платформы Azure - HTTPS-трафик должен завершаться на порту 443 на уровне балансировщика нагрузки.

Когда ваша конфигурация .NET Aspire указывает WithHttpsEndpoint(port: 5001, targetPort: 8080), Azure Developer CLI пытается сгенерировать Bicep, который отображает HTTPS-трафик с порта 5001 на целевой порт вашего приложения 8080. Однако вход Azure Container Apps не поддерживает пользовательские HTTPS-порты - он принимает трафик только на порту 443 и перенаправляет его на указанный вами целевой порт.

Почему порт 5001 не работает в конвейерах

Поведение различается между локальной разработкой и средами конвейеров из-за контекстов проверки:

  • Локальная разработка: azd infra gen может быть более допускающим при локальном тестировании
  • Среды конвейеров: Azure Developer CLI выполняет более строгую проверку, чтобы убедиться, что развертывание будет успешным в Azure

Как показано в обсуждении на Stack Overflow, когда пользователи пытаются использовать порт 5001, они получают именно ту ошибку, с которой вы столкнулись: “Привязка https не может быть сопоставлена с основным входом, так как для него определен порт 5001. Основной вход поддерживает только порт 443 для схемы https.”


Подходы к решению

Вариант 1: Использование порта 443 с правильной конфигурацией

Наиболее прямое решение - изменить конфигурацию для использования порта 443:

csharp
externalApi
    .WithHttpsEndpoint(port: 443, targetPort: 8080)
    .WithExternalHttpEndpoints();

Однако, как вы обнаружили, это может привести к проблемам с сертификатами, поскольку Azure автоматически управляет сертификатами для порта 443, и вашему приложению необходимо быть настроенным на доверие к управляемому Azure сертификату.

Вариант 2: Настройка внешнего входа в Bicep

Вручную настройте вход как внешний и позвольте Azure обрабатывать завершение HTTPS:

bicep
resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
  name: appName
  location: location
  properties: {
    configuration: {
      ingress: {
        external: true
        targetPort: 8080
        allowInsecure: false // Обеспечить только HTTPS
      }
    }
    template: {
      containers: [{
        name: containerName
        image: image
      }]
    }
  }
}

Вариант 3: Конфигурация, зависящая от среды

Используйте разные конфигурации для локальных и сред развертывания:

csharp
// В Program.cs
if (builder.Environment.IsProduction())
{
    externalApi
        .WithHttpsEndpoint(port: 443, targetPort: 8080)
        .WithExternalHttpEndpoints();
}
else
{
    // Конфигурация для локальной разработки
    externalApi
        .WithHttpsEndpoint(port: 5001, targetPort: 8080)
        .WithExternalHttpEndpoints();
}

Рекомендуемая конфигурация

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

1. Обновление конфигурации Aspire

csharp
var externalApi = builder.AddProject<Projects.Eriksens_Api_EriksenExternal>(ServiceNames.EriksensExternalApiServiceName)
    .WithExternalHttpEndpoints()
    .AddCustomEnvironmentVariables();

// Конфигурация для развертывания в Azure
externalApi
    .WithHttpsEndpoint(port: 443, targetPort: 8080)
    .WithExternalHttpEndpoints();

2. Настройка доверия к сертификатам

Измените ваше приложение, чтобы оно доверяло управляемым Azure сертификатам, добавив в Program.cs:

csharp
// Для Azure Container Apps
if (builder.Environment.IsProduction())
{
    builder.Services.Configure<HttpsConnectionFilterOptions>(options =>
    {
        options.AllowedServerCertificates.Add(new X509Certificate2());
    });
}

3. Обновление конфигурации конвейера

Убедитесь, что ваш конвейер использует правильную версию azd и аутентификацию:

yaml
 steps:
 - task: AzureCLI@2
   inputs:
     azureSubscription: 'your-connection'
     scriptType: 'pscore'
     scriptLocation: 'inlineScript'
     inlineScript: |
       azd auth login --use-device-code
       azd pipeline provision --no-prompt

Особенности конвейеров

Проблемы аутентификации

Как отмечено в проблеме на GitHub, аутентификация в конвейерах может быть проблематичной. Убедитесь, что ваш конвейер правильно аутентифицируется с Azure:

yaml
- task: AzureKeyVault@2
  inputs:
    azureSubscription: 'your-connection'
    KeyVaultName: 'your-keyvault'
    SecretsFilter: '*'

Генерация Bicep

Ошибка возникает во время azd infra gen, который проверяет сгенерированный Bicep на соответствие ограничениям Azure. Рассмотрите возможность добавления конфигурации, специфичной для конвейера:

yaml
- script: |
    azd config set defaults.location eastus
    azd config set defaults.resourceGroup your-resource-group
    azd infra gen

Управление сертификатами

При использовании порта 443 Azure автоматически предоставляет и управляет TLS-сертификатами для ваших Container Apps. Однако вашему приложению необходимо быть настроенным на:

  1. Доверие к управляемому Azure сертификату
  2. Правильную обработку перенаправления HTTPS

Добавьте это в запуск вашего приложения:

csharp
// Program.cs
if (builder.Environment.IsProduction())
{
    app.UseHsts();
    app.UseHttpsRedirection();
    
    // Настройка доверия к управляемым Azure сертификатам
    builder.Services.AddHttpClient()
        .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
        {
            ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
        });
}

Альтернативные подходы

Использование Azure Front Door

Для более сложных сценариев рассмотрите возможность использования Azure Front Door для обработки завершения HTTPS и маршрутизации трафика к вашим Container Apps:

  1. Создайте экземпляр Azure Front Door
  2. Настройте пул бэкендов, указывающий на ваши Container Apps
  3. Настройте правила маршрутизации для обработки HTTPS-трафика
  4. Обновите конфигурацию Aspire для использования внутренних конечных точек

Переопределение шаблона Bicep вручную

Вы можете переопределить сгенерированный шаблон Bicep, создав пользовательский шаблон в папке infra:

bicep
// infra/override/main.bicep
@override('Microsoft.App/containerApps@2023-05-01')
resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
  // Ваша пользовательская конфигурация
  properties: {
    configuration: {
      ingress: {
        external: true
        targetPort: 8080
        transport: 'http'
        allowInsecure: false
      }
    }
  }
}

Заключение

Azure Developer CLI сообщает об недопустимом Bicep, потому что вход Azure Container Apps поддерживает только порт 443 для HTTPS-трафика. Чтобы решить эту проблему:

  1. Обновите конфигурацию Aspire для использования порта 443 для HTTPS-конечных точек
  2. Настройте доверие к сертификатам в вашем приложении для работы с управляемыми Azure сертификатами
  3. Используйте конфигурации, зависящие от среды для обработки различий между локальной и производственной средами
  4. Обеспечьте правильную аутентификацию конвейера и конфигурацию

Ключевой вывод заключается в том, что у Azure Container Apps есть строгие требования к входу, которые отличаются от сред локальной разработки. Согласовав вашу конфигурацию с этими ограничениями и правильно управляя сертификатами, вы можете успешно развертывать проекты .NET Aspire с внешним HTTPS-доступом через Azure DevOps Pipelines.

Источники

  1. Stack Overflow - Ошибка проверки Bicep Azure Developer CLI
  2. Microsoft Learn - Настройка входа для Azure Container Apps
  3. Microsoft Learn - Настройка развертываний .NET Aspire в Azure
  4. Проблема на GitHub - Проблемы CI/CD конвейера .NET Aspire Azure
  5. Microsoft Learn - Развертывание .NET Aspire с помощью Azure Developer CLI
Авторы
Проверено модерацией
Модерация