azure - 如何测试链接的ARM模板?

标签 azure azure-devops azure-resource-manager azure-rm-template

我的 ARM 模板变得太大,所以我想使用链接模板。我知道模板需要位于 ARM 可以访问的地方。但在将它们上传到目标位置之前,我应该能够以某种方式测试它们。否则,我可能会用无效的模板覆盖以前工作的模板。那我该如何恢复呢?

你是怎么做到的?

最佳答案

这对我有用。我有一个从 Azure Devops 存储库部署模板的管道。管道将其部署到开发环境,因此破坏某些东西并不是世界末日。您还可以在推送到存储库之前进行本地测试(如果这是一个选项)(在某些情况下可能真的很难做到,其中模板对“真实”开发环境中的内容有很多依赖项,并且在其他订阅上测试它是由于引用现有资源\ keystore \等,这是不可能的)。我在 azure devops 中使用以下代码片段来运行 powershell 脚本,然后进行部署:

- task: AzurePowerShell@3
  displayName: UpdatePrereq
  inputs:
    azureSubscription: ${{ parameters.azureSubscription }}
    ScriptType: InlineScript
    Inline: |
        ${{ format('. $(Build.Repository.LocalPath)\scripts\_helpers.ps1
        Update-DeploymentPrereq -resourceGroup {1} -location {3}
        Update-Prereq -pathSuffix {0} -pathBase $(Build.Repository.LocalPath) -resourceGroup {1} -buildId $(Build.BuildNumber) -paramFile {2}
        Update-DeploymentConcurrency -resourceGroup {1} -buildId $(Build.BuildNumber)',
            parameters.buildDir, parameters.resourceGroupName, parameters.paramFile, parameters.location ) }}
    azurePowerShellVersion: LatestVersion

- task: AzureResourceGroupDeployment@2
  displayName: DeploySolution
  inputs:
    azureSubscription: ${{ parameters.azureSubscription }}
    resourceGroupName: ${{ parameters.resourceGroupName }}
    location: ${{ parameters.location }}
    templateLocation: 'URL of the file'
    csmFileLink: "https://xxx.blob.core.windows.net/$(containerName)/azuredeploy.json"
    csmParametersFileLink: ${{ format('https://xxx.blob.core.windows.net/$(containerName)/param.{0}.json', parameters.paramFile) }}

让我解释一下这里发生的事情:

  1. Update-DeploymentPrereq - 用于检查目标资源组是否存在并设置了正确的标签。如果不是,则创建并标记它。标签是:Version - 表示最后成功部署的版本; FailedVersion - 这实际上意味着上次部署失败,并且它包含启动部署的构建 ID(成功部署后将被删除); InProgress - 包含开始部署到资源组的构建的构建 ID;这将在部署结束后重置(无论是否失败),因此它仅在构建运行时才具有值。
  2. Update-Prereq - 将所有模板\工件上传到专用存储帐户(稍后详细介绍)
  3. Update-DeploymentConcurrency - 通过检查 InProgress 的值来检查此资源组上是否已运行部署。标签。如果该值匹配 not running (或者您编写的任何字符串来测试 - it sets the InProgress` 标记到作业的构建 ID,否则 - 以非零退出代码退出脚本,有效地破坏构建(从而防止冲突)。
  4. 部署应该显而易见

现在我们来谈谈 Update-Prereq因为这对于所有这一切的发挥都是至关重要的。它通过执行以下操作为每个构建生成一个随机容器名称:

Function Get-StringHash ([String]$String, $HashName = "MD5") {
    $StringBuilder = New-Object System.Text.StringBuilder
    [System.Security.Cryptography.HashAlgorithm]::Create($HashName).ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))|
        ForEach-Object { [Void]$StringBuilder.Append($_.ToString("x2"))
    }
    $StringBuilder.ToString().Substring(0, 24)
}

...

Function Update-Prereq {
    ... 
    $containerName = Get-StringHash ( $resourceGroup + $buildId )
    New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Blob
    Write-Host "##vso[task.setvariable variable=containerName]$containerName"
    ...
} 

这会产生一个 24 个字符长的确定性字符串(对于提供给 Get-StringHash 函数的相同输入,它始终是相同的,这意味着当您从同一资源组的同一提交运行构建时 - 它始终上传到同一个容器,但如果您为另一个提交或另一个资源组运行它 - 它会生成一个新的容器名称),从而避免您正在谈论的冲突。上述标签给出了构建 ID,它使用 GitVersion 映射到特定提交(因此您始终可以找出已部署\或未能部署到特定环境的代码版本)。它输出生成的容器名称,因此 AzureResourceGroupDeployment@2将能够弄清楚并使用该特定容器来查找模板。

还有其他构建步骤,可以控制失败\成功标记,清理旧构建\旧容器。如果您需要我的具体实现,我可能可以将其变成博客文章

本质上,这一切都归结为:

  1. 防止并行执行
  2. 为每个资源组/提交组合提供一组单独的模板,因此它们永远不会重叠
  3. 能够判断哪个版本部署到了环境
  4. 能够轻松地回溯到提交 ID。

这可能不是最佳方式,但这是我需要时能想到的最好方式。

ps。对于本地测试,您可以使用 Update-Prereq函数,因为您不需要所有检查,只需要模板的唯一 url

关于azure - 如何测试链接的ARM模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59697821/

相关文章:

c# - Azure函数: how to efficiently send batch of messages to Service Bus using bindings?

Azure CloudPageBlob Create - 如何实现 CreateIfNotExist

具有排除模式的 Azure CLI 存储删除批处理

azure-devops - 是否有用于发布标准桌面应用程序的 Azure Pipeline 工具?

powershell - 将 SSL 自动化任务添加到管道

azure-devops - 在releases/*中创建新分支时触发Azure管道

azure - 在 Azure 资源管理模板中创建 StorageV2 存储帐户

从 native 应用程序登录 Azure AD B2C - 要登录此应用程序,必须将帐户添加到目录中

azure - 如何在 Azure Arm 模板中使用粘性暂存槽

azure - 为使用 OnPrem 数据网关的 API 连接部署 ARM 模板成功,但缺少 authType 和网关参数