テンプレートとそれに付随するランブックを作成しました。テンプレートは Runbook をトリガーします。Runbook のパラメーターの 1 つにオブジェクトを渡そうとするまで、テンプレートと Runbook は正常に動作しています。Azure エラーは次のとおりです。
エラー
"content":
{
"status": "Failed",
"error":
{
"code": "DeploymentFailed",
"message": "At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-debug for usage details.",
"details":
[
{
"code": "BadRequest",
"message": "{\r\n \"code\": \"BadRequest\",\r\n \"message\": \"{\\\"Message\\\":\\\"The request is invalid.\\\",\\\"ModelState\\\":{\\\"job.properties.parameters.MyTags\\\":[\\\"An error has occurred.\\\"]}}\"\r\n}"
}
]
}
}
が何を意味するのかわかりませんがModelState
、job.properties.parameters.MyTags
は厄介なパラメーターを指しています。
私はそれがデータ型と関係があると確信しています。パラメーターが JSON オブジェクトとして渡され、Runbook がそれを理解できないことが原因である可能性があります。私は、PowerShell からテンプレートにオブジェクトを渡すことに慣れています。
Runbook (Update-ResourceGroupTags.ps1)
テスト用の Runbook は次のようになります。
param
(
[string]$ResourceGroupId,
$MyTags
)
Write-Output "ResourceGroupId: $ResourceGroupId"
Write-Output "MyTags: $($MyTags | Out-String)"
Write-Output "MyTagsType: $($MyTags.GetType() | Out-String)"
認証はまだ必要ないため、意図的に入力していませんが、書かれていない/見逃したルールがある場合に備えて、 `[parameter(Mandatory = $true)] を$MyTags
試して使用しました。[object]
ゴール
簡単に言うと、テンプレートで複雑なオブジェクトを変数として作成し、それを単一のオブジェクトとして Runbook のパラメーターに渡したいと考えています。値は動的であり、展開時までわかりません。Runbook で各パラメーター (テスト 8) を指定する必要があると、この要件が破られます。
New-AzureRmResourceGroupDeployment
コマンドレットでテンプレートを開始します。
「複合オブジェクト」変数を作成します。
"rolesTagObject": {
"db": "TestVm1",
"Server": "TestVm1",
"Client": "TestVm1"
}
テンプレートは のリソースを実行し"type" : "jobs"
ます。
によって実行される Runbook には、次のように渡す必要jobs
があるパラメーターがあります。MyTags
roleTagObject
jobs.properties.parameters.MyTags
,
"parameters": {
"MyTags": "[variable('roleTagObject')]"
}
これが機能していません。各キーに分解すると (テスト 8)、機能します。
私の最初の考えは、それを単一の文字列に変換し、関数を使用してランブックに渡すことjson()
ですが、テンプレートでそれを行う方法がわかりません。
テンプレート (testRunRunbook.json)
この質問をこれ以上行わないように、テンプレートを GIST に入れました。 https://gist.github.com/arcotek-ltd/7c606540980a45a3a7915ccae2e0b140
"resources":[]
テンプレートが作成されたので、セクションを別のテンプレートにコピーできます。したがって、一部の変数とパラメーターの名前が奇妙に見える場合があります。私が言ったように、この問題を除けば、テンプレートは機能します。
パワーシェル
したがって、PowerShell を使用してテンプレートを呼び出しています。
$Ticks = (Get-Date).Ticks.ToString()
$RGID = (Get-AzureRmResourceGroup -Name "MyResourceGroup").ResourceId
$MyTags = @{"TestTag2"="TestValue2"}
$JsonTagsHash = ($MyTags | ConvertTo-Json -Depth 20 | Out-String) -replace '\s',''
$TemplateParametersObject = @{
currentDateTimeInTicks = $Ticks
runbookParameters = @{
ResourceGroupId = $RGID
#"MyTags" = $MyTags #$JsonTagsHash
}
}
New-AzureRmResourceGroupDeployment `
-Name "Test_Runbook" `
-ResourceGroupName "MyResourceGroup" `
-Mode Incremental `
-DeploymentDebugLogLevel All `
-Force `
-TemplateFile "D:temp\testRunRunbook.json" `
-Verbose `
-TemplateParameterObject $TemplateParametersObject
次のテストを試しました。
テスト 1
コメントを外す$TemplateParametersObject.runbookParameters.MyTags
:
$MyTags = @{"TestTag1"="TestValue1"}
$TemplateParametersObject = @{
currentDateTimeInTicks = $Ticks
runbookParameters = @{
ResourceGroupId = $RGID
MyTags = $MyTags
}
}
結果の失敗- 上記のエラーを参照してください。
テスト 2
に置き換え$MyTags
ます$JsonTagsHash
:
$MyTags = @{"TestTag2"="TestValue2"}
$JsonTagsHash = ($MyTags | ConvertTo-Json -Depth 20 | Out-String) -replace '\s',''
$TemplateParametersObject = @{
currentDateTimeInTicks = $Ticks
runbookParameters = @{
ResourceGroupId = $RGID
MyTags = $JsonTagsHash
}
}
結果:合格期待どおりに動作します。パラメーターは Runbook に渡されます。
テスト 2 は機能しますが、実行時にテンプレート内で生成されるパラメーターを Runbook に渡すことができる必要があります。つまり、PowerShell を使用できません。テンプレート内job.properties.parameters
(gist の 103 行目)
テスト 3
MyTags
それが問題の原因であることを証明するには、完全に取り除きます。
"parameters": {
"ResourceGroupId": "[parameters('runbookParameters').ResourceGroupId]"
}
結果:エラーはありませんが、myTags
渡されません (明らかに)。
テスト 4
変数オブジェクトを作成し、それをパラメーターに渡します。
"variables" : {
"rolesTagObject": {
"db": "TestVm1",
"Server": "TestVm1",
"Client": "TestVm1"
}
}
そして戻ってjob.properties.parameters
:
"parameters": {
"ResourceGroupId": "[parameters('runbookParameters').ResourceGroupId]",
"MyTags": "[variables('rolesTagObject')]"
}
結果の失敗- 上記のエラーを参照してください。
テスト 5
直接試してください:
"parameters": {
"ResourceGroupId": "[parameters('runbookParameters').ResourceGroupId]",
"MyTags": {
"testTag5" : "testValue5"
}
}
結果の失敗- 上記のエラーを参照してください。
テスト 6
json()
テンプレート機能を使用します。文字列が必要なので、うまくいくとは思っていません。
"parameters": {
"ResourceGroupId": "[parameters('runbookParameters').ResourceGroupId]",
"MyTags": "[json(variables('rolesTagObject'))]"
}
結果失敗。予測どおり:
'The template language function 'json' expects an argument of type 'string'. The provided value is of type 'Object'.
テスト 7
MS が提供するjson()
テンプレート関数の例を試してみてください。
"parameters": {
"ResourceGroupId": "[parameters('runbookParameters').ResourceGroupId]",
"MyTags": "[json('{\"a\": \"b\"}')]"
}
結果の失敗- 上記のエラーを参照してください。面白い!しかし、なぜ?動作中の PowerShell テストでは、JSON オブジェクトである必要があることが示唆されています。これは何をするのjson()
ではないですか?
テスト 8
オブジェクトを個々のキー/値に分解:
"parameters": {
"db": "[variables('rolesTagObject').db]",
"server": "[variables('rolesTagObject').server]",
"client": "[variables('rolesTagObject').client]"
}
また、Runbook のパラメーターを 1 から 3 に変更する必要があります。
結果パス- ただし、オブジェクトを渡すことができるという考え方は、キーと値のペアをいくつでも持つことができるということです。この方法では、変数とパラメーターをハードコーディングする必要があるだけでなく、Runbook もハードコーディングする必要があります。あまり柔軟ではありません。
私はアイデアがありません。何か提案はありますか?