DSL/VaporShell.DSL.psm1
function Template { [CmdletBinding()] Param ( [parameter(Mandatory = $true,Position = 0)] [System.Management.Automation.ScriptBlock] $Contents, [parameter(Mandatory = $false)] [ValidateScript({[System.Text.Encoding]::UTF8.GetByteCount($_) -in 0..1024})] [Alias('Desc')] [System.String] $Description, [parameter(Mandatory = $false)] [ValidateSet("2010-09-09")] [Alias('Vers')] [System.String] $FormatVersion ) Begin { $script:templateObjects = @{ Resources = New-Object System.Collections.ArrayList Mappings = New-Object System.Collections.ArrayList Conditions = New-Object System.Collections.ArrayList Parameters = New-Object System.Collections.ArrayList Outputs = New-Object System.Collections.ArrayList Transforms = New-Object System.Collections.ArrayList Metadata = New-Object System.Collections.ArrayList } $initParams = @{} @('Description','FormatVersion') | ForEach-Object { if ($PSBoundParameters.Keys -contains $_) { $initParams[$_] = $PSBoundParameters[$_] } } $template = Initialize-Vaporshell @initParams } Process { $Contents.Invoke() } End { foreach ($object in $script:templateObjects['Resources']) { Write-Verbose "Adding Resource '$($object.LogicalId)' to template" $template.AddResource($object) } foreach ($object in $script:templateObjects['Mappings']) { Write-Verbose "Adding Mapping '$($object.LogicalId)' to template" $template.AddMapping($object) } foreach ($object in $script:templateObjects['Conditions']) { Write-Verbose "Adding Condition '$($object.LogicalId)' to template" $template.AddCondition($object) } foreach ($object in $script:templateObjects['Parameters']) { Write-Verbose "Adding Parameter '$($object.LogicalId)' to template" $template.AddParameter($object) } foreach ($object in $script:templateObjects['Outputs']) { Write-Verbose "Adding Output '$($object.LogicalId)' to template" $template.AddOutput($object) } foreach ($object in $script:templateObjects['Transforms']) { Write-Verbose "Adding Include Location '$($object.Props.Parameters.Location)' to template" $template.AddTransform($object) } foreach ($object in $script:templateObjects['Metadata']) { Write-Verbose "Adding Metadata '$($object.LogicalId)' to template" $template.AddMetadata($object) } return $template } } function Resource { [CmdletBinding()] Param () DynamicParam { $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $ParamName_ResourceType = 'ResourceType' $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute $ParameterAttribute.Mandatory = $true $ParameterAttribute.Position = 0 $AttributeCollection.Add($ParameterAttribute) $prevErrAct = $ErrorActionPreference $ErrorActionPreference = 'SilentlyContinue' $arrSet = (Get-Command -Module VaporShell | Where-Object {$_.OutputType -and $_.OutputType -like '*Vaporshell.Resource.*' -and $_.Name -Like 'New-VS*'} -ErrorAction SilentlyContinue).Name.Replace('New-VS','') | Sort-Object $ErrorActionPreference = $prevErrAct $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet) $AttributeCollection.Add($ValidateSetAttribute) $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParamName_ResourceType, [System.String], $AttributeCollection) $RuntimeParameterDictionary.Add($ParamName_ResourceType, $RuntimeParameter) $ParamName_LogicalId = 'LogicalId' $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute $ParameterAttribute.Mandatory = $true $ParameterAttribute.Position = 1 $AttributeCollection.Add($ParameterAttribute) $validationScriptBlock = [System.Management.Automation.ScriptBlock]{ if ($_ -match "^[a-zA-Z0-9]*$") { $true } else { $PSCmdlet.ThrowTerminatingError((New-VSError -String 'The LogicalID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.')) } } $ValidateScriptAttribute = New-Object System.Management.Automation.ValidateScriptAttribute($validationScriptBlock) $AttributeCollection.Add($ValidateScriptAttribute) $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParamName_LogicalId, [System.String], $AttributeCollection) $RuntimeParameterDictionary.Add($ParamName_LogicalId, $RuntimeParameter) $ParamName_Properties = 'Properties' $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute $ParameterAttribute.Mandatory = $true $ParameterAttribute.Position = 2 $AttributeCollection.Add($ParameterAttribute) $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParamName_Properties, [System.Management.Automation.ScriptBlock], $AttributeCollection) $RuntimeParameterDictionary.Add($ParamName_Properties, $RuntimeParameter) return $RuntimeParameterDictionary } Process { $scriptBlockString = "`$props = @{$($PSBoundParameters['Properties'].ToString())}; New-VS$($PSBoundParameters['ResourceType']) -LogicalId '$($PSBoundParameters['LogicalId'])' @props" $newScriptBlock = [ScriptBlock]::Create($scriptBlockString) $object = & $newScriptBlock $script:templateObjects['Resources'].Add($object) | Out-Null } } function Mapping { [CmdletBinding()] Param ( [parameter(Mandatory = $true,Position = 0)] [ValidateScript( { if ($_ -match "^[a-zA-Z0-9]*$") { $true } else { $PSCmdlet.ThrowTerminatingError((New-VSError -String 'The LogicalID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.')) } })] [System.String] $LogicalId, [parameter(Mandatory = $true,Position = 1)] [Hashtable] $Map ) Process { $object = New-VaporMapping -LogicalId $LogicalId -Map $Map -Verbose:$false $script:templateObjects['Mappings'].Add($object) | Out-Null } } function CustomResource { [CmdletBinding()] Param ( [parameter(Mandatory = $true,Position = 0)] [System.String] $ResourceType, [parameter(Mandatory = $true,Position = 1)] [ValidateScript( { if ($_ -match "^[a-zA-Z0-9]*$") { $true } else { $PSCmdlet.ThrowTerminatingError((New-VSError -String 'The LogicalID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.')) } })] [System.String] $LogicalId, [parameter(Mandatory = $true,Position = 2)] [System.Management.Automation.ScriptBlock] $Properties ) Process { $scriptBlockString = "`$props = @{$($PSBoundParameters['Properties'].ToString())}; New-VaporResource -LogicalId '$($PSBoundParameters['LogicalId'])' -Type '$($PSBoundParameters['ResourceType'])' @props" $newScriptBlock = [ScriptBlock]::Create($scriptBlockString) $object = & $newScriptBlock $script:templateObjects['Resources'].Add($object) | Out-Null } } function Output { [CmdletBinding()] Param ( [parameter(Mandatory = $true,Position = 0)] [ValidateScript( { if ($_ -match "^[a-zA-Z0-9]*$") { $true } else { $PSCmdlet.ThrowTerminatingError((New-VSError -String 'The LogicalID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.')) } })] [System.String] $LogicalId, [parameter(Mandatory = $true,Position = 1)] [System.Management.Automation.ScriptBlock] $Properties ) Process { $scriptBlockString = "`$props = @{$($PSBoundParameters['Properties'].ToString())}; New-VaporOutput -LogicalId '$($PSBoundParameters['LogicalId'])' @props" $newScriptBlock = [ScriptBlock]::Create($scriptBlockString) $object = & $newScriptBlock $script:templateObjects['Outputs'].Add($object) | Out-Null } } function Condition { [CmdletBinding()] Param ( [parameter(Mandatory = $true,Position = 0)] [ValidateScript( { if ($_ -match "^[a-zA-Z0-9]*$") { $true } else { $PSCmdlet.ThrowTerminatingError((New-VSError -String 'The LogicalID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.')) } })] [System.String] $LogicalId, [parameter(Mandatory = $true,Position = 1)] [ValidateScript( { $allowedTypes = "Vaporshell.Condition.And","Vaporshell.Condition.Equals","Vaporshell.Condition.If","Vaporshell.Condition.Not","Vaporshell.Condition.Or" if ([string]$($_.PSTypeNames) -match "($(($allowedTypes|ForEach-Object{[RegEx]::Escape($_)}) -join '|'))") { $true } else { $PSCmdlet.ThrowTerminatingError((New-VSError -String "This parameter only accepts the following types: $($allowedTypes -join ", "). The current types of the value are: $($_.PSTypeNames -join ", ").")) } })] $Condition ) Process { $object = New-VaporCondition -LogicalId $LogicalId -Condition $Condition $script:templateObjects['Conditions'].Add($object) | Out-Null } } function Parameter { [CmdletBinding()] Param ( [parameter(Mandatory = $true,Position = 0)] [ValidateScript( { if ($_ -match "^[a-zA-Z0-9]*$") { $true } else { $PSCmdlet.ThrowTerminatingError((New-VSError -String 'The LogicalID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.')) } })] [System.String] $LogicalId, [parameter(Mandatory = $true,Position = 1)] [System.Management.Automation.ScriptBlock] $Properties ) Process { $scriptBlockString = "`$props = @{$($PSBoundParameters['Properties'].ToString())}; New-VaporParameter -LogicalId '$($PSBoundParameters['LogicalId'])' @props" $newScriptBlock = [ScriptBlock]::Create($scriptBlockString) $object = & $newScriptBlock $script:templateObjects['Parameters'].Add($object) | Out-Null } } function Metadata { [CmdletBinding()] Param ( [parameter(Mandatory = $true,Position = 0)] [ValidateScript( { if ($_ -match "^[a-zA-Z0-9]*$") { $true } else { $PSCmdlet.ThrowTerminatingError((New-VSError -String 'The LogicalID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.')) } })] [System.String] $LogicalId, [parameter(Mandatory = $true,Position = 1)] [Hashtable] $Metadata ) Process { $object = New-VaporMetadata -LogicalId $LogicalId -Metadata $Metadata -Verbose:$false $script:templateObjects['Metadata'].Add($object) | Out-Null } } function Transform { [CmdletBinding()] Param ( [parameter(Mandatory = $true,Position = 0)] [ValidatePattern("^s3:\/\/.*")] [System.String] $Location ) Process { $object = Add-Include -Location $Location -Verbose:$false $script:templateObjects['Transforms'].Add($object) | Out-Null } } Export-ModuleMember -Function Template,Resource,Mapping,CustomResource,Output,Condition,Parameter,Metadata,Transform |