【发布时间】:2019-05-23 02:53:53
【问题描述】:
我正在尝试创建一种简单的方法,让产品所有者能够站起来并拆除虚拟助手所需的 Azure 资源。但是,部署脚本 deploy.ps1 需要 PowerShell 6+,而 Azure DevOps 似乎不提供该版本。
最好的方法是什么?
描述您想要的解决方案
目标是使用发布管道自动支持机器人运行所需的 Azure 资源。
想法
- 有没有办法通过 Azure PowerShell 使用 PowerShell 6+?
- 我们不应该使用
deploy.ps1在 DevOps 发布管道中部署资源吗?
代码
这是deploy.ps1 和link to the latest 的内容。
#Requires -Version 6
Param(
[string] $name,
[string] $resourceGroup,
[string] $location,
[string] $appId,
[string] $appPassword,
[string] $luisAuthoringKey,
[string] $luisAuthoringRegion,
[string] $parametersFile,
[string] $languages = "en-us",
[string] $outFolder = $(Get-Location),
[string] $logFile = $(Join-Path $PSScriptRoot .. "deploy_log.txt")
)
# Reset log file
if (Test-Path $logFile) {
Clear-Content $logFile -Force | Out-Null
}
else {
New-Item -Path $logFile | Out-Null
}
# Get mandatory parameters
if (-not $name) {
$name = Read-Host "? Bot Name (used as default name for resource group and deployed resources)"
}
if (-not $resourceGroup) {
$resourceGroup = $name
}
if (-not $location) {
$location = Read-Host "? Azure resource group region"
}
if (-not $appPassword) {
$appPassword = Read-Host "? Password for MSA app registration (must be at least 16 characters long, contain at least 1 special character, and contain at least 1 numeric character)"
}
if (-not $luisAuthoringRegion) {
$luisAuthoringRegion = Read-Host "? LUIS Authoring Region (westus, westeurope, or australiaeast)"
}
if (-not $luisAuthoringKey) {
Switch ($luisAuthoringRegion) {
"westus" {
$luisAuthoringKey = Read-Host "? LUIS Authoring Key (found at https://luis.ai/user/settings)"
Break
}
"westeurope" {
$luisAuthoringKey = Read-Host "? LUIS Authoring Key (found at https://eu.luis.ai/user/settings)"
Break
}
"australiaeast" {
$luisAuthoringKey = Read-Host "? LUIS Authoring Key (found at https://au.luis.ai/user/settings)"
Break
}
default {
Write-Host "! $($luisAuthoringRegion) is not a valid LUIS authoring region." -ForegroundColor DarkRed
Break
}
}
if (-not $luisAuthoringKey) {
Break
}
}
if (-not $appId) {
# Create app registration
$app = (az ad app create `
--display-name $name `
--password $appPassword `
--available-to-other-tenants `
--reply-urls 'https://token.botframework.com/.auth/web/redirect')
# Retrieve AppId
if ($app) {
$appId = ($app | ConvertFrom-Json) | Select-Object -ExpandProperty appId
}
if(-not $appId) {
Write-Host "! Could not provision Microsoft App Registration automatically. Review the log for more information." -ForegroundColor DarkRed
Write-Host "! Log: $($logFile)" -ForegroundColor DarkRed
Write-Host "+ Provision an app manually in the Azure Portal, then try again providing the -appId and -appPassword arguments. See https://aka.ms/vamanualappcreation for more information." -ForegroundColor Magenta
Break
}
}
# Get timestamp
$timestamp = Get-Date -f MMddyyyyHHmmss
# Create resource group
Write-Host "> Creating resource group ..."
(az group create --name $name --location $location) 2>> $logFile | Out-Null
# Deploy Azure services (deploys LUIS, QnA Maker, Content Moderator, CosmosDB)
Write-Host "> Deploying Azure services (this could take a while)..." -ForegroundColor Yellow
if ($parametersFile) {
(az group deployment create `
--name $timestamp `
--resource-group $resourceGroup `
--template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" `
--parameters "@$($parametersFile)" `
--parameters microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"") 2>> $logFile | Out-Null
}
else {
(az group deployment create `
--name $timestamp `
--resource-group $resourceGroup `
--template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" `
--parameters microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"") 2>> $logFile | Out-Null
}
# Get deployment outputs
$outputs = (az group deployment show `
--name $timestamp `
--resource-group $resourceGroup `
--query properties.outputs)
# If it succeeded then we perform the remainder of the steps
if ($outputs)
{
# Log and convert to JSON
$outputs >> $logFile
$outputs = $outputs | ConvertFrom-Json
# Update appsettings.json
Write-Host "> Updating appsettings.json ..."
if (Test-Path $(Join-Path $outFolder appsettings.json)) {
$settings = Get-Content $(Join-Path $outFolder appsettings.json) | ConvertFrom-Json
}
else {
$settings = New-Object PSObject
}
$settings | Add-Member -Type NoteProperty -Force -Name 'microsoftAppId' -Value $appId
$settings | Add-Member -Type NoteProperty -Force -Name 'microsoftAppPassword' -Value $appPassword
if ($outputs.appInsights) { $settings | Add-Member -Type NoteProperty -Force -Name 'appInsights' -Value $outputs.appInsights.value }
if ($outputs.storage) { $settings | Add-Member -Type NoteProperty -Force -Name 'blobStorage' -Value $outputs.storage.value }
if ($outputs.cosmosDb) { $settings | Add-Member -Type NoteProperty -Force -Name 'cosmosDb' -Value $outputs.cosmosDb.value }
if ($outputs.contentModerator) { $settings | Add-Member -Type NoteProperty -Force -Name 'contentModerator' -Value $outputs.contentModerator.value }
$settings | ConvertTo-Json -depth 100 | Out-File $(Join-Path $outFolder appsettings.json)
# Delay to let QnA Maker finish setting up
Start-Sleep -s 30
# Deploy cognitive models
Invoke-Expression "$(Join-Path $PSScriptRoot 'deploy_cognitive_models.ps1') -name $($name) -luisAuthoringRegion $($luisAuthoringRegion) -luisAuthoringKey $($luisAuthoringKey) -qnaSubscriptionKey $($outputs.qnaMaker.value.key) -outFolder $($outFolder) -languages `"$($languages)`""
Write-Host "> Done."
}
else
{
# Check for failed deployments
$operations = az group deployment operation list -g $resourceGroup -n $timestamp | ConvertFrom-Json
$failedOperations = $operations | Where { $_.properties.statusmessage.error -ne $null }
if ($failedOperations) {
foreach ($operation in $failedOperations) {
switch ($operation.properties.statusmessage.error.code) {
"MissingRegistrationForLocation" {
Write-Host "! Deployment failed for resource of type $($operation.properties.targetResource.resourceType). This resource is not avaliable in the location provided." -ForegroundColor DarkRed
Write-Host "+ Update the .\Deployment\Resources\parameters.template.json file with a valid region for this resource and provide the file path in the -parametersFile parameter." -ForegroundColor Magenta
}
default {
Write-Host "! Deployment failed for resource of type $($operation.properties.targetResource.resourceType)."
Write-Host "! Code: $($operation.properties.statusMessage.error.code)."
Write-Host "! Message: $($operation.properties.statusMessage.error.message)."
}
}
}
Write-Host "+ To delete this resource group, run 'az group delete -g $($resourceGroup) --no-wait'" -ForegroundColor Magenta
Break
}
}
设置截图
尝试运行 Azure PowerShell
当我尝试使用 Azure PowerShell 运行脚本时,我收到以下错误。
##[error]The script 'deploy.ps1' cannot be run because it contained a "#requires" statement for Windows PowerShell 6.0. The version of Windows PowerShell that is required by the script does not match the currently running version of Windows PowerShell 5.1.17763.316.
这是将Azure PowerShell Version 设置为Latest installed version。使用Specify other version 和6.7.0、6.2.1 或6.0.0 也不起作用。这些似乎都没有真正的效果。它总是以5.1.17763.316 的形式返回。
【问题讨论】:
-
您没有在项目模板中添加一个JSON格式的ARM模板文件,可以创建资源吗? deploy.ps1 的内容是什么?
-
我编辑了我的帖子以包含
deploy.ps1的内容。我可能有一个可用的 ARM 模板,但我认为它比我从 ARM 模板中得到的更多。我不知道。 Virtual Assistant docs 中没有提到如何进行。任何提示表示赞赏。 -
@EricHansen 为什么你认为 PowerShell 6+ 在 Azure DevOps 上不可用?
-
你好@PravinAmbekar。在我的专业意见中〜在我的原始帖子之后 1 年,不要使用管道中的 deploy.ps1。 deploy.ps1 是一个很好的快速启动脚本,可让您启动并运行,但如果您想真正使这个强大的企业使用,请修改 Microsoft 提供的 ARM 模板以满足您的需求。我建议详细阅读 deploy.ps1 的每一行。你会看到它使用了一个存储在这里的模板github.com/microsoft/botframework-solutions/tree/master/…。
-
我认为最好的解决方案是使用 ARM 部署任务来部署/更新资源。您仍然需要运行一些 CLI 命令来与您供应的资源进行交互。我建议不要使用 Microsoft 提供的 PowerShell 脚本之一。取而代之的是,提取您需要的特定 CLI 命令(以脚本为例来查看您需要什么)并为特定场景所需的各个 CLI 命令创建单独的任务。
标签: azure azure-devops botframework azure-pipelines azure-pipelines-release-pipeline