scripts/New-OsDeploymentResource.ps1

Function New-OsDeploymentResource {
    Param(
        [string] $module,
        [array] $DefaultParameters,
        [string] $ResourceGroupLocation,
        [string] $Environment,
        [alias('Dir', 'Path')]
        [string] $ProjectDirectory = (Get-Location | Select-Object -ExpandProperty Path)
    )

    $ModulesAdded = 0
    $keyvaultparams = @()
    $script:DeploymentResourceJson = Get-Content "$ProjectDirectory\schema.template.json" -Raw | ConvertFrom-Json | Select-Object -ExpandProperty resources
    Write-Verbose "module: $module"

    if (Test-Path -Path "$ProjectDirectory\modules\$module\metadata.json") {
        $moduleMetadataJson = Get-Content "$ProjectDirectory\modules\$module\metadata.json" -Raw | ConvertFrom-Json
        $modulenames = $moduleMetadataJson.modulenames
        $customname = $moduleMetadataJson.CustomDeploymentName
        $dependson = $moduleMetadataJson.dependson
    }
    else {
        $modulenames = @()
        $modulenames += $module
        Write-Verbose "Running module $module with no module configuration! Will use default module deployment settings."
    }

    if (Test-Path -Path "$ProjectDirectory\env\$ResourceGroupLocation\$Environment\modules\$module\metadata.json") {
        $moduleEnvMetadataJson = Get-Content "$ProjectDirectory\env\$ResourceGroupLocation\$Environment\modules\$module\metadata.json" -Raw | ConvertFrom-Json
        if ($moduleEnvMetadataJson | Select-Object dependson) {
            $dependsonenv = $moduleEnvMetadataJson.dependson
        }
    }

    # Build out the deployment template resources for the selected module(s).
    $DeploymentTime = ((Get-Date)).ToString('yyyy-MM-dd-HHmm')

    foreach ($modulename in $modulenames) {
        $ModulesAdded ++
        Write-Verbose "Building Deployment for Module: $module"
        
        if ($customname) {
            $DeploymentResourceJson | add-member -MemberType NoteProperty -Name name -Value "$customname" -Force
        }
        elseif ($modulenames.Count -gt 1) {
            $DeploymentResourceJson | add-member -MemberType NoteProperty -Name name -Value "[concat(parameters('EnvName'), '-$module-$ModulesAdded-$DeploymentTime')]" -Force
        }
        else {
            $DeploymentResourceJson | add-member -MemberType NoteProperty -Name name -Value "[concat(parameters('EnvName'), '-$module-$DeploymentTime')]" -Force
        }

        if (($dependson -or $dependsonenv) -and -not $modules) {
            $DependsOnBlock = @()
            $dependsonenv | ForEach-Object {
                $DependsOnBlock += "[concat(parameters('EnvName'), '-$($_)-$DeploymentTime')]"
            }
            $dependson | ForEach-Object {
                $DependsOnBlock += "[concat(parameters('EnvName'), '-$($_)-$DeploymentTime')]"
            }
            $DeploymentResourceJson | add-member -MemberType NoteProperty -Name DependsOn -Value $DependsOnBlock -Force
        }

        $DeploymentResourceJson.properties.templateLink | add-member -MemberType NoteProperty -Name uri -Value "[concat(parameters('_artifactsLocation'), '/modules/$modulename/module.json', parameters('_artifactsLocationSasToken'))]" -Force

        # For parameters we can grab these from the module file directly.
        # Add any Key Vault secrets to pass in as a SecureString parameter to a child deployment.
        if (Test-Path -Path "$ProjectDirectory\env\$ResourceGroupLocation\$Environment\modules\$module\metadata.json") {
            $EnvmoduleJson = Get-Content "$ProjectDirectory\env\$ResourceGroupLocation\$Environment\modules\$module\metadata.json" -Raw | ConvertFrom-Json
            if ($EnvmoduleJson.keyvaultsecrets) {
                $EnvmoduleJson.keyvaultsecrets | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name | ForEach-Object {
                    $DeploymentResourceJson.properties.parameters | Add-Member -MemberType NoteProperty -Name $_ -Value $EnvmoduleJson.keyvaultsecrets.$_ -Force
                    $keyvaultparams += $_
                }
            }
        }
                
        $ModuleJson = Get-Content "$ProjectDirectory\modules\$modulename\module.json" -Raw | ConvertFrom-Json
    
        $ModuleParameters = $ModuleJson.parameters | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name
        Write-Verbose "ModuleParameters: $ModuleParameters"

        $ModuleSpecificParameters = $ModuleParameters | Where-Object { $DefaultParameters -notcontains $_ } | Where-Object { $keyvaultparams -notcontains $_ }
        Write-Verbose "ModuleSpecificParameters: $ModuleSpecificParameters"

        $ModuleGlobalParameters = $ModuleParameters | Where-Object { $DefaultParameters -contains $_ }
        Write-Verbose "ModuleGlobalParameters: $ModuleGlobalParameters"

        foreach ($ModuleParam in $ModuleSpecificParameters) {
            $DeploymentResourceJson.properties.parameters | add-member -MemberType NoteProperty -Name $ModuleParam -Value (New-Object -TypeName pscustomobject) -Force
            $DeploymentResourceJson.properties.parameters.$ModuleParam | add-member -MemberType NoteProperty -Name value -Value "[parameters('$module').$ModuleParam]" -Force
        }

        foreach ($ModuleParam in $ModuleGlobalParameters) {
            $DeploymentResourceJson.properties.parameters | add-member -MemberType NoteProperty -Name $ModuleParam -Value (New-Object -TypeName pscustomobject) -Force
            $DeploymentResourceJson.properties.parameters.$ModuleParam | add-member -MemberType NoteProperty -Name value -Value "[parameters('$ModuleParam')]" -Force
        }
    }
}