Два идентичных развертывания Azure; всегда выдает 404 - как узнать в чем разница?

Я развертываю веб-службу C# ASP.NET Core в Azure с помощью Pulumi. Я могу развернуть его тремя способами:

  1. Запустите его локально из Visual Studio, т. е. вообще не используя Azure.
  2. Разверните его в Azure с моего локального компьютера разработчика.
  3. Разверните его в Azure из Jenkins (который работает на другом компьютере).

У меня есть проблема:

  1. Когда я запускаю его локально, я могу вызвать службу нормально, например. из Postman или из приложения C#. Веб-служба возвращает то, что я ожидаю.
  2. Когда я развертываю его в Azure со своего локального компьютера, я также могу сказать, что все в порядке. Веб-служба возвращает то, что я ожидаю.
  3. Когда я развертываю его в Azure из Jenkins, а затем пытаюсь вызвать веб-сервис, он возвращает NotFound на все вызовы, независимо от того, что я делаю. (Предположительно это означает HTTP 404.)

Развертывания во 2 и 3 должны быть точно такими же. Мой вопрос: Как узнать, в чем разница между этими двумя развертываниями в Azure?

Развернутый Jenkins веб-сервис демонстрирует следующее любопытное поведение:

  • Он не регистрирует никаких исключений (даже когда я жду их появления несколько минут).
  • Если я зайду в свою группу ресурсов -> Application Insights -> Журналы и найду запросы, там будут запросы. Любопытно, что он говорит, что возвращает HTTP 200 на все запросы, хотя я получаю при их вызове 404.
  • Вышеприведенное верно даже для вызовов веб-служб, которые никогда не должны возвращать 200 (они должны возвращать 201).
  • Вышеупомянутое верно даже для вызовов веб-службы к методам, которые даже не должны существовать (т. Е. Когда я преднамеренно искажаю URI метода перед вызовом службы).

Во время развертывания я аутентифицируюсь в Azure, используя субъект-службу. Мой Jenkinsfile выглядит так:

withVaultSecrets([                                    
    "path/to/secret/in/vault": [
        "sp_name", "application_id", "object_id", "sp_secret"
    ]
]){
    script {
        env.PULUMI_CONFIG_PASSPHRASE = 'jenkinspassphrase'
        env.ARM_CLIENT_ID = "${application_id}"
        env.ARM_CLIENT_SECRET = "${sp_secret}"
        env.ARM_TENANT_ID = "${azure_dev_tenant_id}"
        env.ARM_SUBSCRIPTION_ID = "${azure_dev_subscription_id}"
        env.AZURE_CLIENT_ID = "${application_id}"
        env.AZURE_CLIENT_SECRET = "${sp_secret}"
        env.AZURE_TENANT_ID = "${azure_dev_tenant_id}"
    }//script
    dir("./src/deploy/KmsStack"){
        powershell "pulumi login --local";
        powershell "pulumi stack init jenkinsfunctionaltest --secrets-provider=passphrase"
        powershell "pulumi up --yes"
    }//dir
}//withVaultSecrets

Сценарий, который я использую для локального развертывания, выглядит следующим образом с теми же учетными данными субъекта-службы:

cd $PSScriptRoot
cd webapi
dotnet publish /p:DisableGitVersionTask=true
cd ../deploy/KmsStack
$env:PULUMI_CONFIG_PASSPHRASE = 'jenkinspassphrase'
$env:ARM_CLIENT_ID = ...
$env:ARM_CLIENT_SECRET = ...
$env:ARM_TENANT_ID = ...
$env:ARM_SUBSCRIPTION_ID = ...
$env:AZURE_CLIENT_ID = ...
$env:AZURE_CLIENT_SECRET = ...
$env:AZURE_TENANT_ID = ...
pulumi logout
pulumi login --local
pulumi stack rm jenkinsfunctionaltest -y
pulumi stack init jenkinsfunctionaltest --secrets-provider=passphrase
pulumi stack select jenkinsfunctionaltest
pulumi up --yes

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

