Public/Test-VMetricDeployment.ps1

function Test-VMetricDeployment {
    <#
    .SYNOPSIS
    Checks a Bicep template without deploying it.
 
    .DESCRIPTION
    Test-VMetricDeployment parses and checks a template without touching storage and returns the engine's
    answer (VirtualMetric.DeploymentValidation): valid, the diagnostics (VirtualMetric.Diagnostic, each with
    its line and column: syntax errors, unknown types or properties, parameters that do not bind), and the
    parameters, resources and outputs the template declares.
 
    With -Preview it runs the engine's what-if instead and writes what a deployment would do to each resource
    (VirtualMetric.WhatIfChange): create, modify with the property changes, no change, and so on. A preview
    needs the read permission of every type the template names; its diagnostics are written as errors and
    warnings.
 
    .PARAMETER TemplateFile
    The Bicep file to check.
 
    .PARAMETER Template
    The Bicep text to check.
 
    .PARAMETER TemplateParameterObject
    The template's parameters. Without parameters, a required parameter that has no value is not reported.
 
    .PARAMETER TemplateParameterFile
    A JSON parameters file, as New-VMetricDeployment takes.
 
    .PARAMETER Preview
    Run the what-if and write the changes instead of the validation.
 
    .EXAMPLE
    (Test-VMetricDeployment ./syslog.bicep).diagnostics | Format-Table
 
    .EXAMPLE
    Test-VMetricDeployment -TemplateFile ./syslog.bicep -TemplateParameterObject @{ port = 1514 } -Preview
 
    .OUTPUTS
    VirtualMetric.DeploymentValidation, or VirtualMetric.WhatIfChange with -Preview.
 
    .LINK
    New-VMetricDeployment
    #>

    [CmdletBinding(DefaultParameterSetName = 'File')]
    [OutputType('VirtualMetric.DeploymentValidation', 'VirtualMetric.WhatIfChange')]
    param(
        [Parameter(Mandatory, Position = 0, ParameterSetName = 'File', ValueFromPipelineByPropertyName)]
        [Alias('FullName')]
        [ValidateNotNullOrEmpty()]
        [string] $TemplateFile,

        [Parameter(Mandatory, ParameterSetName = 'Text')]
        [ValidateNotNullOrEmpty()]
        [string] $Template,

        [System.Collections.IDictionary] $TemplateParameterObject,

        [ValidateNotNullOrEmpty()]
        [string] $TemplateParameterFile,

        [switch] $Preview
    )

    process {
        try {
            $session = Get-VMetricSession
            $text = Get-VMetricTemplateText -Cmdlet $PSCmdlet -TemplateFile $TemplateFile -Template $Template
            $parameters = Get-VMetricTemplateParameter -Cmdlet $PSCmdlet -ParameterObject $TemplateParameterObject -ParameterFile $TemplateParameterFile
            $secrets = Get-VMetricSecretText -InputObject $parameters

            if ($Preview) {
                $whatIf = Invoke-VMetricRequest -Method POST -Path '/deployments/what-if' -Session $session `
                    -Body ([ordered]@{ template = $text; parameters = $parameters })
                $null = Write-VMetricPreviewDiagnostic -Cmdlet $PSCmdlet -Preview $whatIf -Secret $secrets
                foreach ($change in (ConvertTo-VMetricArray -InputObject (Get-VMetricMember -InputObject $whatIf -Name 'changes'))) {
                    Hide-VMetricSecretInObject -InputObject $change -Secret $secrets
                    ConvertTo-VMetricWhatIfChange -InputObject $change
                }
                return
            }

            $body = [ordered]@{ template = $text }
            if ($TemplateParameterObject -or $TemplateParameterFile) {
                $body['parameters'] = $parameters
            }
            $result = Invoke-VMetricRequest -Method POST -Path '/deployments/validate' -Session $session -Body $body
            Hide-VMetricSecretInObject -InputObject $result -Secret $secrets
            foreach ($diagnostic in (ConvertTo-VMetricArray -InputObject (Get-VMetricMember -InputObject $result -Name 'diagnostics'))) {
                $null = ConvertTo-VMetricDiagnostic -InputObject $diagnostic
            }
            Add-VMetricTypeName -InputObject $result -TypeName 'VirtualMetric.DeploymentValidation'
            $result
        }
        catch {
            if (Test-VMetricFlowControl -ErrorRecord $_) {
                throw
            }
            $record = Hide-VMetricSecretInError -ErrorRecord $_ -Secret (Get-VMetricSecretText -InputObject $TemplateParameterObject)
            Write-VMetricCmdletError -Cmdlet $PSCmdlet -ErrorRecord $record
        }
    }
}