Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BadRequest (HTTP Status Code 400) InvalidTemplateDeployment - The template deployment is not valid according to the validation procedure. #4

Closed
disbenovi opened this issue May 17, 2024 · 5 comments

Comments

@disbenovi
Copy link

disbenovi commented May 17, 2024

nextstageproperties parameter-

[
{
"stageName": "TEST_Tue_Windows_2200",
"offsetDays": 7,
"scope": [
"/subscriptions/",
"/subscriptions/"
],
"filter": {
"resourceTypes": [
"microsoft.compute/virtualmachines",
"microsoft.hybridcompute/machines"
],
"resourceGroups": [],
"tagSettings": {
"tags": {
"aum-stage": ["TEST"],
"os-name": ["windows2022"]
},
"filterOperator": "All"
},
"locations": [],
"osTypes": ["Windows"]
}
},
{
"stageName": "PRD_Tue_Windows_2200",
"offsetDays": 14,
"scope": [
"/subscriptions/",
"/subscriptions/"
],
"filter": {
"resourceTypes": [
"microsoft.compute/virtualmachines",
"microsoft.hybridcompute/machines"
],
"resourceGroups": [],
"tagSettings": {
"tags": {
"aum-stage": ["PRD"],
"os-name": ["windows2022"]
},
"filterOperator": "All"
},
"locations": [],
"osTypes": ["Windows"]
}
}
]

The Runbook throws an exception:

"The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: 7:40:40 PM - Error: Code=InvalidTemplateDeployment; Message=The template deployment 'TEST_Tue_Windows_2200-240517194035' is not valid according to the validation procedure. The tracking id is '6adf3658-7193-4701-b9cc-e308051a84e9'. See inner errors for details."

From the Activity Log of the resource group:

resourceId": "/subscriptions/""/resourcegroups/updates-test-rg/providers/Microsoft.Resources/deployments/TEST_Tue_Windows_2200-240517194035",
"status": {
"value": "Failed",
"localizedValue": "Failed"
},
"subStatus": {
"value": "BadRequest",
"localizedValue": "Bad Request (HTTP Status Code: 400)"
},
"submissionTimestamp": "2024-05-17T19:42:52Z",
"subscriptionId": "",
"tenantId": "",
"properties": {
"statusCode": "BadRequest",
"serviceRequestId": null,
"statusMessage": "{"error":{"code":"InvalidTemplateDeployment","message":"The template deployment 'TEST_Tue_Windows_2200-240517194035' is not valid according to the validation procedure. The tracking id is '6adf3658-7193-4701-b9cc-e308051a84e9'. See inner errors for details.","details":[{"code":"MaintenanceRPTemplateValidationFailed","message":"The template failed MaintenanceRP validation","details":[{"code":"InvalidRequestContent","target":"/subscriptions/resourceGroups/updates-test-rg/providers/Microsoft.Maintenance/maintenanceConfigurations/TEST_Tue_Windows_2200","message":"Invalid KB number ''"}]}]}}",
"eventCategory": "Administrative",
"entity": "/subscriptions/""/resourcegroups/updates-test-rg/providers/Microsoft.Resources/deployments/TEST_Tue_Windows_2200-240517194035",
"message": "Microsoft.Resources/deployments/validate/action",
"hierarchy": ""
},
"relatedEvents": []
}

Output from the runbook:
image

Input parameters:
image

@helderpinto
Copy link
Owner

helderpinto commented May 19, 2024

Thank you for reporting this issue @disbenovi.

From the output you shared, it seems the "Windows Admin Center 2311" update is breaking the script, due to the fact it comes with an empty KB value. In order to confirm my analysis and think of the best solution for this case, can you please run the Azure Resource Graph query below (replacing the maintenanceRunId filter by the full ID of the DEV_BiWeekly_Tue_Windows2022_2200 maintenance configuration) and check whether the kbId column comes empty for any of the patches?

patchinstallationresources
| where type endswith '/patchinstallationresults'
| extend maintenanceRunId=tolower(split(properties.maintenanceRunId,'/providers/microsoft.maintenance/applyupdates')[0])
| where maintenanceRunId =~ '<replace with the full ID of the maintenance configuration>'
| where todatetime(properties.lastModifiedDateTime) > todatetime('2024-05-15T06:00:51.000Z')
| extend vmId = tostring(split(tolower(id), '/patchinstallationresults/')[0])
| extend osType = tostring(properties.osType)
| extend lastDeploymentStart = tostring(properties.startDateTime)
| extend deploymentStatus = tostring(properties.status)
| join kind=inner (
    patchinstallationresources
    | where type endswith '/patchinstallationresults/softwarepatches'
    | where todatetime(properties.lastModifiedDateTime) > todatetime('2024-05-15T06:00:51.000Z')
    | extend vmId = tostring(split(tolower(id), '/patchinstallationresults/')[0])
    | extend patchName = tostring(properties.patchName)
    | extend patchVersion = tostring(properties.version)
    | extend kbId = tostring(properties.kbId)
    | extend installationState = tostring(properties.installationState)
    | project vmId, installationState, patchName, patchVersion, kbId
) on vmId
| join kind=inner ( 
    resources
    | where type == 'microsoft.maintenance/maintenanceconfigurations'
    | extend maintenanceDuration = tostring(properties.maintenanceWindow.duration)
    | extend rebootSetting = tostring(properties.installPatches.rebootSetting)
    | project maintenanceRunId=tolower(id), maintenanceDuration, rebootSetting, location, mcTags=tostring(tags)
) on maintenanceRunId
| where installationState == 'Installed'
| distinct osType, lastDeploymentStart, maintenanceDuration, patchName, patchVersion, kbId, rebootSetting, location, mcTags

