Az.Extensions.DynamicDeployment.psm1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
function Get-ExpandedString { [cmdletbinding()] param($data, $prefix='$pwsh[', $lastChar=']') if($data -and $data.IndexOf($prefix) -gt -1 -and $data.EndsWith($lastChar)){ Write-Verbose "Expanding $data" $data = $data.Replace($prefix,''); $data = $data.Substring(0, $data.length-1) $hasFunctionStart = $data.IndexOf('{'); $hasFunctionEnd = $data.IndexOf('}'); $expandedString = $ExecutionContext.InvokeCommand.ExpandString($data) # Allow expressions such as a($b) or a(-paramName '$b') translating into a -paramName 'value' if($hasFunctionStart -gt -1 -and $hasFunctionEnd -gt -1){ $expandedString = $expandedString.Substring($expandedString.IndexOf('{')+1, $expandedString.IndexOf('}')-1) $expandedString = Invoke-Expression $expandedString } return $expandedString } else { Write-Verbose "Value does not have magic string format" return $data } } function Get-FileContentFromUri { [cmdletbinding()] param ( $uri ) $tempFile = New-TemporaryFile; [void](Invoke-WebRequest -uri $uri -OutFile $tempFile.FullName) return (Get-Content $file.FullName) } <# .SYNOPSIS Parses a parameters file/uri and returns the expanded parameters in a hashtable to be used for deployment .DESCRIPTION Returns a hashtable to be used for deployment, with values expanded - supporting Powershell variables and simple expressions .EXAMPLE PS C:\> Add-AzAccount PS C:\> $myVar = 'The Variable Content PS C:\> $params = Expand-AZParameters -TemplateParameterUri 'https://www.github.com/haraldfianbakken/Az.Extensions.DynamicDeployment/Templates/Simple.Params.json PS C:\> $params PS C:\> New-AZResourceGroupDeployment -TemplateUri https://www.github.com/haraldfianbakken/Az.Extensions.DynamicDeployment/Templates/Simple.json -TemplateParameterObject $params Sets the variable found in the dynamics parameters and expands it. You can use the params in any deployment as fit. .EXAMPLE PS C:\> Add-AzAccount PS C:\> function func($testParam){ "Hello $testParam"} PS C:\> $params = Expand-AZParameters -TemplateParameterUri 'https://www.github.com/haraldfianbakken/Az.Extensions.DynamicDeployment/Templates/UsingFunc.Params.json PS C:\> New-AZResourceGroupDeployment -TemplateObject $template -TemplateParameterObject $params .EXAMPLE PS C:\> Add-AzAccount PS C:\> $params = Expand-AZParameters -TemplateParameterUri 'https://www.github.com/haraldfianbakken/Az.Extensions.DynamicDeployment/Templates/Complex.Params.json PS C:\> New-AZResourceGroupDeployment -TemplateObject $template -TemplateParameterObject $params This demonstates a complex template - which has an expression - calling out to ARM, selecting your Storage accounts (first one) and its name into the parameter. .INPUTS -TemplateParameterUri Uri of the parameters file -TemplateParameterFile Local path of the parameters file .OUTPUTS Hashtable of expanded variables #> function Expand-AzParameters { [cmdletbinding()] param( [Parameter(Position = 0, Mandatory=$true, ParameterSetName = 'UriSet')] [Uri] $templateParameterUri, [Parameter(Position = 0, Mandatory=$true, ParameterSetName = 'FileSet')] [String] $templateParameterFile ) begin { $content = ""; switch ($PSCmdlet.ParameterSetName) { 'UriSet' { $content = Get-FileContentFromUri -uri $templateParameterUri; } 'FileSet' { $content = Get-Content $templateParameterFile -Raw; } } $paramsJson = $content | ConvertFrom-Json if($paramsJson.'$schema'.IndexOf('deploymentParameters.json') -eq -1){ Write-Error 'Invalid parameters file passed' exit 1; } $paramsAsHashTable = $content | ConvertFrom-Json -AsHashtable } process { $paramsAsHashTable.parameters.Keys|ForEach-Object { $paramsJson.parameters."$_".value = Get-ExpandedString -data $paramsJson.parameters."$_".value } } end { $paramsObject=$paramsJson.parameters; # Parmas Object needs to be simpler $o = @{} $paramsAsHashTable.parameters.keys|ForEach-Object { $o.Add($_, $paramsJson.parameters."$_".Value) } return $o; # $paramsJson|ConvertTo-Json # return $paramsObject|ConvertTo-Json|ConvertFrom-Json -AsHashtable; } } <# .SYNOPSIS Parses a parameters file/uri and returns the expanded template in a hashtable to be used for deployment .DESCRIPTION Returns a hashtable to be used for deployment - with default values (parameters) expanded - supporting Powershell variables and simple expressions .EXAMPLE PS C:\> Add-AZAccount PS C:\> $myVar = 'The Variable Content PS C:\> $template = Expand-AzTemplate -TemplateParameterUri 'https://www.github.com/haraldfianbakken/Az.Extensions.DynamicDeployment/Templates/Simple.json PS C:\> $template PS C:\> New-AZResourceGroupDeployment -TemplateObject $template -TemplateParameterUri $paramsUri Expanding variables from Powershell into the default value params. .EXAMPLE PS C:\> Add-AzAccount PS C:\> function func($testParam){ "Hello $testParam"} PS C:\> $template = Expand-AzTemplate -TemplateParameterUri 'https://www.github.com/haraldfianbakken/Az.Extensions.DynamicDeployment/Templates/UsingFunc.json PS C:\> $template PS C:\> New-AZResourceGroupDeployment -TemplateObject $template -TemplateParameterUri $paramsUri Showing how to create a function returning a value that is expanded into the template before deployment .EXAMPLE PS C:\> Add-AzAccount PS C:\> $params = Expand-AzTemplate -TemplateParameterUri 'https://www.github.com/haraldfianbakken/Az.Extensions.DynamicDeployment/Templates/Complex.json PS C:\> $template PS C:\> New-AZResourceGroupDeployment -TemplateObject $template -TemplateParameterUri $paramsUri This demonstates a complex template - which has an expression - calling out to ARM, selecting your Storage accounts (first one) and its name into the parameter. .INPUTS -TemplateUri Uri of the template file -TemplateFile Local path of the template file .OUTPUTS Hashtable of expanded variables #> function Expand-AzTemplate { [cmdletbinding()] param( [Parameter(Position = 0, Mandatory=$true, ParameterSetName = 'UriSet')] [Uri] $templateUri, [Parameter(Position = 0, Mandatory=$true, ParameterSetName = 'FileSet')] [String] $templateFile ) begin { $content = ""; switch ($PSCmdlet.ParameterSetName) { 'UriSet' { $content = Get-FileContentFromUri -uri $templateUri; } 'FileSet' { $content = Get-Content $templateFile -Raw; } } $templateJson = $content | ConvertFrom-Json if($templateJson.'$schema'.IndexOf('deploymentTemplate.json') -eq -1){ Write-Error 'Invalid parameters file passed' exit 1; } $templateAsHashTable = $content | ConvertFrom-Json -AsHashtable } process { $templateAsHashTable.parameters.Keys|ForEach-Object { if($templateJson.parameters."$_".defaultvalue){ $templateJson.parameters."$_".defaultvalue = Get-ExpandedString -data $templateJson.parameters."$_".defaultvalue } else { Write-Verbose "$_ does not have a default value" } } } end { return $templateJson|ConvertTo-Json|ConvertFrom-Json -AsHashtable; } } |