private TemplateContext GetDeploymentContext()

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;
    }