scripts/New-OsARMTemplate.ps1
Function New-OsARMParameterTemplate { Param( [string]$Environment, [array] $modules, [alias('Dir', 'Path')] [string] $ProjectDirectory = (Get-Location | Select-Object -ExpandProperty Path).ToString(), [string] $ResourceGroupLocation = 'eastus2', [string] $TemplateParametersFile, [string] $ResourceGroup ) if ($ResourceGroup) { $Environment = $ResourceGroup } # Parameter Layering - Deserialize all ARM template JSON documents and setup variables. $JsonParameters = Get-Content "$ProjectDirectory\schema.parameters.json" -Raw | ConvertFrom-Json $GlobalParameters = Get-Content "$ProjectDirectory\global.parameters.json" -Raw | ConvertFrom-Json $EnvironmentParameters = Get-Content "$ProjectDirectory\env\$ResourceGroupLocation\$Environment\environment.parameters.json" -Raw | ConvertFrom-Json $modulesList = $EnvironmentParameters.parameters.modules.value | Get-Member -MemberType NoteProperty | Where-Object { $_.Definition -match "[1]" } | Select-Object -ExpandProperty Name # Begin layering Global parameters from the root "global" directory and the environment directory. $JsonParameters.parameters.Global | Add-Member -MemberType NoteProperty -Name value -Value $GlobalParameters.parameters.Global.value -Force $JsonParameters.parameters.modules.value = $EnvironmentParameters.parameters.modules.value $EnvironmentParameters.parameters.Global.value | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name | ForEach-Object { $JsonParameters.parameters.Global.value | Add-Member -MemberType NoteProperty -Name $_ -Value $EnvironmentParameters.parameters.Global.value.$_ -Force } # Determine which deployments and modules will be used if ($modules) { $modulesList = $modules } # This loops through every file in the module folder subdirectory of the environment and adds top level parameter blocks to $JsonParameters. $modulesList | ForEach-Object { Add-OsTemplatemoduleParameters -Environment $Environment -module $_ -JsonParameters $JsonParameters -ProjectDirectory $ProjectDirectory -ResourceGroupLocation $ResourceGroupLocation } #Cleanup template and check folders. if (-not (Test-Path -Path "$ProjectDirectory\temp")) { New-Item -Path "$ProjectDirectory\temp" -ItemType Directory } # The latest-template-deployment.json is used to create the deployment parameter file that is deployed. # Can also be used to review the last template generated for errors and/or troubleshooting deployments. $JsonParameters | ConvertTo-Json -Depth 100 | Out-File "$ProjectDirectory\temp\latest-template-deployment.json" } Function New-OsARMDeploymentTemplate { Param( [string]$Environment, [array] $modules, [alias('Dir', 'Path')] [string] $ProjectDirectory = (Get-Location | Select-Object -ExpandProperty Path).ToString(), [string] $ResourceGroupLocation = 'eastus2', [object] $JsonParameters, [string] $TemplateFile ) # Parameter Layering - Deserialize all ARM template JSON documents and setup variables. $EnvironmentParameters = Get-Content "$ProjectDirectory\env\$ResourceGroupLocation\$Environment\environment.parameters.json" -Raw | ConvertFrom-Json $moduleDeployJson = Get-Content "$ProjectDirectory\schema.template.json" -Raw | ConvertFrom-Json $moduleDeployJson.resources = @() # Determine which deployments and modules will be used for either a full deployment or for manually selected modules. if ($modules) { $modulesList = $modules } else { $modulesList = $EnvironmentParameters.parameters.modules.value | Get-Member -MemberType NoteProperty | Where-Object { $_.Definition -match "[1]" } | Select-Object -ExpandProperty Name } # This loops through the folders of every module subdirectory in the environment and adds all the top level parameters to $moduleDeployJson. $AllModulesParamList = @() $script:AllModulesUsedList = @() $modulenames = @() $DefaultParameters = $moduleDeployJson.parameters | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name $modulesList | ForEach-Object { if (Test-Path -Path "$ProjectDirectory\modules\$($_)\metadata.json") { $moduleJson = Get-Content "$ProjectDirectory\modules\$($_)\metadata.json" -Raw | ConvertFrom-Json $modulenames += $moduleJson.modulenames } else { $modulenames += $_ } # Adds the current module name to the parameters so it can use a unique set of module parameters. # Will default to the module name if no valid module was found. $AllModulesParamList += $modulenames $script:AllModulesUsedList += $modulenames foreach ($modulename in $modulenames) { $ModuleParameters = Get-Content "$ProjectDirectory\modules\$modulename\module.json" -Raw | ConvertFrom-Json $ModuleParamList = $ModuleParameters.parameters | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name $AllModulesParamList += $ModuleParamList } $moduleDeployJson.parameters | Add-Member -MemberType NoteProperty -Name $_ -Value (New-Object -TypeName PSCustomObject) -Force $moduleDeployJson.parameters.$_ | Add-Member -MemberType NoteProperty -Name 'type' -Value "Object" -Force } # Trim off deployment parameters not needed by the called modules. $AllModulesParamList = $AllModulesParamList | Select-Object -Unique $DeploymentParamList = $moduleDeployJson.parameters | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name $DeploymentParamList = $DeploymentParamList | Where-Object { $_ -notmatch "_artifactsLocation|EnvName" } # $DeploymentParamList | ForEach-Object { # if ($_ -eq "Global") { # $moduleDeployJson.parameters | Add-Member -MemberType NoteProperty -Name "Global" -Value (New-Object -TypeName PSCustomObject) -Force # $moduleDeployJson.parameters.$_ | Add-Member -MemberType NoteProperty -Name 'type' -Value "Object" -Force # } # elseif ($AllModulesParamList -notcontains $_) { # $moduleDeployJson.parameters = $moduleDeployJson.parameters | Select-Object -ExcludeProperty $_ # } # } #Build out deployment resources to run each requested module in the template. foreach ($module in $modulesList) { try { Write-Verbose "module: $module" New-OsDeploymentResource -ProjectDirectory $ProjectDirectory -module $module -DefaultParameters $DefaultParameters -ResourceGroupLocation $ResourceGroupLocation -Environment $Environment -ErrorAction Stop $moduleDeployJson.resources += $DeploymentResourceJson } catch { Write-Warning "Could not create a deployment resource for module $module! Please check the modules metadata file!`n$_" } } if (-not (Test-Path -Path "$ProjectDirectory\temp")) { New-Item -Path "$ProjectDirectory\temp" -ItemType Directory } $moduleDeployJson | ConvertTo-Json -Depth 100 | Out-File "$ProjectDirectory\temp\latest-module-deploy.json" $script:AllModulesUsedList = $script:AllModulesUsedList | Select-Object -Unique | Sort-Object Write-Host "modules: $script:AllModulesUsedList" -ForegroundColor Green Write-Verbose "All module params: $AllModulesParamList" } |