azure-devops - 在 YAML 部署作业中部署后检查应用程序运行状况端点的最佳方法?

标签 azure-devops azure-pipelines

在你大喊“盖茨!”之前请阅读。

我有本地 IIS 服务器场,我为每个服务器场(开发、测试、生产)创建了一个 VM 环境。在我所有的应用程序中,我都有一个像这样的 CD YAML:

- stage: Deploy_Test
  jobs:
  - deployment: APIDeployTestIISFarm
    displayName: Deploy API to Test IIS
    environment:
      name: Test
      resourceType: VirtualMachine
    strategy:
      runOnce:
        deploy:
          steps:

因为我有 20 个不同的应用程序都针对相同的环境,所以我无法使用 gates 功能。并非所有应用都具有完全相同的 /health 端点。

我目前正在制作一个 powershell 命令来简单地调用/health 并且如果“不健康”可能会抛出结果。尽管与仅检查 200 的 HTTP 门相比,这对我来说听起来非常丑陋,但我敢打赌它也具有容错/弹性。毕竟,IIS 站点在部署后需要一秒钟的时间才能在第一次点击时启动。

对我尚未见过的其他想法或任务持开放态度。

最佳答案

我的解决方案是创建一个容错的 PowerShell 脚本来 ping 健康端点。我更进一步并将其包装在一个模板中,该模板可以插入到您的主 CI/CD 模板中。这样做让我可以使用我选择的 IDE (VSCode) 单独开发和测试 PS 脚本,还可以借助模板将其作为标准任务重新使用,或者在 Azure Pipelines 之外使用它。

脚本

脚本注释:脚本最终通过Write-Error 结合 failOnStderr: true 来决定任务是否失败 PowerShell@2 任务我们稍后会看到。

## Base code borrowed from https://karask.com/retry-powershell-invoke-webrequest/
## Slightly modified to remove things like the file logging.

param (
    [string]$URI,
    [string]$Method = 'GET',
    [string]$SuccessTextContent = 'Healthy',
    [string]$Retries = 1,
    [string]$SecondsDelay = 2,
    [string]$TimeoutSec = 120
)

Write-Output "$Method ""$URI"" Retries: $Retries, SecondsDelay $SecondsDelay, TimeoutSec $TimeoutSec";

Function Req {
    Param(
        [Parameter(Mandatory=$True)]
        [hashtable]$Params,
        [int]$Retries = 1,
        [int]$SecondsDelay = 2
    )

    $Params.Add('UserAgent', 'azagent powershell task')

    $method = $Params['Method']
    $url = $Params['Uri']

    $cmd = { Write-Host "$method $url..." -NoNewline; Invoke-WebRequest @Params }

    $retryCount = 0
    $completed = $false
    $response = $null

    while (-not $completed) {
        try {
            $response = Invoke-Command $cmd -ArgumentList $Params
            if ($response.StatusCode -ne 200) {
                throw "Expecting reponse code 200, was: $($response.StatusCode)"
            }
            $completed = $true
        } catch {
            Write-Output "$(Get-Date -Format G): Request to $url failed. $_"
            if ($retrycount -ge $Retries) {
                Write-Error "Request to $url failed the maximum number of $retryCount times."
                throw
            } else {
                Write-Warning "Request to $url failed. Retrying in $SecondsDelay seconds."
                Start-Sleep $SecondsDelay
                $retrycount++
            }
        }
    }

    Write-Host "OK ($($response.StatusCode))"
    return $response
}

$res = Req -Retries $Retries -SecondsDelay $SecondsDelay -Params @{ 'Method'=$Method;'Uri'=$URI;'TimeoutSec'=$TimeoutSec;'UseBasicParsing'=$true }

if($res.Content -ne "$SuccessTextContent")
{
    Write-Error $response.Content
}
else
{
    Write-Host "Helath check validation success."
}

模板

模板注意事项:此任务有一个很容易被忽略的微妙细节。 -结帐:模板。这实际上将 check out 在插入此模板的模板中定义的存储库资源。这似乎很明显,因为插入了模板,然后一旦完成,它就会像一个 yaml 一样执行。

parameters:
  - name: URI
    type: string
  - name: Method
    type: string
    default: 'GET'
  - name: SuccessTextContent
    type: string
    default: 'Healthy'
  - name: Retries
    type: number
    default: 5
  - name: SecondsDelay
    type: number
    default: 2
  - name: TimeoutSec
    type: number
    default: 120

steps:
  - checkout: templates
  - task: PowerShell@2
    displayName: '${{ parameters.Method }} ${{ parameters.URI }}...'    
    inputs:
      failOnStderr: true
      targetType: 'filePath'
      filePath: $(System.DefaultWorkingDirectory)\InvokeRequestWithRetry.ps1
      arguments: > # Use this to avoid newline characters in multi-line string
        -URI "${{ parameters.URI }}"
        -Method "${{ parameters.Method }}"
        -SuccessTextContent "${{ parameters.SuccessTextContent }}"
        -Retries ${{ parameters.Retries }}
        -SecondsDelay ${{ parameters.SecondsDelay }}
        -TimeoutSec ${{ parameters.TimeoutSec }}

父 CI/CD YAML

Parent YAML 注释: 最后,我们有用法。我选择将其作为自己的专用部署作业,这样我可以在一切失败时手动单击重试,而不必重新运行整个部署。此外,我希望 PS 在我的防火墙后面的 VM 环境中运行。

resources:
  repositories:
    - repository: templates
      type: git
      name: IAMM/azure-pipelines-templates
      ref: refs/tags/v0.4

## ...
## Removed for brevity
## ...

- deployment: MyAppHealthDevIIS
  dependsOn: MyAppDeployDevIIS
  displayName: 'Hit /health/views endpoint before proceeding'
  environment:
    name: Development
    resourceType: VirtualMachine
  strategy:
    runOnce:
      deploy:
        steps:
        - template: templates/health-check.yaml@templates
          parameters:
            URI: 'https://$(iisHostName)/$(iisTargetApplication)/health/views'
            SecondsDelay: 5

关于azure-devops - 在 YAML 部署作业中部署后检查应用程序运行状况端点的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62938424/

相关文章:

Azure 文件复制任务在 VSTS 构建中失败

azure-devops - 使用 AppCmd "IIS Web App Manage"在 "Not enough storage is available to process this command."步骤上进行 VSTS 发布错误

azure - Azure Devops Pipelines 中的循环和数组

azure-devops - 无法在 Azure DevOps 的 "Code Coverage"选项卡中呈现代码覆盖率 HTML 结果

xamarin - 在 Azure DevOps 微软托管构建服务器上安装新版本的依赖项

maven - 在托管池中找不到满足指定要求的代理 : svn maven

Azure DevOps - 从传入电子邮件创建工作项

azure-devops - 从 VSTS 任务组中删除不必要的参数

Azure DevOps管道: read parameter values from a yaml and formulate a checklist

Azure 管道不会从具有单个 azure-pipelines.yml 文件的分支触发