来自 Azure Git Repo 的带有 Powershell 文件的 Runbook 的 Azure ARM 模板
Azure ARM Template for runbook with Powershell file from Azure Git Repo
我们正在尝试使用定期查询 Log Analytics 的 Powershell 部署 runbook。我们在门户网站上使用它,现在我们正在尝试构建一个 ARM 模板,以便将来部署到其他环境。我们在同一个 Azure Devops Git 存储库中有我们的 ARM (json) 模板和 PS1 文件,我们甚至尝试在模板中硬编码 PS1 文件的路径但是它不起作用。有人可以在这里帮助我们了解我们做错了什么。以下是 ARM 模板:-
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"automationAccountName": {
"type": "string",
"defaultValue": "Automation-XXX-INFRA-MONITORING",
"metadata": {
"description": "Automation Account"
}
},
"automationRegion": {
"defaultValue": "eastus2",
"type": "string",
"allowedValues": [
"westeurope",
"southeastasia",
"eastus2",
"southcentralus",
"japaneast",
"northeurope",
"canadacentral",
"australiasoutheast",
"centralindia",
"westcentralus"
],
"metadata": {
"description": "Specify the region for your automation account"
}
},
"_artifactsLocation": {
"type": "string",
"defaultValue": "https://ABCD.visualstudio.com/3Pager/_git/Infrastructure?path=%2FAzure.Infra%2FAppInsights%2FMonthOverMonthTrendAnalysisReport.ps1&version=GBmaster",
"metadata": {
"description": "URI to artifacts location"
}
},
"_artifactsLocation1": {
"type": "string",
"defaultValue": "https://ABCD.visualstudio.com/3Pager/_git/Infrastructure?path=%2FAzure.Infra%2FAppInsights%2FMonthOverMonthTrendAnalysisReport.ps1&version=GBmaster",
"metadata": {
"description": "URI to artifacts location"
}
}
},
"variables": {
"asrScripts": {
"runbooks": [
{
"name": "Test_Runbook",
"url": "[parameters('_artifactsLocation')]",
"version": "1.0.0.0",
"type": "PowerShell",
"description": "Runbook for month over month trend analysis report"
}
]
}
},
"resources": [
{
"apiVersion": "2015-10-31",
"type": "Microsoft.Automation/automationAccounts/runbooks",
"name": "[concat(parameters('automationAccountName'), '/', variables('asrScripts').runbooks[copyIndex()].Name)]",
"location": "[parameters('automationRegion')]",
"copy": {
"name": "runbooksLoop",
"count": "[length(variables('asrScripts').runbooks)]"
},
"properties": {
"description": "[variables('asrScripts').runbooks[copyIndex()].description]",
"runbookType": "[variables('asrScripts').runbooks[copyIndex()].type]",
"logProgress": false,
"logVerbose": true,
"publishContentLink": {
"uri":"[parameters('_artifactsLocation1')]",
"version": "[variables('asrScripts').runbooks[copyIndex()].version]" }
}
}
],
"outputs": {}
}
您正在向 ARM 发送一个 URI,告诉它在哪里可以找到运行手册。创建 AutomationAccount/runbooks 资源类型后,它将对 publishContentLink.url 进行 GET 调用,以便从 URI 获取内容。如果 Azure 无法访问该 URI(可能是您的 visualstudio.com URI 无法 public 访问),那么它将无法访问 runbook 内容并且部署将失败。
解决方案是确保 publishContentLink URI 可供 Azure 自动化服务访问。您可以通过几种方式做到这一点:
- 将内容放入 public 可访问的 URI,例如 Github 或 public Blob 存储容器。
- 为内容创建 SAS 令牌。 https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-tutorial-secure-artifacts shows an example of how to do this with Azure Storage, or https://xebia.com/blog/setting-up-vsts-with-arm-templates/ 因为用 VSTS 做到了。
留在这里以防有人遇到类似问题。对于私有 Azure DevOps Repo,可以通过 Azure Function 使用 HTTP 触发器和以下 PowerShell 脚本来解决:
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Interact with query parameters or the body of the request.
$adouri = $Request.Query.adouri
$pat = $Request.Query.pat
if (!$adouri){
$response = "Please pass uri"
Write-Warning "URI not passed" -Warning
} elseif (!$pat){
$response = "Please pass pat"
Write-Warning "PAT not passed" -Warning
} else {
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $pat)))
$headers = @{
"Authorization" = ("Basic {0}" -f $base64AuthInfo)
}
$response = Invoke-RestMethod -Uri $adouri -Method Get -ContentType "application/text" -Headers $headers
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $response
})
一旦函数准备就绪,就可以直接从 ARM 模板调用它,例如:
"variables": {
"runbookUri": "https://[function name].azurewebsites.net/api/[trigger name]?adouri=https://dev.azure.com/[ADO Organization]/[ADO project]/_apis/git/repositories/[Repo]/items?path=%2F[folder]%2F[subfolder]%2Fscript.ps1&pat=[token]"
},
"resources": [
{
"type": "Microsoft.Automation/automationAccounts/runbooks",
"apiVersion": "2018-06-30",
"name": "[name]",
"location": "[location]"
"properties": {
"runbookType": "PowerShell",
"logVerbose": false,
"logProgress": false,
"logActivityTrace": 0,
"publishContentLink": {
"uri": "[variables('runbookUri')]"
}
}
}]
令牌只是来自 Azure DevOps 的个人访问令牌。为了确保它的安全,它可以从秘密 ADO 变量或 Azure KeyVault 传递到 ARM 模板。
我通过使用 Terraform 模板克服了这个限制。它们提供了使用本地路径将自定义内容发布到 Runbook 的可能性。因此,您可以直接从 Git 存储库文件系统(您的电脑)执行此操作,或者通过将 Azure Pipeline 链接到您的存储库并将该文件用作工件。
如果有兴趣,请查看“示例用法 - 自定义内容”中的 https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/automation_runbook。
我们正在尝试使用定期查询 Log Analytics 的 Powershell 部署 runbook。我们在门户网站上使用它,现在我们正在尝试构建一个 ARM 模板,以便将来部署到其他环境。我们在同一个 Azure Devops Git 存储库中有我们的 ARM (json) 模板和 PS1 文件,我们甚至尝试在模板中硬编码 PS1 文件的路径但是它不起作用。有人可以在这里帮助我们了解我们做错了什么。以下是 ARM 模板:-
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"automationAccountName": {
"type": "string",
"defaultValue": "Automation-XXX-INFRA-MONITORING",
"metadata": {
"description": "Automation Account"
}
},
"automationRegion": {
"defaultValue": "eastus2",
"type": "string",
"allowedValues": [
"westeurope",
"southeastasia",
"eastus2",
"southcentralus",
"japaneast",
"northeurope",
"canadacentral",
"australiasoutheast",
"centralindia",
"westcentralus"
],
"metadata": {
"description": "Specify the region for your automation account"
}
},
"_artifactsLocation": {
"type": "string",
"defaultValue": "https://ABCD.visualstudio.com/3Pager/_git/Infrastructure?path=%2FAzure.Infra%2FAppInsights%2FMonthOverMonthTrendAnalysisReport.ps1&version=GBmaster",
"metadata": {
"description": "URI to artifacts location"
}
},
"_artifactsLocation1": {
"type": "string",
"defaultValue": "https://ABCD.visualstudio.com/3Pager/_git/Infrastructure?path=%2FAzure.Infra%2FAppInsights%2FMonthOverMonthTrendAnalysisReport.ps1&version=GBmaster",
"metadata": {
"description": "URI to artifacts location"
}
}
},
"variables": {
"asrScripts": {
"runbooks": [
{
"name": "Test_Runbook",
"url": "[parameters('_artifactsLocation')]",
"version": "1.0.0.0",
"type": "PowerShell",
"description": "Runbook for month over month trend analysis report"
}
]
}
},
"resources": [
{
"apiVersion": "2015-10-31",
"type": "Microsoft.Automation/automationAccounts/runbooks",
"name": "[concat(parameters('automationAccountName'), '/', variables('asrScripts').runbooks[copyIndex()].Name)]",
"location": "[parameters('automationRegion')]",
"copy": {
"name": "runbooksLoop",
"count": "[length(variables('asrScripts').runbooks)]"
},
"properties": {
"description": "[variables('asrScripts').runbooks[copyIndex()].description]",
"runbookType": "[variables('asrScripts').runbooks[copyIndex()].type]",
"logProgress": false,
"logVerbose": true,
"publishContentLink": {
"uri":"[parameters('_artifactsLocation1')]",
"version": "[variables('asrScripts').runbooks[copyIndex()].version]" }
}
}
],
"outputs": {}
}
您正在向 ARM 发送一个 URI,告诉它在哪里可以找到运行手册。创建 AutomationAccount/runbooks 资源类型后,它将对 publishContentLink.url 进行 GET 调用,以便从 URI 获取内容。如果 Azure 无法访问该 URI(可能是您的 visualstudio.com URI 无法 public 访问),那么它将无法访问 runbook 内容并且部署将失败。
解决方案是确保 publishContentLink URI 可供 Azure 自动化服务访问。您可以通过几种方式做到这一点:
- 将内容放入 public 可访问的 URI,例如 Github 或 public Blob 存储容器。
- 为内容创建 SAS 令牌。 https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-tutorial-secure-artifacts shows an example of how to do this with Azure Storage, or https://xebia.com/blog/setting-up-vsts-with-arm-templates/ 因为用 VSTS 做到了。
留在这里以防有人遇到类似问题。对于私有 Azure DevOps Repo,可以通过 Azure Function 使用 HTTP 触发器和以下 PowerShell 脚本来解决:
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Interact with query parameters or the body of the request.
$adouri = $Request.Query.adouri
$pat = $Request.Query.pat
if (!$adouri){
$response = "Please pass uri"
Write-Warning "URI not passed" -Warning
} elseif (!$pat){
$response = "Please pass pat"
Write-Warning "PAT not passed" -Warning
} else {
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $pat)))
$headers = @{
"Authorization" = ("Basic {0}" -f $base64AuthInfo)
}
$response = Invoke-RestMethod -Uri $adouri -Method Get -ContentType "application/text" -Headers $headers
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $response
})
一旦函数准备就绪,就可以直接从 ARM 模板调用它,例如:
"variables": {
"runbookUri": "https://[function name].azurewebsites.net/api/[trigger name]?adouri=https://dev.azure.com/[ADO Organization]/[ADO project]/_apis/git/repositories/[Repo]/items?path=%2F[folder]%2F[subfolder]%2Fscript.ps1&pat=[token]"
},
"resources": [
{
"type": "Microsoft.Automation/automationAccounts/runbooks",
"apiVersion": "2018-06-30",
"name": "[name]",
"location": "[location]"
"properties": {
"runbookType": "PowerShell",
"logVerbose": false,
"logProgress": false,
"logActivityTrace": 0,
"publishContentLink": {
"uri": "[variables('runbookUri')]"
}
}
}]
令牌只是来自 Azure DevOps 的个人访问令牌。为了确保它的安全,它可以从秘密 ADO 变量或 Azure KeyVault 传递到 ARM 模板。
我通过使用 Terraform 模板克服了这个限制。它们提供了使用本地路径将自定义内容发布到 Runbook 的可能性。因此,您可以直接从 Git 存储库文件系统(您的电脑)执行此操作,或者通过将 Azure Pipeline 链接到您的存储库并将该文件用作工件。
如果有兴趣,请查看“示例用法 - 自定义内容”中的 https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/automation_runbook。