首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何测试链接的ARM模板?

问如何测试链接的ARM模板?
EN

Stack Overflow用户
提问于 2020-01-11 19:16:57
回答 2查看 529关注 0票数 1

我的ARM模板太大了,所以我想使用链接模板。我知道模板需要在一个可以方便ARM访问的地方。但在上传到目标位置之前,我应该可以测试它们。否则,我可能会用无效的模板覆盖以前的工作模板。那我该怎么恢复呢?

你是怎么做到的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-24 11:48:51

所以我想出了这个剧本。每个开发人员都预先创建了资源组,他将在其中部署资源和预创建Blob容器,以存储当前正在开发的模板。在部署模板之前,我使用azcopy将本地文件夹与Blob容器同步。不幸的是,有时Test-AzResourceGroupDeployment在失败时没有给出足够的细节,所以我无法根据它的返回值来决定是否执行部署。就目前而言,这似乎还不错。但它已经是第三或第四版本,它很可能会改变在未来。一个想法是将ARM-TTK集成到模板测试中。

代码语言:javascript
复制
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$resourceGroup = $currentUser.Substring($currentUser.IndexOf('\') + 1) + "-testing"
$containerName = $currentUser.Substring($currentUser.IndexOf('\') + 1) + "-testing"
$storageAccountName = "team_shared_account_here";
$containerUrl = "https://${storageAccountName}.blob.core.windows.net/${containerName}"

Write-Host "Current user: <${currentUser}>" -ForegroundColor Green
Write-Host "Deployment will use templates from <${containerName}> container" -ForegroundColor Green
Write-Host "Resources will be deployed to <${resourceGroup}> resource group" -ForegroundColor Green
Write-Host

Write-Host "Syncing templates..." -ForegroundColor Green
.\azcopy.exe sync '.' $containerUrl --include-pattern "*.json" --delete-destination true

$toDeploy = "app1", "app2"
foreach ($template in $toDeploy) {
    $templateUri = "${containerUrl}/${template}.json"
    $templateParameterUri = "${containerUrl}/${template}.parameters.DEV.json"

    Write-Host "`nDeploying:  ${templateUri}" -ForegroundColor Green
    Write-Host "Paramaters: ${templateParameterUri}" -ForegroundColor Green

    Test-AzResourceGroupDeployment -ResourceGroupName $resourceGroup `
        -TemplateUri $templateUri `
        -TemplateParameterUri $templateParameterUri `
        -Mode Incremental `
        -Verbose

    New-AzResourceGroupDeployment -ResourceGroupName $resourceGroup `
        -TemplateUri $templateUri `
        -TemplateParameterUri $templateParameterUri `
        -Mode Incremental `
        -DeploymentDebugLogLevel All `
        -Verbose
}
票数 0
EN

Stack Overflow用户

发布于 2020-01-11 19:52:09

这是对我有用的东西。我有一个管道,部署从Azure Devops模板。管道将其部署到dev环境中,因此破坏某些东西并不是世界末日。您还可以在本地进行测试,然后再转到回购系统(如果这是一个选项(在某些情况下,模板对“真实”开发环境中的内容有大量依赖,在其他订阅上测试它是不可能的,因为对现有资源\key库的引用\等等)。我正在使用azure中的以下代码片段来运行powershell脚本,然后运行部署:

代码语言:javascript
复制
- 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匹配(或任何用于测试作业的生成id的- it sets theInProgress`‘标记的字符串),否则-使用非零退出代码退出脚本,从而有效地破坏构建(从而防止冲突)。
  4. 部署应该是显而易见的

现在让我们来谈谈Update-Prereq,因为所有这些都是必不可少的。它通过执行以下操作为每个构建生成一个随机容器名:

代码语言:javascript
复制
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函数的相同输入,它总是相同的,这意味着当您从同一个提交到同一个资源组运行构建时,它总是上载到同一个容器,但是如果您为另一个提交或另一个资源组运行它,它将生成一个新的容器名称),从而避免了您正在讨论的冲突。前面提到的标记给出了build id,它使用GitVersion映射到特定的提交(因此您总是可以知道部署到特定环境的代码版本\或部署失败)。并输出生成的容器名称,这样AzureResourceGroupDeployment@2就能够计算出并使用特定的容器来查找模板。

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

从本质上讲,这一切归结为:

  1. 防止并行执行
  2. 为每个资源组\commit组合拥有一组单独的模板,这样它们就不会重叠
  3. 能够分辨部署到环境中的构建。
  4. 能够在没有太大麻烦的情况下将其回溯到提交id。

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

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59697821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档