in src/PSRule.Rules.Azure/Data/Template/TemplateVisitor.cs [1497:1583]
private TemplateContext GetDeploymentContext(TemplateContext context, string deploymentName, JObject resource, JObject properties)
{
if (!TryObjectProperty(properties, PROPERTY_EXPRESSION_EVALUATION_OPTIONS, out var options) ||
!TryStringProperty(options, PROPERTY_SCOPE, out var scope) ||
!StringComparer.OrdinalIgnoreCase.Equals(DEPLOYMENT_SCOPE_INNER, scope) ||
!TryObjectProperty(properties, PROPERTY_TEMPLATE, out var template))
return context;
// Handle inner scope
var subscription = new SubscriptionOption(context.Subscription);
var resourceGroup = new ResourceGroupOption(context.ResourceGroup);
var tenant = new TenantOption(context.Tenant);
var managementGroup = new ManagementGroupOption(context.ManagementGroup);
var deployer = new DeployerOption(context.Deployer);
if (TryStringProperty(resource, PROPERTY_SUBSCRIPTION_ID, out var subscriptionId))
{
var targetSubscriptionId = ExpandString(context, subscriptionId);
if (!string.IsNullOrEmpty(subscriptionId))
subscription.SubscriptionId = targetSubscriptionId;
}
if (TryStringProperty(resource, PROPERTY_RESOURCE_GROUP, out var resourceGroupName))
{
var targetResourceGroup = ExpandString(context, resourceGroupName);
if (!string.IsNullOrEmpty(targetResourceGroup))
resourceGroup.Name = targetResourceGroup;
}
if (TryStringProperty(resource, PROPERTY_SCOPE, out var scopeId) && ResourceHelper.ResourceIdComponents(scopeId, out _, out var managementGroupName, out subscriptionId, out resourceGroupName, out _, out _))
{
if (!string.IsNullOrEmpty(managementGroupName))
managementGroup.Name = managementGroupName;
if (!string.IsNullOrEmpty(subscriptionId))
subscription.SubscriptionId = subscriptionId;
if (!string.IsNullOrEmpty(resourceGroupName))
resourceGroup.Name = resourceGroupName;
}
resourceGroup.SubscriptionId = subscription.SubscriptionId;
TryObjectProperty(template, PROPERTY_PARAMETERS, out var templateParameters);
var deploymentContext = new TemplateContext(context, context.Pipeline, subscription, resourceGroup, tenant, managementGroup, deployer, context.ParameterDefaults);
// Handle custom type definitions early to allow type mapping of parameters if required.
if (TryObjectProperty(template, PROPERTY_DEFINITIONS, out var definitions))
Definitions(deploymentContext, definitions);
if (TryObjectProperty(properties, PROPERTY_PARAMETERS, out var innerParameters))
{
foreach (var parameter in innerParameters.Properties())
{
var parameterType = templateParameters.TryGetProperty<JObject>(parameter.Name, out var templateParameter) &&
TryParameterType(deploymentContext, templateParameter, out var t) ? t.Value.Type : TypePrimitive.None;
if (parameter.Value is JValue parameterValueExpression)
parameter.Value = ResolveToken(context, ResolveVariable(context, parameterType, parameterValueExpression));
if (parameter.Value is JObject parameterInner)
{
if (parameterInner.TryGetProperty(PROPERTY_VALUE, out JToken parameterValue))
parameterInner[PROPERTY_VALUE] = ResolveToken(context, ResolveVariable(context, parameterType, parameterValue));
if (parameterInner.TryGetProperty(PROPERTY_COPY, out JArray _))
{
foreach (var copyIndex in GetVariableIterator(context, parameterInner, pushToStack: false))
{
if (copyIndex.IsCopy())
{
var jArray = new JArray();
while (copyIndex.Next())
{
var instance = copyIndex.CloneInput<JToken>();
jArray.Add(ResolveToken(context, instance));
}
parameterInner[copyIndex.Name] = ResolveVariable(context, jArray);
}
}
}
}
}
deploymentContext.Load(properties);
}
deploymentContext.SetSource(context.TemplateFile, context.ParameterFile);
return deploymentContext;
}