Заранее спасибо!


person Claus Appel    schedule 23.02.2021    source источник
comment
Любопытно, что он вернул HTTP 200, что звучит как проблема с сетью, а не с лазурью. Вы проверили свой брандмауэр?   -  person Liam    schedule 23.02.2021
comment
Во-первых, он не должен возвращать 200. Во всяком случае, он должен возвращать 201, поэтому сервер определенно ведет себя неправильно. Во-вторых, я не понимаю, как это может быть проблемой брандмауэра. Они работают на kmsappxxxxxxxx.azurewebsites.net и kmsappyyyyyyyy.azurewebsites.net (новые при каждом развертывании новой версии). Мой брандмауэр не может обрабатывать их по-разному.   -  person Claus Appel    schedule 23.02.2021
comment
Одна из возможностей заключается в том, что Azure требует HTTPS (безопасный), в то время как другой сервер примет незащищенный. Таким образом, не найдено указывает на то, что уровень безопасности не разрешает доступ к файлу.   -  person jdweng    schedule 23.02.2021
comment
Я использую https для доступа к ним обоим.   -  person Claus Appel    schedule 23.02.2021
comment
Мой брандмауэр не может обрабатывать их по-другому Мой рабочий брандмауэр автоматически блокирует любые неизвестные URL-адреса в течение определенного периода времени. Так это именно то, что он делает   -  person Liam    schedule 23.02.2021
comment
NotFound может быть вызван рядом причин, например, отсутствием секретного элемента kv, я бы получил конфигурацию службы приложений в блокноте как для развертывания, так и для сравнения, где какое-либо значение отличается. Когда вы развернули форму Jenkins, использовали ли вы тот же метод для публикации и развертывания пакета dotnet?   -  person Sujit Singh    schedule 23.02.2021
comment
Я использовал один и тот же dotnet publish для обоих, да. Как получить конфигурацию службы приложений в формате, который может прочитать Блокнот?   -  person Claus Appel    schedule 24.02.2021


Ответы (1)


Мы выяснили, что было не так. Это не проблема Azure. Проблема заключалась в том, что мы развертывали неверный ZIP-файл. В ZIP-файле отсутствовал web.config, что означало, что веб-приложение не могло запуститься.

Мы заархивировали наше опубликованное веб-приложение, имея это в файле CSPROJ:

<Target Name="ZipOutputPath" AfterTargets="Publish">
  <ZipDirectory SourceDirectory="$(OutputPath)\publish" DestinationFile="$(MSBuildProjectDirectory)\kmswebapp.zip" Overwrite="true" />
</Target>

Оказалось, что это не сработало, потому что компилятор делает что-то в другом порядке, чем мы ожидали. В то время, когда был сгенерирован ZIP-файл, web.config еще не был сгенерирован, поэтому web.config так и не был упакован в ZIP-файл. Следовательно, Azure не удалось запустить приложение.

Когда мы выполняли развертывание с наших локальных компьютеров, это работало, потому что мы не очищали каталог публикации перед каждым запуском, поэтому оставался web.config, оставшийся от предыдущего запуска, и этот старый (но без изменений) web.config будет упакован в ZIP-файл и развернут в Azure, поэтому Azure будет знать, как запустить приложение.

Мы решили эту проблему, удалив вышеуказанное из нашего файла CSPROJ и сделав (примерно) это в нашем файле Jenkins:

powershell "dotnet publish ./src/webapi/WebAPI.csproj"
powershell "if (!(Test-Path('${publishDirectoryPath}/web.config'))){throw 'We need web.config to exist in the publish directory'}"
powershell "Compress-Archive -Path '${publishDirectoryPath}/*' -DestinationPath './src/webapi/kmswebapp.zip' -Force"

Это создает правильный ZIP-файл, включая web.config, и теперь Azure может запустить наше приложение, чтобы оно могло правильно отвечать на запросы.

person Claus Appel    schedule 25.02.2021