in src/Analyzer.TemplateProcessor/ArmTemplateProcessor.cs [102:153]
internal Template ParseAndValidateTemplate(InsensitiveDictionary<JToken> parameters, InsensitiveDictionary<JToken> metadata)
{
Dictionary<string, (string, int)> copyNameMap = [];
Template template = TemplateEngine.ParseTemplate(armTemplate);
TemplateEngine.ValidateTemplate(template, apiVersion, TemplateDeploymentScope.NotSpecified);
SetOriginalResourceNames(template);
// If there are resources using copies, the original resource will
// be removed from template.Resources and the copies will be added instead,
// to the end of the array. This means that OriginalName will be lost
// in the resource and will be out of order.
// To work around this, build a map of copy name to OriginalName and index
// so OriginalName can be updated and the order fixed after copies are finished
for (int i = 0; i < template.Resources.Length; i++)
{
var resource = template.Resources[i];
if (resource.Copy != null) copyNameMap[resource.Copy.Name.Value] = (resource.OriginalName, i);
}
var managementGroupName = metadata["managementGroup"]["name"].ToString();
var subscriptionId = metadata["subscription"]["subscriptionId"].ToString();
var resourceGroupName = metadata["resourceGroup"]["name"].ToString();
try
{
TemplateEngine.ProcessTemplateLanguageExpressions(managementGroupName, subscriptionId, resourceGroupName, template, apiVersion, parameters, metadata, null);
}
catch (Exception ex)
{
if (ex.Message.Contains("incorrect segment lengths")) {
// Processing stops when the error is found: some resources could be missing
// information that is needed for the remaining template processing,
// like updated values in their DependsOn and Name properties
throw;
}
// Do not throw if there was another issue with evaluating language expressions
logger?.LogWarning(ex, "An exception occurred when processing the template language expressions");
}
MapTopLevelResources(template, copyNameMap);
TemplateEngine.ValidateProcessedTemplate(template, apiVersion, TemplateDeploymentScope.NotSpecified);
template = ProcessResourcesAndOutputs(template);
return template;
}