@disbenovi
Copy link
Author

disbenovi commented May 19, 2024

Thanks for grabbing this @helderpinto

Your KQL query returned with empty results:
image

I managed to customize a built-in query in AUM and add 'kbId' to it:
image

You were right, the KBID is missing for Windows Admin Center.

Here's the query I ran:

patchinstallationresources
| where type in~ ("microsoft.hybridcompute/machines/patchinstallationresults/softwarepatches", "microsoft.compute/virtualmachines/patchinstallationresults/softwarepatches")
| where properties.lastModifiedDateTime >= datetime(2024-05-15T00:00:00.000Z) and properties.lastModifiedDateTime <= datetime(2024-05-15T13:00:00.000Z) 
| project id, properties
| parse kind=regex flags=i id with patchInstallationResultId:string  "/softwarePatches/"
| extend packageId = iff(isempty(properties.kbId), strcat(tostring(properties.patchName),'_',tostring(properties.version)), properties.patchName)
| extend patchInstallationResultId = tolower(patchInstallationResultId)
| join kind=inner (
    patchinstallationresources
    | where type in~ ("microsoft.hybridcompute/machines/patchinstallationresults", "microsoft.compute/virtualmachines/patchinstallationresults")
    | where properties.maintenanceRunId =~ "/subscriptions/xxxx/resourcegroups/updates-test-rg/providers/microsoft.maintenance/maintenanceconfigurations/dev_biweekly_tue_windows2022_2200/providers/microsoft.maintenance/applyupdates/20240515050000"
    | parse kind=regex flags=i id with vmId "/patchInstallationResults/"
    | extend machineResourceId = tolower(vmId)
    | summarize arg_max(todatetime(properties.startDateTime), properties, id) by machineResourceId
    | project patchInstallationResultId = tolower(id), machineResourceId, osType = properties.osType
) on $left.patchInstallationResultId == $right.patchInstallationResultId
| summarize totalMachinesCount = dcount(machineResourceId, 2), osType = any(osType), updateName = any(tostring(properties.patchName)), classification = any(properties.classifications[0]), failedMachinesCount = dcountif(machineResourceId, properties.installationState =~ "Failed", 2), notAttemptedMachinesCount=dcountif(machineResourceId, properties.installationState =~ "Pending", 2),
notSelectedMachinesCount=dcountif(machineResourceId,  properties.installationState=~ "NotSelected", 2),
exludedMachinesCount=dcountif(machineResourceId,  properties.installationState =~ "Excluded", 2),
succeededMachinesCount = dcountif(machineResourceId, properties.installationState =~ "Installed", 2), kbId = any(properties.kbId) by packageId
| project updateName, classification, failedMachinesCount, notAttemptedMachinesCount, notSelectedMachinesCount, exludedMachinesCount, succeededMachinesCount, osType, totalMachinesCount, kbId
| order by failedMachinesCount desc, updateName asc

@helderpinto
Copy link
Owner

Thank you for confirming, @disbenovi. The query I shared earlier had a typo. I am glad you were able to get the details we needed.

I must now try to reproduce your issue and decide whether those types of updates should be included (and how) or not. Meanwhile, as a quick fix for your error, can you please replace line 130 of the Create-StagedMaintenanceConfiguration runbook:

$windowsPackages = ($installedPackages | Where-Object { $_.osType -eq "Windows" } | Select-Object -Property kbId -Unique).kbId

with the following?

$windowsPackages = ($installedPackages | Where-Object { $_.osType -eq "Windows" -and -not([string]::isNullOrEmpty($_.kbId))} | Select-Object -Property kbId -Unique).kbId

And give it a new try?

@disbenovi
Copy link
Author

Sweet, that got it working.

If it helps, the Windows Admin Center was installed as a VM Extension and not using the installer.

Thanks for a workaround @helderpinto

@helderpinto
Copy link
Owner

It does help, absolutely. VM extensions should be updated via their own lifecycle and auto-upgrade options and not depend on Azure Update Manager. Therefore, the temporary fix I gave you, which excludes updates that have no KB, will be permanent. Once the code is pushed into the main branch, this issue will be closed automatically. Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants