Diagnosing Azure Resource Manager template validation errors
- Name of the template: azuredeploy
- Template has failed validation procedure
- You can check details with provided tracking Id which is some Guid
- Deletion of resources
- Deployments
- Starting and stopping of resources
- Timestamp
- Principal which initiated event
- JSON object which describes change in details
Break something!
Clone the repository and open azuredeploy.parameters.json file. To break it change value of the storageAccountName parameter to provision-warm-template. Now you can try to deploy the template with the instruction from the previous post or the GitHub repository - as a result you should get error similar to one on the screenshot above.
Using Azure Portal
{\"error\":{\"code\":\"InvalidTemplateDeployment\",\"message\":\"The template deployment 'azuredeploy' is not valid according to the validation procedure. The tracking id is '0fa3c66c-6b01-4f42-aadf-0a886c926d35'. See inner errors for details.\",\"details\":[{\"code\":\"PreflightValidationCheckFailed\",\"message\":\"Preflight validation failed. Please refer to the details for the specific errors.\",\"details\":[{\"code\":\"AccountNameInvalid\",\"target\":\"provision-warm-template\",\"message\":\"provision-warm-template is not a valid storage account name. Storage account name must be between 3 and 24 characters in length and use numbers and lower-case letters only.\"}]}]}}
Using Azure CLI
az monitor activity-log list --correlation-id 0fa3c66c-6b01-4f42-aadf-0a886c926d35
az monitor activity-log list `
--correlation-id 0fa3c66c-6b01-4f42-aadf-0a886c926d35 `
--query "[?level=='Error'].properties.{Entity: entity, StatusCode: statusCode, StatusMessage: statusMessage}" `
--output yaml
- Entity: /subscriptions/975874d0-9f27-4c97-8464-701c68575c6b/resourcegroups/my-infra-rg/providers/Microsoft.Resources/deployments/azuredeploy
StatusCode: BadRequest
StatusMessage: '{"error":{"code":"InvalidTemplateDeployment","message":"The template
deployment ''azuredeploy'' is not valid according to the validation procedure.
The tracking id is ''0fa3c66c-6b01-4f42-aadf-0a886c926d35''. See inner errors
for details.","details":[{"code":"PreflightValidationCheckFailed","message":"Preflight
validation failed. Please refer to the details for the specific errors.","details":[{"code":"AccountNameInvalid","target":"provision-warm-template","message":"provision-warm-template
is not a valid storage account name. Storage account name must be between 3 and
24 characters in length and use numbers and lower-case letters only."}]}]}}'
az monitor activity-log - first piece of command is responsible for selecting Azure resource type against which command will be run. In this case we would like to ingest activity logs which are part of Azure Monitor - thus we use monitor activity-log. For other types of resources you can use other parameter names e.g. account for subscription or group for resource groups.
list - tells Azure to get... list (surprise :) of all resources of specific type (defined in the first piece of command) executing principal has access to.
--correlation-id <Guid> - this is one of optional parameters for az monitor activity-log list, which is responsible for getting only these activity log records which are assigned to specific correlation Id.
--query <JMESPath Query> - this is the most interesting part of the command. It accepts so called JMESPath query which allows to filter out result and select only the fields we are interested in.
Lets take a closer look at the query we have used in example above:
- Filter - [?level='Error'] - the first piece is surrounded with square braces which mean that we are dealing with JSON array. Inside of braces with have expression starting with question mark - it is responsible for filtering out object which do not meet the condition - level property of the object must be equal to Error. To sum up, the filter expression here will go through array of objects and filter out these object where level property has value other than Error.
- Path - this part of query string tells that only properties property of the object should be returned.
- Field Selectors - at the end in curly braces there are field selectors, they are responsible for selecting the fields to be returned. Imagine object with ten properties, out of which you are interested in two (similar as in our case), with this syntax you are able to tell Azure to return only selected set of fields and give each of them alias name. For each field the syntax is following: <alias>: <name of the field in original object>.
--output yaml - the last parameter is responsible for defining the output format of the data to by YAML. As you probably noticed by default Azure CLI is outputting the data in JSON format. Other commonly used value for this parameter is table. Full list of possible values can be found in https://docs.microsoft.com/pl-pl/cli/azure/format-output-azure-cli.