我的ARM模板太大了,所以我想使用链接模板。我知道模板需要在一个可以方便ARM访问的地方。但在上传到目标位置之前,我应该可以测试它们。否则,我可能会用无效的模板覆盖以前的工作模板。那我该怎么恢复呢?
你是怎么做到的?
发布于 2020-01-24 11:48:51
所以我想出了这个剧本。每个开发人员都预先创建了资源组,他将在其中部署资源和预创建Blob容器,以存储当前正在开发的模板。在部署模板之前,我使用azcopy将本地文件夹与Blob容器同步。不幸的是,有时Test-AzResourceGroupDeployment在失败时没有给出足够的细节,所以我无法根据它的返回值来决定是否执行部署。就目前而言,这似乎还不错。但它已经是第三或第四版本,它很可能会改变在未来。一个想法是将ARM-TTK集成到模板测试中。
$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
}发布于 2020-01-11 19:52:09
这是对我有用的东西。我有一个管道,部署从Azure Devops模板。管道将其部署到dev环境中,因此破坏某些东西并不是世界末日。您还可以在本地进行测试,然后再转到回购系统(如果这是一个选项(在某些情况下,模板对“真实”开发环境中的内容有大量依赖,在其他订阅上测试它是不可能的,因为对现有资源\key库的引用\等等)。我正在使用azure中的以下代码片段来运行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) }}让我稍微解释一下这里发生的事情:
Version --意思是最后成功部署的版本;FailedVersion --这实际上意味着最后一次部署失败,它包含启动部署的构建id (这将在成功部署后删除);InProgress --包含开始部署到资源组的构建id;这将在部署结束后(无论是否失败)重置,因此在构建运行时它只有一个值。InProgress标记的值,检查是否已经在此资源组上运行部署。如果该值与not running匹配(或任何用于测试作业的生成id的- it sets theInProgress`‘标记的字符串),否则-使用非零退出代码退出脚本,从而有效地破坏构建(从而防止冲突)。现在让我们来谈谈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函数的相同输入,它总是相同的,这意味着当您从同一个提交到同一个资源组运行构建时,它总是上载到同一个容器,但是如果您为另一个提交或另一个资源组运行它,它将生成一个新的容器名称),从而避免了您正在讨论的冲突。前面提到的标记给出了build id,它使用GitVersion映射到特定的提交(因此您总是可以知道部署到特定环境的代码版本\或部署失败)。并输出生成的容器名称,这样AzureResourceGroupDeployment@2就能够计算出并使用特定的容器来查找模板。
还有其他构建步骤,它们控制失败\成功标记,清理旧版本\旧容器。如果您需要我的具体实现,我可能会把它变成博客文章。
从本质上讲,这一切归结为:
这可能不是最佳的方法,但这是我能想到的最好的时候,我需要它。
ps。对于本地测试,您可以只使用Update-Prereq函数,因为您不需要所有的检查,只需要模板的唯一url
https://stackoverflow.com/questions/59697821
复制相似问题