VaporShell.psm1

[CmdletBinding()]
Param ()
$VaporshellPath = $PSScriptRoot
function Add-ObjectDetail {
    <#
    .SYNOPSIS
        Decorate an object with
            - A TypeName
            - New properties
            - Default parameters

        ** This is a stripped down version of the function built out by Warren Frame -- http://ramblingcookiemonster.github.io/Decorating-Objects/ | https://github.com/RamblingCookieMonster/PSStackExchange/blob/master/PSStackExchange/Private/Add-ObjectDetail.ps1

    .DESCRIPTION
        Helper function to decorate an object with
            - A TypeName
            - New properties
            - Default parameters

    .PARAMETER InputObject
        Object to decorate. Accepts pipeline input.

    .PARAMETER TypeName
        Typenames to insert.
        
        This will show up when you use Get-Member against the resulting object.

    .PARAMETER Passthru
        Whether to pass the resulting object on. Defaults to true

    .NOTES
        This breaks the 'do one thing' rule from certain perspectives...
        The goal is to decorate an object all in one shot
   
        This abstraction simplifies decorating an object, with a slight trade-off in performance. For example:

        10,000 objects, add a property and typename:
            Add-ObjectDetail: ~4.6 seconds
            Add-Member + PSObject.TypeNames.Insert: ~3 seconds

        Initial code borrowed from Shay Levy:
        http://blogs.microsoft.co.il/scriptfanatic/2012/04/13/custom-objects-default-display-in-powershell-30/
        
    .LINK
        http://ramblingcookiemonster.github.io/Decorating-Objects/

    .FUNCTIONALITY
        PowerShell Language
    #>

    [CmdletBinding()] 
    param(
        [Parameter( Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true )]
        [ValidateNotNullOrEmpty()]
        [psobject[]]$InputObject,

        [Parameter( Mandatory = $true,
            Position = 1)]
        [string[]]$TypeName,

        [boolean]$Passthru = $True
    )
    
    Process {
        foreach ($Object in $InputObject) {
            #Add specified type(s)
            foreach ($T in $TypeName) {
                [void]$Object.PSObject.TypeNames.Insert(0,$T)
            }
            if ($Passthru) {
                $Object
            }
        }
    }
}

function Colorize {
    Param
    (
        [parameter(Mandatory = $false, Position = 0, ValueFromPipeline = $true)]
        [String[]]
        $Strings
    )
    Process {
        foreach ($row in $Strings) {
            $hostParams = @{
                Object   = $row
                NoNewLine = $true
            }
            switch -Regex -CaseSensitive ($row) {
                "(STACK NAME|REFRESH)" {
                    $hostParams['ForegroundColor'] = 'Black'
                    $hostParams['BackgroundColor'] = 'Cyan'
                }
                "_FAILED" {
                    if ($row -match 'AWS::CloudFormation::Stack') {
                        $hostParams['ForegroundColor'] = 'White'
                        $hostParams['BackgroundColor'] = 'DarkRed'
                    }
                    else {
                        $hostParams['ForegroundColor'] = 'Black'
                        $hostParams['BackgroundColor'] = 'Red'
                    }
                }
                "REVIEW_IN_PROGRESS" {
                    $hostParams['ForegroundColor'] = 'Black'
                    $hostParams['BackgroundColor'] = 'Red'
                }
                "ROLLBACK_IN_PROGRESS" {
                    $hostParams['ForegroundColor'] = 'Cyan'
                }
                "ROLLBACK_COMPLETE" {
                    $hostParams['ForegroundColor'] = 'Black'
                    $hostParams['BackgroundColor'] = 'Cyan'
                }
                "(UPDATE_IN_PROGRESS|CREATE_IN_PROGRESS|IMPORT_IN_PROGRESS)" {
                    if ($row -match 'AWS::CloudFormation::Stack') {
                        $hostParams['ForegroundColor'] = 'White'
                        $hostParams['BackgroundColor'] = 'DarkMagenta'
                    }
                    else {
                        $hostParams['ForegroundColor'] = 'Green'
                    }
                }
                "(UPDATE_COMPLETE|CREATE_COMPLETE|IMPORT_COMPLETE)" {
                    if ($row -match 'AWS::CloudFormation::Stack') {
                        $hostParams['ForegroundColor'] = 'White'
                        $hostParams['BackgroundColor'] = 'DarkGreen'
                    }
                    else {
                        $hostParams['ForegroundColor'] = 'Black'
                        $hostParams['BackgroundColor'] = 'Green'
                    }
                }
                "DELETE_IN_PROGRESS" {
                    $hostParams['ForegroundColor'] = 'Yellow'
                }
                "DELETE_COMPLETE" {
                    $hostParams['ForegroundColor'] = 'Black'
                    $hostParams['BackgroundColor'] = 'Yellow'
                }
                "DELETE_SKIPPED" {
                    $hostParams['ForegroundColor'] = 'Black'
                    $hostParams['BackgroundColor'] = 'Magenta'
                }
            }
            Write-Host @hostParams
            Write-Host ''
        }
    }
}

function Format-Json {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
        [String]
        $Json
    )
    Begin {
        $cleaner = {
            param([String]$Line)
            Process{
                [Regex]::Replace(
                    $Line,
                    "\\u(?<Value>[a-zA-Z0-9]{4})",
                    {
                        param($m)([char]([int]::Parse(
                            $m.Groups['Value'].Value,
                            [System.Globalization.NumberStyles]::HexNumber
                        ))).ToString()
                    }
                )
            }
        }
    }
    Process {
        if ($PSVersionTable.PSVersion.Major -lt 6) {
            try {
                $indent = 0;
                $res = $Json -split '\n' | ForEach-Object {
                    if ($_ -match '[\}\]]') {
                        # This line contains ] or }, decrement the indentation level
                        $indent--
                    }
                    $line = (' ' * $indent * 2) + $_.TrimStart().Replace(': ', ': ')
                    if ($_ -match '[\{\[]') {
                        # This line contains [ or {, increment the indentation level
                        $indent++
                    }
                    $cleaner.Invoke($line)
                }
                $res -join "`n"
            }
            catch {
                ($Json -split '\n' | ForEach-Object {$cleaner.Invoke($_)}) -join "`n"
            }
        }
        else {
            ($Json -split '\n' | ForEach-Object {$cleaner.Invoke($_)}) -join "`n"
        }
    }
}

function Get-TrueCount {
    Param
    (
        [parameter(Mandatory = $false,Position = 0,ValueFromPipeline = $true)]
        $Array
    )
    Process {
        if ($array) {
            if ($array.Count) {
                $count = $array.Count
            }
            else {
                $count = 1
            }
        }
        else {
            $count = 0
        }
    }
    End {
        return $count
    }
}

function Import-AWSSDK {
    [CmdletBinding()]
    Param()
    Process {
        # Load the AWSSDK assemblies without conflict and kill any warning messages thrown by AWS.Tools.* modules
        try {
            $currentWarningPref = $WarningPreference
            $WarningPreference = "SilentlyContinue"
            $currentErrorPref = $ErrorActionPreference
            $ErrorActionPreference = "SilentlyContinue"
            $awsModules = if ($tools = (Get-Module AWS.Tools* -ListAvailable -Verbose:$false).Name | Where-Object {$_ -match '^AWS\.Tools\.(CloudFormation|S3)$'}) {
                $tools | Select-Object -Unique
            }
            else {
                (Get-Module AWS* -ListAvailable -Verbose:$false).Name | Select-Object -Unique
            }
            @(
                'AWSSDK.CloudFormation.dll'
                'AWSSDK.S3.dll'
            ) | ForEach-Object {
                $assemblyName = $_
                if ($null -eq ([System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object {$_.Location -match $assemblyName})) {
                    $toolsModule = switch ($assemblyName) {
                        'AWSSDK.CloudFormation.dll' {'AWS.Tools.CloudFormation'}
                        'AWSSDK.S3.dll' {'AWS.Tools.S3'}
                    }
                    if ($awsModules -contains $toolsModule) {
                        Write-Verbose "Importing $assemblyName via module $toolsModule"
                        Import-Module $toolsModule -Verbose:$false -ErrorAction SilentlyContinue
                    }
                    elseif ($awsModules -contains 'AWSPowerShell.NetCore') {
                        Write-Verbose "Importing $assemblyName via module AWSPowerShell.NetCore"
                        Import-Module 'AWSPowerShell.NetCore' -Verbose:$false -ErrorAction SilentlyContinue
                    }
                    elseif ($awsModules -contains 'AWSPowerShell') {
                        Write-Verbose "Importing $assemblyName via module AWSPowerShell"
                        Import-Module 'AWSPowerShell' -Verbose:$false -ErrorAction SilentlyContinue
                    }
                    else {
                        Write-Verbose "Importing $assemblyName from VaporShell module base"
                        [System.Reflection.Assembly]::LoadFrom((Join-Path $PSScriptRoot $assemblyName)) | Out-Null
                    }
                }
            }
        }
        catch {}
        finally {
            $WarningPreference = $currentWarningPref
            $ErrorActionPreference = $currentErrorPref
        }
    }
}

function New-VSError {
    <#
    .SYNOPSIS
    Error generator function to use in tandem with $PSCmdlet.ThrowTerminatingError()
    
    .PARAMETER Result
    Allows input of an error from AWS SDK, resulting in the Exception message being parsed out.
    
    .PARAMETER String
    Used to create basic String message errors in the same wrapper
    #>

    [cmdletbinding(DefaultParameterSetName="Result")]
    param(
        [parameter(Position=0,ParameterSetName="Result")]
        $Result,
        [parameter(Position=0,ParameterSetName="String")]
        $String
    )
    switch ($PSCmdlet.ParameterSetName) {
        Result { $Exception = "$($result.Exception.InnerException.Message)" }
        String { $Exception = "$String" }
    }
    $e = New-Object "System.Exception" $Exception
    $errorRecord = New-Object 'System.Management.Automation.ErrorRecord' $e, $null, ([System.Management.Automation.ErrorCategory]::InvalidOperation), $null
    return $errorRecord
}

function ProcessRequest {
    <#
    .SYNOPSIS
    Receives AWS SDK requests, then sends them to the appropriate processor function depending on PowerShell version, as PSv3 does not allow dot sourcing method names.
    #>

    [cmdletbinding()]
    Param
    (
        [parameter(Mandatory = $false,Position=0)]
        [String]
        $ParameterSetName,
        [parameter(Mandatory = $false,Position=1)]
        [String]
        $ProfileName = $env:AWS_PROFILE,
        [parameter(Mandatory = $true,Position=2)]
        [String]
        $Method,
        [parameter(Mandatory = $true,Position=3)]
        $Request,
        [parameter(Mandatory = $false,Position=4)]
        [String]
        $Expand
    )
    Process {
        if ($PSVersionTable.PSVersion.Major -eq 3) {
            ProcessRequest3 @PSBoundParameters
        }
        else {
            ProcessRequest4 @PSBoundParameters
        }
    }
}

function ProcessRequest3 {
    <#
    .SYNOPSIS
    Receives AWS SDK requests, then sends them to the appropriate processor function depending on PowerShell version, as PSv3 does not allow dot sourcing method names.
    #>

    [cmdletbinding()]
    Param
    (
        [parameter(Mandatory = $false,Position=0)]
        [String]
        $ParameterSetName,
        [parameter(Mandatory = $false,Position=1)]
        [String]
        $ProfileName = $env:AWS_PROFILE,
        [parameter(Mandatory = $true,Position=2)]
        [String]
        $Method,
        [parameter(Mandatory = $true,Position=3)]
        $Request,
        [parameter(Mandatory = $false,Position=4)]
        [String]
        $Expand
    )
    Process {
        if (!$ProfileName) {
            $ProfileName = "default"
            $PSBoundParameters["ProfileName"] = "default"
        }
        $results = @()
        try {
            $service = ($request.PSObject.TypeNames)[0].split('.')[1]
            $sharedFile = New-Object Amazon.Runtime.CredentialManagement.SharedCredentialsFile -ErrorAction Stop
            $matchedProfile = $sharedFile.ListProfiles() | Where-Object {$_.Name -eq $ProfileName}
            if ($null -eq $matchedProfile) {
                $creds = [Amazon.Runtime.FallbackCredentialsFactory]::GetCredentials()
                $endPoint = if ([Amazon.Runtime.FallbackRegionFactory]::GetRegionEndpoint()) {
                    [Amazon.Runtime.FallbackRegionFactory]::GetRegionEndpoint()
                }
                else {
                    # Need to set a default if we can't resolve the region
                    Write-Warning "Unable to resolve target region! Defaulting to us-east-1 and continuing in 5 seconds."
                    Write-Warning "If you do not want to execute method [$Method] on service [$service] in this region,"
                    Write-Warning "please set the environment variable 'AWS_REGION' or run the following to set a region"
                    Write-Warning "on the shared credential file:`n`n`tSet-VSCredential -ProfileName $ProfileName -Region <PREFERRED REGION>"
                    Start-Sleep -Seconds 5
                    [Amazon.RegionEndpoint]::USEast1
                }
            }
            else {
                $creds = New-Object Amazon.Runtime.StoredProfileAWSCredentials $ProfileName -ErrorAction Stop
                $endPoint = if ($matchedProfile.Region) {
                    $matchedProfile.Region
                }
                elseif ([Amazon.Runtime.FallbackRegionFactory]::GetRegionEndpoint()) {
                    [Amazon.Runtime.FallbackRegionFactory]::GetRegionEndpoint()
                }
                else {
                    # Need to set a default if we can't resolve the region
                    Write-Warning "Unable to resolve target region! Defaulting to us-east-1 and continuing in 5 seconds."
                    Write-Warning "If you do not want to execute method [$Method] on service [$service] in this region,"
                    Write-Warning "please set the environment variable 'AWS_REGION' or run the following to set a region"
                    Write-Warning "on the shared credential file:`n`n`tSet-VSCredential -ProfileName $ProfileName -Region <PREFERRED REGION>"
                    Start-Sleep -Seconds 5
                    [Amazon.RegionEndpoint]::USEast1
                }
            }
            Write-Verbose "Building '$service' client in region '$($endPoint.DisplayName)' [$($endPoint.SystemName)]"
            if ($endPoint) {
                $client = New-Object "Amazon.$($service).Amazon$($service)Client" $creds,$endPoint -ErrorAction Stop
            }
            else {
                return (New-VSError -String "No region set for profile '$ProfileName'! Please run the following to set a region:`n`nSet-VSCredential -ProfileName $ProfileName -Region <PREFERRED REGION>")
            }
        }
        catch {
            return (New-VSError -String "$($_.Exception.Message)")
        }
        Write-Verbose "Processing request:`n$($PSBoundParameters | Format-Table -AutoSize | Out-String)"
        $i = 0
        do {
            $i++
            $result = $client.PSObject.Methods[$Method].Invoke($Request)
            if ($Expand) {
                $results += $result.$Expand
            }
            else {
                $results += $result
            }
            if ($result.NextToken -and !$request.MaxResults) {
                $Request.NextToken = $result.NextToken
                $done = $false
            }
            else {
                $done = $true
            }
        }
        until ($done)
        if (!$result) {
            return
        }
        if ($results) {
            return $results
        }
        elseif ($IsCoreCLR) {
            if ($result.Result) {
                return $result.Result
            }
            elseif ($result.Exception) {
                return (New-VSError $result)
            }
        }
        else {
            return $result
        }
    }
}

function ProcessRequest4 {
    <#
    .SYNOPSIS
    Receives AWS SDK requests, then sends them to the appropriate processor function depending on PowerShell version, as PSv3 does not allow dot sourcing method names.
    #>

    [cmdletbinding()]
    Param
    (
        [parameter(Mandatory = $false,Position=0)]
        [String]
        $ParameterSetName,
        [parameter(Mandatory = $false,Position=1)]
        [String]
        $ProfileName = $env:AWS_PROFILE,
        [parameter(Mandatory = $true,Position=2)]
        [String]
        $Method,
        [parameter(Mandatory = $true,Position=3)]
        $Request,
        [parameter(Mandatory = $false,Position=4)]
        [String]
        $Expand
    )
    Process {
        if (!$ProfileName) {
            $ProfileName = "default"
            $PSBoundParameters["ProfileName"] = "default"
        }
        $results = @()
        try {
            $service = ($request.PSObject.TypeNames)[0].split('.')[1]
            $sharedFile = New-Object Amazon.Runtime.CredentialManagement.SharedCredentialsFile -ErrorAction Stop
            $matchedProfile = $sharedFile.ListProfiles() | Where-Object {$_.Name -eq $ProfileName}
            if ($null -eq $matchedProfile) {
                $creds = [Amazon.Runtime.FallbackCredentialsFactory]::GetCredentials()
                $endPoint = if ([Amazon.Runtime.FallbackRegionFactory]::GetRegionEndpoint()) {
                    [Amazon.Runtime.FallbackRegionFactory]::GetRegionEndpoint()
                }
                else {
                    # Need to set a default if we can't resolve the region
                    Write-Warning "Unable to resolve target region! Defaulting to us-east-1 and continuing in 5 seconds."
                    Write-Warning "If you do not want to execute method [$Method] on service [$service] in this region,"
                    Write-Warning "please set the environment variable 'AWS_REGION' or run the following to set a region"
                    Write-Warning "on the shared credential file:`n`n`tSet-VSCredential -ProfileName $ProfileName -Region <PREFERRED REGION>"
                    Start-Sleep -Seconds 5
                    [Amazon.RegionEndpoint]::USEast1
                }
            }
            else {
                $creds = New-Object Amazon.Runtime.StoredProfileAWSCredentials $ProfileName -ErrorAction Stop
                $endPoint = if ($matchedProfile.Region) {
                    $matchedProfile.Region
                }
                elseif ([Amazon.Runtime.FallbackRegionFactory]::GetRegionEndpoint()) {
                    [Amazon.Runtime.FallbackRegionFactory]::GetRegionEndpoint()
                }
                else {
                    # Need to set a default if we can't resolve the region
                    Write-Warning "Unable to resolve target region! Defaulting to us-east-1 and continuing in 5 seconds."
                    Write-Warning "If you do not want to execute method [$Method] on service [$service] in this region,"
                    Write-Warning "please set the environment variable 'AWS_REGION' or run the following to set a region"
                    Write-Warning "on the shared credential file:`n`n`tSet-VSCredential -ProfileName $ProfileName -Region <PREFERRED REGION>"
                    Start-Sleep -Seconds 5
                    [Amazon.RegionEndpoint]::USEast1
                }
            }
            Write-Verbose "Building '$service' client in region '$($endPoint.DisplayName)' [$($endPoint.SystemName)]"
            if ($endPoint) {
                $client = New-Object "Amazon.$($service).Amazon$($service)Client" $creds,$endPoint -ErrorAction Stop
            }
            else {
                return (New-VSError -String "No region set for profile '$ProfileName'! Please run the following to set a region:`n`nSet-VSCredential -ProfileName $ProfileName -Region <PREFERRED REGION>")
            }
        }
        catch {
            return (New-VSError -String "$($_.Exception.Message)")
        }
        if ($client | Get-Member -MemberType Method -Name "$Method*" | Where-Object {$_.Name -eq "$($Method)Async"}) {
            $useAsync = $true
            Write-Verbose "Processing async request:`n$($PSBoundParameters | Format-Table -AutoSize | Out-String)"
        }
        else {
            $useAsync = $false
            Write-Verbose "Processing request:`n$($PSBoundParameters | Format-Table -AutoSize | Out-String)"
        }
        $i = 0
        do {
            $i++
            if ($useAsync) {
                $result = $client."$($Method)Async"($Request)
                if ($Expand) {
                    $results += $result.Result.$Expand
                }
                else {
                    $results += $result.Result
                }
            }
            else {
                $result = $client.$Method($Request)
                if ($Expand) {
                    $results += $result.$Expand
                }
                else {
                    $results += $result
                }
            }
            if ($result.Result.NextToken -and !$request.MaxResults) {
                $Request.NextToken = $result.Result.NextToken
                $done = $false
            }
            elseif ($result.NextToken -and !$request.MaxResults) {
                $Request.NextToken = $result.NextToken
                $done = $false
            }
            else {
                $done = $true
            }
        }
        until ($done)
        if (!$result) {
            return
        }
        if ($results) {
            return $results
        }
        elseif ($IsCoreCLR) {
            if ($result.Result) {
                return $result.Result
            }
            elseif ($result.Exception) {
                return (New-VSError $result)
            }
        }
        else {
            return $result
        }
    }
}

function ResolveS3Endpoint {
    <#
    .SYNOPSIS
    Resolves the S3 endpoint most appropriate for each region.
    #>

    Param
    (
      [parameter(Mandatory=$true,Position=0)]
      [ValidateSet("eu-west-2","ap-south-1","us-east-2","sa-east-1","us-west-1","us-west-2","eu-west-1","ap-southeast-2","ca-central-1","ap-northeast-2","us-east-1","eu-central-1","ap-southeast-1","ap-northeast-1")]
      [String]
      $Region
    )
    $endpointMap = @{
        "us-east-2" = "s3.us-east-2.amazonaws.com"
        "us-east-1" = "s3.amazonaws.com"
        "us-west-1" = "s3-us-west-1.amazonaws.com"
        "us-west-2" = "s3-us-west-2.amazonaws.com"
        "ca-central-1" = "s3.ca-central-1.amazonaws.com"
        "ap-south-1" = "s3.ap-south-1.amazonaws.com"
        "ap-northeast-2" = "s3.ap-northeast-2.amazonaws.com"
        "ap-southeast-1" = "s3-ap-southeast-1.amazonaws.com"
        "ap-southeast-2" = "s3-ap-southeast-2.amazonaws.com"
        "ap-northeast-1" = "s3-ap-northeast-1.amazonaws.com"
        "eu-central-1" = "s3.eu-central-1.amazonaws.com"
        "eu-west-1" = "s3-eu-west-1.amazonaws.com"
        "eu-west-2" = "s3.eu-west-2.amazonaws.com"
        "sa-east-1" = "s3-sa-east-1.amazonaws.com"
    }
    return $endpointMap[$Region]
}

function Add-ConAnd {
    <#
    .SYNOPSIS
        Adds the condition function "Fn::And" to a resource property

    .DESCRIPTION
        Returns true if all the specified conditions evaluate to true, or returns false if any one of the conditions evaluates to false. Fn::And acts as an AND operator. The minimum number of conditions that you can include is 2, and the maximum is 10.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-and

    .PARAMETER Conditions
        A collection of conditions in object form where each evaluates to true or false. There must be at least 2 conditions but no more than 10 defined.

    .EXAMPLE
        Add-ConAnd -Conditions (Add-ConEquals -FirstValue "sg-mysggroup" -SecondValue (Add-FnRef -Ref "ASecurityGroup")),(Add-ConEquals -FirstValue "Production" -SecondValue (Add-FnRef -Ref "Environment"))

        When the template is exported, this will convert to: {"Fn::And":[{"Fn::Equals":["sg-mysggroup",{"Ref":"ASecurityGroup"}]},{"Fn::Equals":["Production",{"Ref":"Environment"}]}]}

    .NOTES
        You can use the following functions in this condition statement:
            Fn::FindInMap
            Ref
            Other condition functions

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([ConAnd])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory = $true,Position = 0)]
        [ValidateCount(2,10)]
        [object[]]
        $Conditions
    )
    $obj = [ConAnd]::new($Conditions)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-ConAnd'

function Add-ConEquals {
    <#
    .SYNOPSIS
        Adds the condition function "Fn::Equals" to a resource property

    .DESCRIPTION
        Compares if two values are equal. Returns true if the two values are equal or false if they aren't.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-equals

    .PARAMETER FirstValue
        A value of any type that you want to compare against the SecondValue

    .PARAMETER SecondValue
        A value of any type that you want to compare against the FirstValue

    .EXAMPLE
        Add-ConEquals -FirstValue "sg-mysggroup" -SecondValue (Add-FnRef -Ref "ASecurityGroup")

        When the template is exported, this will convert to: {"Fn::Equals":["sg-mysggroup",{"Ref":"ASecurityGroup"}]}

    .EXAMPLE
        Add-ConEquals -FirstValue (Add-FnRef -Ref "EnvironmentType") -SecondValue "prod"

        When the template is exported, this will convert to: {"Fn::Equals":[{"Ref":"EnvironmentType"},"prod"]}

    .NOTES
        You can use the following functions in this condition statement:
            Fn::FindInMap
            Ref
            Other condition functions

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([ConEquals])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [object]
        $FirstValue,
        [parameter(Mandatory,Position = 1)]
        [object]
        $SecondValue
    )
    $obj = [ConEquals]::new($FirstValue,$SecondValue)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-ConEquals'

function Add-ConIf {
    <#
    .SYNOPSIS
        Adds the condition function "Fn::If" to a resource property

    .DESCRIPTION
        Returns one value if the specified condition evaluates to true and another value if the specified condition evaluates to false. Currently, AWS CloudFormation supports the Fn::If intrinsic function in the metadata attribute, update policy attribute, and property values in the Resources section and Outputs sections of a template. You can use the AWS::NoValue pseudo parameter as a return value to remove the corresponding property.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if

    .PARAMETER ConditionName
        A reference to a condition in the Conditions section. Use the condition's name to reference it.

    .PARAMETER ValueIfTrue
        A value to be returned if the specified condition evaluates to true.

    .PARAMETER ValueIfFalse
        A value to be returned if the specified condition evaluates to false.

    .EXAMPLE
        Add-ConIf -ConditionName "CreateNewSecurityGroup" -ValueIfTrue (Add-FnRef -Ref "NewSecurityGroup") -ValueIfFalse (Add-FnRef -Ref "ExistingSecurityGroup")

        When the template is exported, this will convert to: {"Fn::If":["CreateNewSecurityGroup",{"Ref":"NewSecurityGroup"},{"Ref":"ExistingSecurityGroup"}]}

    .NOTES
        You can use the following functions in the Fn::If condition:
            Fn::Base64
            Fn::FindInMap
            Fn::GetAtt
            Fn::GetAZs
            Fn::If
            Fn::Join
            Fn::Select
            Ref

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([ConIf])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [string]
        $ConditionName,
        [parameter(Mandatory,Position = 1)]
        [object]
        $ValueIfTrue,
        [parameter(Mandatory,Position = 2)]
        [object]
        $ValueIfFalse
    )
    $obj = [ConIf]::new($ConditionName,$ValueIfTrue,$ValueIfFalse)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-ConIf'

function Add-ConNot {
    <#
    .SYNOPSIS
        Adds the condition function "Fn::Not" to a resource property

    .DESCRIPTION
        Returns true for a condition that evaluates to false or returns false for a condition that evaluates to true. Fn::Not acts as a NOT operator.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-not

    .PARAMETER Condition
        A condition such as Fn::Equals that evaluates to true or false.

    .EXAMPLE
        Add-ConNot -Condition (Add-ConEquals -FirstValue (Add-FnRef -Ref "EnvironmentType") -SecondValue "prod")

        When the template is exported, this will convert to: {"Fn::Equals":["sg-mysggroup",{"Ref":"ASecurityGroup"}]}

    .NOTES
        You can use the following functions in this condition statement:
            Fn::FindInMap
            Ref
            Other condition functions

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([ConNot])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [object[]]
        $Conditions
    )
    $obj = [ConNot]::new($Conditions)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-ConNot'

function Add-ConOr {
    <#
    .SYNOPSIS
        Adds the condition function "Fn::Or" to a resource property

    .DESCRIPTION
        Returns true if any one of the specified conditions evaluate to true, or returns false if all of the conditions evaluates to false. Fn::Or acts as an OR operator. The minimum number of conditions that you can include is 2, and the maximum is 10.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-or

    .PARAMETER Condition
        A condition such as Fn::Equals that evaluates to true or false.

    .EXAMPLE
        Add-ConOr -Conditions (Add-ConEquals -FirstValue "sg-mysggroup" -SecondValue (Add-FnRef -Ref "ASecurityGroup")),(Add-ConEquals -FirstValue "Production" -SecondValue (Add-FnRef -Ref "Environment"))

        When the template is exported, this will convert to: {"Fn::Or":[{"Fn::Equals":["sg-mysggroup",{"Ref":"ASecurityGroup"}]},{"Fn::Equals":["Production",{"Ref":"Environment"}]}]}

    .NOTES
        You can use the following functions in this condition statement:
            Fn::FindInMap
            Ref
            Other condition functions

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([ConOr])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [object[]]
        $Conditions
    )
    $obj = [ConOr]::new($Conditions)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-ConOr'

function Add-ConRef {
    <#
    .SYNOPSIS
        Adds the condition helper function "Condition" to a resource property to reference a condition on the stack by LogicalId.

    .DESCRIPTION
        Adds the condition helper function "Condition" to a resource property to reference a condition on the stack by LogicalId.

    .LINK
        https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-or

    .PARAMETER Ref
        The logical name of the condition you want to reference.

    .EXAMPLE

        Add-ConRef -Condition "HasSSHKey"

        When the template is exported, this will convert to: {"Condition":"HasSSHKey"}

    .NOTES
        You cannot use any functions in the Condition function. You must specify a string that is a condition logical ID.

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([ConRef])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [string]
        $Condition
    )
    $obj = [ConRef]::new($Condition)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-ConRef'

function Export-Vaporshell {
    <#
    .SYNOPSIS
        Exports the template object to JSON file.

    .DESCRIPTION
        Exports the template object to JSON file.

        Requires the Vaporshell input object to be type 'Vaporshell.Template'

    .PARAMETER VaporshellTemplate
        The input template object

    .PARAMETER As
        Specify JSON or YAML for your preferred output. Defaults to JSON.

        **Important**: In order to use YAML, you must have cfn-flip installed: https://github.com/awslabs/aws-cfn-template-flip

    .PARAMETER Path
        Path to save the resulting JSON file.

    .PARAMETER ValidateTemplate
        Validates the template using the AWS .NET SDK

    .PARAMETER Force
        Forces an overwrite if the Path already exists

    .EXAMPLE
        $Template = Initialize-Vaporshell -Description "This is a sample template that builds an S3 bucket"
        # Add items to the $Template object here
        $Template | Export-Vaporshell -Path "C:\CloudFormation\Templates\S3Bucket.json" -Force

    .EXAMPLE
        $Template = Initialize-Vaporshell -Description "This is a sample template that builds an S3 bucket"
        # Add items to the $Template object here
        Export-Vaporshell -VaporshellTemplate $Template -Path "C:\CloudFormation\Templates\S3Bucket.json" -Force

    .FUNCTIONALITY
        Vaporshell
    #>

    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0,ValueFromPipeline)]
        [VSTemplate]
        $VaporshellTemplate,
        [parameter(Position = 1)]
        [ValidateSet("JSON","YAML")]
        [string]
        $As = "JSON",
        [parameter(Position = 2)]
        [string]
        $Path,
        [parameter()]
        [switch]
        $ValidateTemplate,
        [parameter()]
        [switch]
        $Force
    )
    Begin {
        if (-not $PSBoundParameters.ContainsKey('As')) {
            $As = if (-not $PSBoundParameters.ContainsKey('Path')) {
                'JSON'
            }
            else {
                switch -RegEx ($Path) {
                    '\.(yml|yaml)$' {
                        'YAML'
                    }
                    default {
                        'JSON'
                    }
                }
            }
        }
    }
    Process {
        Write-Verbose "Converting template object to $As"
        $final = $VaporshellTemplate.Export($true, $As)
    }
    End {
        if ($ValidateTemplate) {
            Get-TemplateValidation -TemplateBody ($Final -join [System.Environment]::NewLine)
        }
        if ($Path) {
            Write-Verbose "Exporting $As template to: $Path"
            $VaporshellTemplate.Export($Path, $As, $Force)
        }
        else {
            return ($Final -join [System.Environment]::NewLine)
        }
    }
}

Export-ModuleMember -Function 'Export-Vaporshell'

function Import-Vaporshell {
    <#
    .SYNOPSIS
        Allows you to import an existing CloudFormation template as a starting point.

    .DESCRIPTION
        Allows you to import an existing CloudFormation template as a starting point.

    .PARAMETER Path
        The path to the existing template.

    .EXAMPLE
        $Template = Import-Vaporshell -Path "C:\CloudFormation\Templates\S3Bucket.json"

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([VSTemplate])]
    [cmdletbinding(DefaultParameterSetName = "Path")]
    Param
    (
        [parameter(Mandatory,Position = 0,ParameterSetName = "Path")]
        [Alias("FullName")]
        [ValidateScript( {Test-Path $_})]
        [String]
        $Path,
        [parameter(Mandatory,Position = 0,ValueFromPipeline,ParameterSetName = "TemplateBody")]
        [String]
        $TemplateBody,
        [parameter(Mandatory,Position = 0,ParameterSetName = "RawUrl")]
        [String]
        $RawUrl
    )
    Process {
        $finalString = $PSBoundParameters[$PSCmdlet.ParameterSetName] -join [System.Environment]::NewLine
        $obj = [VSTemplate]::new($finalString)
        Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
        $obj
    }
}

Export-ModuleMember -Function 'Import-Vaporshell'

function Import-VSTemplateConfig {
    <#
    .SYNOPSIS
        Imports a configuration from either a JSON or PSD1 file at the specified key.

    .DESCRIPTION
        Imports a configuration from either a JSON or PSD1 file at the specified key.

    .PARAMETER Path
        The path to the configuration file. This can be relative or absolute

    .PARAMETER Key
        The key of the sub-configuration to return, i.e. "Dev".

    .EXAMPLE
        Import-VSTemplateConfig -Path .\WebServerConfig.psd1 -Key Prd

        Imports the "Prd" sub-configuration from the WebServerConfig.psd1 configuration file

    .FUNCTIONALITY
        Vaporshell
    #>

    [cmdletbinding()]
    Param(
        [parameter(Mandatory, Position = 0)]
        [ValidateScript({Test-Path $_})]
        [String]
        $Path,
        [parameter(Mandatory, Position = 1)]
        [String]
        $Key
    )
    try {
        $item = Get-Item $Path -ErrorAction Stop
        $contents = Get-Content $item.FullName -Raw -ErrorAction Stop
        $Global:VSConfig = switch ($item.Extension) {
            '.json' {
                $obj = ConvertFrom-Json -InputObject $contents -ErrorAction Stop
                [PSCustomObject]$obj.$key
            }
            '.psd1' {
                $sb = [scriptblock]::Create($contents)
                $hash = $sb.Invoke()
                [PSCustomObject]($hash.$Key)
            }
            Default {
                throw "$Path must be a JSON or PSD1 file!"
            }
        }
        Write-Verbose "Imported config:`n`n$(($Global:VSConfig | Out-String).Trim())"
        return $Global:VSConfig
    }
    catch {
        $PSCmdlet.ThrowTerminatingError($_)
    }
}

Export-ModuleMember -Function 'Import-VSTemplateConfig'

function Initialize-Vaporshell {
    <#
    .SYNOPSIS
        The starting point for your template buildout. This should always be the first thing called in your template script.

    .DESCRIPTION
        The starting point for your template buildout. This should always be the first thing called in your template script.

        This creates a PSObject, custom typed as 'Vaporshell.Template'. It builds out the containers for Metadata, Parameters, Mappings, Conditions, Resources and Outputs.

    .PARAMETER FormatVersion
        The AWSTemplateFormatVersion section (optional) identifies the capabilities of the template. The latest template format version is 2010-09-09 and is currently the only valid value.

    .PARAMETER Description
        The template description. Total byte count for the description has to be greater than 0 but less than 1024.

    .EXAMPLE
        $Template = Initialize-Vaporshell -Description "This is a sample template that builds an S3 bucket"

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([VSTemplate])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory = $false,Position = 0)]
        [ValidateScript( {[System.Text.Encoding]::UTF8.GetByteCount($_) -lt 1024 -and [System.Text.Encoding]::UTF8.GetByteCount($_) -gt 0})]
        [string]
        $Description,
        [parameter(Mandatory = $false)]
        [ValidateSet("2010-09-09")]
        [Alias('AWSTemplateFormatVersion')]
        [string]
        $FormatVersion
    )
    $obj = [VSTemplate]::new($PSBoundParameters)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Initialize-Vaporshell'

function Install-VaporShellServiceModule {
    [CmdletBinding(DefaultParameterSetName = 'Name', SupportsShouldProcess, ConfirmImpact = 'Low')]
    Param(
        [parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position = 0,ParameterSetName = 'Name')]
        [VaporShellServiceModule[]]
        $Name,
        [parameter(ParameterSetName = 'All')]
        [switch]
        $All,
        [parameter()]
        [string]
        $MinimumVersion,
        [parameter()]
        [string]
        $MaximumVersion,
        [parameter()]
        [string]
        $RequiredVersion,
        [parameter()]
        [string[]]
        $Repository,
        [parameter()]
        [PSCredential]
        $Credential,
        [parameter()]
        [ValidateSet('AllUsers','CurrentUser')]
        [string]
        $Scope,
        [parameter()]
        [string]
        $Proxy,
        [parameter()]
        [PSCredential]
        $ProxyCredential,
        [parameter()]
        [switch]
        $AllowClobber,
        [parameter()]
        [switch]
        $SkipPublisherCheck,
        [parameter()]
        [switch]
        $Force,
        [parameter()]
        [switch]
        $AllowPrerelease,
        [parameter()]
        [switch]
        $PassThru
    )
    Begin {
        Write-Verbose "Getting list of installed VaporShell modules"
        $installed = Get-Module VaporShell* -ListAvailable -Verbose:$false
    }
    Process {
        $params = $PSBoundParameters
        if ($PSCmdlet.ParameterSetName -eq 'All') {
            $params.Remove('All') | Out-Null
            $params['Name'] = [enum]::GetValues([VaporShellServiceModule])
        }
        $params['Name'] = $params['Name'] | ForEach-Object {
            if ($_ -notmatch '^VaporShell') {
                "VaporShell.$_"
            }
            else {
                $_
            }
        }

        $notInstalled = $params['Name'] | Where-Object {$_ -notin $installed.Name}
        $alreadyInstalled = $params['Name'] | Where-Object {$_ -in $installed.Name}

        if ($notInstalled) {
            Write-Verbose "Installing modules:`n- $($notInstalled -join "`n- ")"
            if (($params.Keys -join '-') -match 'Version|Prerelease') {
                $params.Remove('Name') | Out-Null
                foreach ($mod in $notInstalled) {
                    Install-Module -Name $mod @params
                }
            }
            else {
                $params['Name'] = $notInstalled
                Install-Module @params
            }
        }
        if ($alreadyInstalled) {
            Write-Verbose "The following modules are already installed and will be updated instead:`n- $($alreadyInstalled -join "`n- ")"
            $updateParams = $params
            $updateParams['Name'] = $alreadyInstalled

            if (($updateParams.Keys -join '-') -match 'Version|Prerelease') {
                $updateParams.Remove('Name') | Out-Null
                foreach ($mod in $alreadyInstalled) {
                    Update-Module -Name $mod @updateParams
                }
            }
            else {
                Update-Module @updateParams
            }
        }
    }
}

Export-ModuleMember -Function 'Install-VaporShellServiceModule'

function Add-FnBase64 {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::Base64" to a resource property

    .DESCRIPTION
        The intrinsic function Fn::Base64 returns the Base64 representation of the input string. This function is typically used to pass encoded data to Amazon EC2 instances by way of the UserData property.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-base64.html

    .PARAMETER ValueToEncode
        The string value you want to convert to Base64.

    .EXAMPLE
        Add-FnBase64 -ValueToEncode "AWS CloudFormation"

        When the template is exported, this will convert to: {"Fn::Base64":"AWS CloudFormation"}

    .EXAMPLE
        Add-FnBase64 -ValueToEncode (Add-FnRef "$_AWSRegion"")

        When the template is exported, this will convert to: {"Fn::Base64":{"Ref":"AWS::Region"}}

    .NOTES
        You can use any function that returns a string inside the Fn::Base64 function.

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType('Vaporshell.Function.Base64')]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [object]
        $ValueToEncode
    )
    $obj = [FnBase64]::new($ValueToEncode)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnBase64'

function Add-FnCidr {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::Cidr" to a resource property

    .DESCRIPTION
        The intrinsic function Fn::Cidr returns an array of CIDR address blocks. The number of CIDR blocks returned is dependent on the count parameter.

    .LINK
        https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-cidr.html

    .PARAMETER IpBlock
        The user-specified CIDR address block to be split into smaller CIDR blocks.

    .PARAMETER Count
        The number of CIDRs to generate. Valid range is between 1 and 256.

    .PARAMETER CidrBits
        The number of subnet bits for the CIDR. For example, specifying a value "8" for this parameter will create a CIDR with a mask of "/24".

    .EXAMPLE
        Add-FnCidr -IpBlock "192.168.0.0/24" -Count 6 -CidrBits 5

        When the template is exported, this will convert to: { "Fn::Cidr" : [ "192.168.0.0/24", "6", "5"] }

    .NOTES
        You can use the following functions in a Fn::Cidr function:
            Fn::Select
            Ref

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([FnCidr])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [object]
        $IpBlock,
        [parameter(Mandatory,Position = 1)]
        [object]
        $Count,
        [parameter(Mandatory,Position = 2)]
        [object]
        $CidrBits
    )
    $obj = [FnCidr]::new($IpBlock,$Count,$CidrBits)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnCidr'

function Add-FnFindInMap {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::FindInMap" to a resource property

    .DESCRIPTION
        The intrinsic function Fn::FindInMap returns the value corresponding to keys in a two-level map that is declared in the Mappings section.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-findinmap.html

    .PARAMETER MapName
        The logical name of a mapping declared in the Mappings section that contains the keys and values. The value can be another function.

    .PARAMETER TopLevelKey
        The top-level key name. Its value is a list of key-value pairs. The value can be another function.

    .PARAMETER SecondLevelKey
        The second-level key name, which is set to one of the keys from the list assigned to TopLevelKey. The value can be another function.

    .EXAMPLE
        Add-FnFindInMap -MapName "RegionMap" -TopLevelKey (Add-FnRef -Ref "$_AWSRegion") -SecondLevelKey "32"

        When the template is exported, this will convert to: {"Fn::FindInMap":["RegionMap",{"Ref":"AWS::Region"},"32"]}

    .NOTES
        You can use the following functions in a Fn::FindInMap function:
            Fn::FindInMap
            Ref

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType('Vaporshell.Function.FindInMap')]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [string]
        $MapName,
        [parameter(Mandatory,Position = 1)]
        [object]
        $TopLevelKey,
        [parameter(Mandatory,Position = 2)]
        [object]
        $SecondLevelKey
    )
    $obj = [FnFindInMap]::new($MapName,$TopLevelKey,$SecondLevelKey)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnFindInMap'

function Add-FnGetAtt {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::GetAtt" to a resource property

    .DESCRIPTION
        The Fn::GetAtt intrinsic function returns the value of an attribute from a resource in the template.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html

    .PARAMETER LogicalNameOfResource
        The logical name of the resource that contains the attribute that you want. You can also pass the short form of `LogicalNameOfResource.AttributeName` and exclude passing the `AttributeName` parameter additionally.

    .PARAMETER AttributeName
        The name of the resource-specific attribute whose value you want. See the resource's reference page for details about the attributes available for that resource type.

        Not needed if the value passed to the `LogicalNameOfResource` parameter is the short form of `LogicalNameOfResource.AttributeName`.

    .EXAMPLE
        Add-FnGetAtt -LogicalNameOfResource "MyLB" -AttributeName "DNSName"

        When the template is exported, this will convert to: {"Fn::GetAtt":["MyLB","DNSName"]}

    .NOTES
        For the Fn::GetAtt logical resource name, you cannot use functions. You must specify a string that is a resource's logical ID.

        For the Fn::GetAtt attribute name, you can use the Ref function.



        You can retrieve the following attributes using Fn::GetAtt :

        Resource TypeName Attribute Description
        ----------------- --------- -----------
        AWS::ApiGateway::RestApi RootResourceId The root resource ID for a?RestApi?resource.

                                                                                                            Example: a0bc123d4e
        AWS::CloudFormation::WaitCondition Data For more information about wait condition signals, see Wait Condition Signal JSON Format.

                                                                                                            Example of a wait condition with two signals:
                                                                                                            {"Signal1":"Step 1 complete.","Signal2":"Step 2 complete."}

        AWS::CloudFormation::Stack Outputs.NestedStackOutputName The output value from the nested stack that you specified, where?NestedStackOutputName?is the name of the output value.
        AWS::CloudFront::Distribution DomainName Example:?d2fadu0nynjpfn.cloudfront.net
        AWS::CodeBuild::Project Arn Example:?arn:aws:codebuild:us-west-2:123456789012:project/myProjectName
        AWS::CodeCommit::Repository Arn Example:?arn:aws:codecommit:us-east-1:123456789012:MyDemoRepo
        AWS::CodeCommit::Repository CloneUrlHttp Example:?https://codecommit.us-east-1.amazonaws.com/v1/repos/MyDemoRepo
        AWS::CodeCommit::Repository CloneUrlSsh Example:?ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos//v1/repos/MyDemoRepo
        AWS::CodeCommit::Repository Name Example:?MyDemoRepo
        AWS::Config::ConfigRule Arn Example:?arn:aws:config:us-east-1:123456789012:config-rule/config-rule-a1bzhi
        AWS::Config::ConfigRule ConfigRuleId Example:?config-rule-a1bzhi
        AWS::Config::ConfigRule Compliance.Type Example:?COMPLIANT
        AWS::DirectoryService::MicrosoftAD and AWS::DirectoryService::SimpleAD Alias The alias for a directory.

                                                                                                            Examples:?d-12373a053a?or?alias4-mydirectory-12345abcgmzsk?(if you have the?CreateAliasproperty set to true)
        AWS::DirectoryService::MicrosoftAD and AWS::DirectoryService::SimpleAD DnsIpAddresses The IP addresses of the DNS servers for the directory.

                                                                                                            Example:?[ "192.0.2.1", "192.0.2.2" ]
        AWS::DynamoDB::Table StreamArn The Amazon Resource Name (ARN) of the DynamoDB stream. To use this attribute, you must specify the DynamoDB table?StreamSpecification?property.

                                                                                                            Example:?arn:aws:dynamodb:us-east-1:123456789012:table/testddbstack-myDynamoDBTable-012A1SL7SMP5Q/stream/2015-11-30T20:10:00.000
        AWS::EC2::EIP AllocationId The ID that AWS assigns to represent the allocation of the address for use with Amazon VPC. It is returned only for VPC Elastic IP addresses.

                                                                                                            Example:?eipalloc-5723d13e
        AWS::EC2::Instance AvailabilityZone The Availability Zone where the instance that you specified is launched.

                                                                                                            Example:?us-east-1b
        AWS::EC2::Instance PrivateDnsName The private DNS name of the instance that you specified.

                                                                                                            Example:?ip-10-24-34-0.ec2.internal
        AWS::EC2::Instance PublicDnsName The public DNS name of the instance that you specified.

                                                                                                            Example:?ec2-107-20-50-45.compute-1.amazonaws.com
        AWS::EC2::Instance PrivateIp The private IP address of the instance that you specified.

                                                                                                            Example:?10.24.34.0
        AWS::EC2::Instance PublicIp The public IP address of the instance that you specified.

                                                                                                            Example:?192.0.2.0
        AWS::EC2::NetworkInterface PrimaryPrivateIpAddress The primary private IP address of the network interface that you specified.

                                                                                                            Example:?10.0.0.192
        AWS::EC2::NetworkInterface SecondaryPrivateIpAddresses The secondary private IP addresses of the network interface that you specified.

                                                                                                            Example:?["10.0.0.161", "10.0.0.162", "10.0.0.163"]
        AWS::EC2::SecurityGroup GroupId The group ID of the specified security group.

                                                                                                            Example:?sg-94b3a1f6
        AWS::EC2::Subnet AvailabilityZone The Availability Zone of the subnet.

                                                                                                            Example:?us-east-1a
        AWS::EC2::Subnet Ipv6CidrBlocks A list of IPv6 CIDR blocks that are associated with the subnet.

                                                                                                            Example:?[ 2001:db8:1234:1a00::/64 ]
        AWS::EC2::SubnetNetworkAclAssociation AssociationId The?NetworkAcl associationId?that is attached to a subnet.
        AWS::EC2::VPC CidrBlock The set of IP addresses for the VPC.

                                                                                                            Example:?10.0.0.0/16
        AWS::EC2::VPC DefaultNetworkAcl The default network ACL ID that is associated with the VPC, which AWS creates when you create a VPC.

                                                                                                            Example:?acl-814dafe3
        AWS::EC2::VPC DefaultSecurityGroup The default security group ID that is associated with the VPC, which AWS creates when you create a VPC.

                                                                                                            Example:?sg-b178e0d3
        AWS::EC2::VPC Ipv6CidrBlocks A list of IPv6 CIDR blocks that are associated with the VPC.

                                                                                                            Example:?[ 2001:db8:1234:1a00::/56 ]
        AWS::ECS::Service Name The name of an Amazon EC2 Container Service service.

                                                                                                            Example:?sample-webapp
        AWS::ElastiCache::CacheCluster ConfigurationEndpoint.Address The DNS address of the configuration endpoint for the Memcached cache cluster.

                                                                                                            Example:?test.abc12a.cfg.use1.cache.amazonaws.com:11111
        AWS::ElastiCache::CacheCluster ConfigurationEndpoint.Port The port number of the configuration endpoint for the Memcached cache cluster.
        AWS::ElastiCache::CacheCluster RedisEndpoint.Address The DNS address of the configuration endpoint for the Redis cache cluster.

                                                                                                            Example:?test.abc12a.cfg.use1.cache.amazonaws.com:11111
        AWS::ElastiCache::CacheCluster RedisEndpoint.Port The port number of the configuration endpoint for the Redis cache cluster.
        AWS::ElastiCache::ReplicationGroup ConfigurationEndPoint.Address The DNS hostname of the cache node.
        AWS::ElastiCache::ReplicationGroup ConfigurationEndPoint.Port The port number that the cache engine is listening on.
        AWS::ElastiCache::ReplicationGroup PrimaryEndPoint.Address The DNS address of the primary read-write cache node.
        AWS::ElastiCache::ReplicationGroup PrimaryEndPoint.Port The port number that the primary read-write cache engine is listening on.
        AWS::ElastiCache::ReplicationGroup ReadEndPoint.Addresses A string with a list of endpoints for the read-only replicas. The order of the addresses map to the order of the ports from the?ReadEndPoint.Ports...

                                                                                                            Example:?"[abc12xmy3d1w3hv6-001.rep12a.0001.use1.cache.amazonaws.com, abc12xmy3d1w3hv6-002.rep12a.0001.use1.cache.amazonaws.com, abc12xmy3d1w3hv6-...
        AWS::ElastiCache::ReplicationGroup ReadEndPoint.Ports A string with a list of ports for the read-only replicas. The order of the ports maps to the order of the addresses from the?ReadEndPoint.Addresse...

                                                                                                            Example:?"[6379, 6379, 6379]"
        AWS::ElastiCache::ReplicationGroup ReadEndPoint.Addresses.List A list of endpoints for the read-only replicas.

                                                                                                            Example:?["abc12xmy3d1w3hv6-001.rep12a.0001.use1.cache.amazonaws.com", "abc12xmy3d1w3hv6-002.rep12a.0001.use1.cache.amazonaws.com", "abc12xmy3d1w3...
        AWS::ElastiCache::ReplicationGroup ReadEndPoint.Ports.List A list of ports for the read-only replicas.

                                                                                                            Example:?["6379","6379","6379"]
        AWS::ElasticBeanstalk::Environment EndpointURL The URL to the load balancer for this environment.

                                                                                                            Example:?awseb-myst-myen-132MQC4KRLAMD-1371280482.us-east-1.elb.amazonaws.com
        AWS::ElasticLoadBalancing::LoadBalancer CanonicalHostedZoneName The name of the Amazon Route?53-hosted zone that is associated with the load balancer.

                                                                                                            Example:?mystack-myelb-15HMABG9ZCN57-1013119603.us-east-1.elb.amazonaws.com
        AWS::ElasticLoadBalancing::LoadBalancer CanonicalHostedZoneNameID The ID of the Amazon Route?53 hosted zone name that is associated with the l oad balancer.

                                                                                                            Example:?Z3DZXE0Q79N41H
        AWS::ElasticLoadBalancing::LoadBalancer DNSName The DNS name for the load balancer.

                                                                                                            Example:?mystack-myelb-15HMABG9ZCN57-1013119603.us-east-1.elb.amazonaws.com
        AWS::ElasticLoadBalancing::LoadBalancer SourceSecurityGroup.GroupName The security group that you can use as part of your inbound rules for your load balancer's back-end Amazon EC2 application instances.

                                                                                                            Example:?amazon-elb
        AWS::ElasticLoadBalancing::LoadBalancer SourceSecurityGroup.OwnerAlias The owner of the source security group.

                                                                                                            Example:?amazon-elb-sg
        AWS::ElasticLoadBalancingV2::LoadBalancer DNSName The DNS name for the application load balancer.

                                                                                                            Example:?my-load-balancer-424835706.us-west-2.elb.amazonaws.com
        AWS::ElasticLoadBalancingV2::LoadBalancer CanonicalHostedZoneID The ID of the Amazon Route?53-hosted zone name that is associated with the load balancer.

                                                                                                            Example:?Z2P70J7EXAMPLE
        AWS::ElasticLoadBalancingV2::LoadBalancer LoadBalancerFullName The full name of the application load balancer.

                                                                                                            Example:?app/my-load-balancer/50dc6c495c0c9188
        AWS::ElasticLoadBalancingV2::LoadBalancer LoadBalancerName The name of the application load balancer.

                                                                                                            Example:?my-load-balancer
        AWS::ElasticLoadBalancingV2::LoadBalancer SecurityGroups The IDs of the security groups for the application load balancer.

                                                                                                            Example:?sg-123456a
        AWS::ElasticLoadBalancingV2::TargetGroup LoadBalancerArns The Amazon Resource Names (ARNs) of the load balancers that route traffic to this target group.

                                                                                                            Example:?[ "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" ]
        AWS::ElasticLoadBalancingV2::TargetGroup TargetGroupFullName The full name of the target group.
                                                                                                            Example:?targetgroup/my-target-group/cbf133c568e0d028
        AWS::Elasticsearch::Domain DomainArn The Amazon Resource Name (ARN) of the domain.

                                                                                                            Example:?arn:aws:es:us-west-2:123456789012:domain/mystack-elasti-1ab2cdefghij
        AWS::Elasticsearch::Domain DomainEndpoint The domain-specific endpoint that is used to submit index, search, and data upload requests to an Amazon Elasticsearch Service domain.

                                                                                                            Example:?search-mystack-elasti-1ab2cdefghij-ab1c2deckoyb3hofw7wpqa3cm.us-west-2.es.amazonaws.com
        AWS::EMR::Cluster MasterPublicDNS The public DNS name of the master node (instance).

                                                                                                            Example:?ec2-12-123-123-123.us-west-2.compute.amazonaws.com
        AWS::Events::Rule Arn The Amazon Resource Name (ARN) of the event rule.

                                                                                                            Example:?arn:aws:events:us-east-1:123456789012:rule/example
        AWS::IAM::AccessKey SecretAccessKey The secret access key for the specified?Access Key.

                                                                                                            Example:?wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY
        AWS::IAM::Group Arn Example:?arn:aws:iam::123456789012:group/mystack-mygroup-1DZETITOWEKVO
        AWS::IAM::InstanceProfile Arn Returns the Amazon Resource Name (ARN) for the instance profile.

                                                                                                            Example:?arn:aws:iam::1234567890:instance-profile/MyProfile-ASDNSDLKJ
        AWS::IAM::Role Arn Example:?arn:aws:iam::1234567890:role/MyRole-AJJHDSKSDF
        AWS::IAM::User Arn Example:?arn:aws:iam::123456789012:user/mystack-myuser-1CCXAFG2H2U4D
        AWS::IoT::Certificate Arn Example:?arn:aws:iot:ap-southeast-2:123456789012:cert/a1234567b89c012d3e4fg567hij8k9l01mno1p23q45678901rs234567890t1u2
        AWS::Kinesis::Stream Arn The ARN of the Amazon Kinesis stream.

                                                                                                            Example:?arn:aws:kinesis:us-east-1:123456789012:stream/mystream.
        AWS::KMS::Key Arn The ARN of the AWS KMS key.

                                                                                                            Example:?arn:aws:kms:us-west-2:123456789012:key/12a34567-8c90-1defg-af84-0bf06c1747f3.
        AWS::Lambda::Function Arn Example:?arn:aws:lambda:us-west-2:123456789012:MyStack-AMILookUp-NT5EUXTNTXXD
        AWS::Lambda::Version Version The version of a Lambda function.

                                                                                                            Example:?1
        AWS::Logs::LogGroup Arn The ARN of the Amazon CloudWatch Logs log group.

                                                                                                            Example:?arn:aws:logs:us-east-1:123456789012:log-group:/mystack-testgroup-12ABC1AB12A1:*
        AWS::OpsWorks::Instance AvailabilityZone The Availability Zone of an AWS OpsWorks instance.

                                                                                                            Example:?us-east-2a.
        AWS::OpsWorks::Instance PrivateDnsName The private DNS name of an AWS OpsWorks instance.
        AWS::OpsWorks::Instance PrivateIp The private IP address of an AWS OpsWorks instance.
        AWS::OpsWorks::Instance PublicDnsName The public DNS name of an AWS OpsWorks instance.
        AWS::OpsWorks::Instance PublicIp The public IP address of an AWS OpsWorks instance.

                                                                                                            Note
                                                                                                            To use this attribute, the AWS OpsWorks instance must be in an AWS OpsWorks layer that auto-assigns public IP addresses.

                                                                                                            Example:?192.0.2.0
        AWS::OpsWorks::UserProfile SshUserName The SSH user name of an AWS OpsWorks instance.
        AWS::Redshift::Cluster Endpoint.Address The connection endpoint for the cluster.

                                                                                                            Example:?examplecluster.cg034hpkmmjt.us-east-1.redshift.amazonaws.com
        AWS::Redshift::Cluster Endpoint.Port The connection port for the cluster.

                                                                                                            Example:?5439
        AWS::RDS::DBCluster Endpoint.Address The connection endpoint for the DB cluster.

                                                                                                            Example:?mystack-mydbcluster-1apw1j4phylrk.cg034hpkmmjt.us-east-1.rds.amazonaws.com
        AWS::RDS::DBCluster Endpoint.Port The port number on which the DB cluster accepts connections.

                                                                                                            Example:?3306
        AWS::RDS::DBInstance Endpoint.Address The connection endpoint for the database.

                                                                                                            Example:?mystack-mydb-1apw1j4phylrk.cg034hpkmmjt.us-east-1.rds.amazonaws.com
        AWS::RDS::DBInstance Endpoint.Port The port number on which the database accepts connections.

                                                                                                            Example:?3306
        AWS::Route53::HostedZone NameServers Returns the set of name servers for the specific hosted zone.

                                                                                                            Example:?ns1.example.com
        AWS::S3::Bucket DomainName The DNS name of the specified bucket.

                                                                                                            Example:?mystack-mybucket-kdwwxmddtr2g.s3.amazonaws.com
        AWS::S3::Bucket WebsiteURL The Amazon S3 website endpoint for the specified bucket.

                                                                                                            Example:?http://mystack-mybucket-kdwwxmddtr2g.s3-website-us-east-1.amazonaws.com/
        AWS::Serverless::Function No attribute. The ARN of an?AWS::Serverless::Function?resource.
        AWS::SNS::Topic TopicName The name of an Amazon SNS topic.

                                                                                                            Example:?my-sns-topic
        AWS::StepFunctions::Activity Name The name of the AWS Step Functions activity.
        AWS::StepFunctions::StateMachine Name The name of the Step Functions state machine.
        AWS::SQS::Queue Arn The ARN for the specified queue.

                                                                                                            Example:?arn:aws:sqs:us-east-1:123456789012:mystack-myqueue-15PG5C2FC1CW8
        AWS::SQS::Queue QueueName The name of an Amazon SQS queue.

                                                                                                            Example:?mystack-myqueue-1VF9BKQH5BJVI

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([FnGetAtt])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [string]
        $LogicalNameOfResource,
        [parameter(Position = 1)]
        [string]
        $AttributeName
    )
    $obj = if ($AttributeName) {
        [FnGetAtt]::new($LogicalNameOfResource,$AttributeName)
    }
    else {
        [FnGetAtt]::new($LogicalNameOfResource)
    }
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnGetAtt'

function Add-FnGetAZs {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::GetAZs" to a resource property

    .DESCRIPTION
        The intrinsic function Fn::GetAZs returns an array that lists Availability Zones for a specified region. Because customers have access to different Availability Zones, the intrinsic function Fn::GetAZs enables template authors to write templates that adapt to the calling user's access. That way you don't have to hard-code a full list of Availability Zones for a specified region.

            ** Important **
                For the EC2-Classic platform, the Fn::GetAZs function returns all Availability Zones for a region. For the EC2-VPC platform, the Fn::GetAZs function returns only Availability Zones that have a default subnet unless none of the Availability Zones has a default subnet; in that case, all Availability Zones are returned.

                Similarly to the response from the describe-availability-zones AWS CLI command, the order of the results from the Fn::GetAZs function is not guaranteed and can change when new Availability Zones are added.

        IAM permissions

            The permissions that you need in order to use the Fn::GetAZs function depend on the platform in which you're launching Amazon EC2 instances. For both platforms, you need permissions to the Amazon EC2 DescribeAvailabilityZones and DescribeAccountAttributes actions. For EC2-VPC, you also need permissions to the Amazon EC2 DescribeSubnets action.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getavailabilityzones.html

    .PARAMETER Region
        The name of the region for which you want to get the Availability Zones.

        You can use the AWS::Region pseudo parameter to specify the region in which the stack is created. Specifying an empty string is equivalent to specifying AWS::Region.

        This is not required. If you would like to default this to the stack deployment region, simply exclude this parameter and call the function by itself.

    .EXAMPLE
        Add-FnImportValue -ValueToImport (Add-FnSub -String "`${NetworkStackNameParameter}-SubnetID")

        When the template is exported, this will convert to: {"Fn::ImportValue":{"Fn::Sub":"${NetworkStackNameParameter}-SubnetID"}}

    .NOTES
        You can use the Ref function in the Fn::GetAZs function.

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([FnGetAZs])]
    [cmdletbinding()]
    Param(
        [parameter(Position = 0)]
        [object]
        $Region = [FnRef]::Region
    )
    $obj = [FnGetAZs]::new($Region)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnGetAZs'

function Add-FnImportValue {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::ImportValue" to a resource property

    .DESCRIPTION
        The intrinsic function Fn::ImportValue returns the value of an output exported by another stack. You typically use this function to create cross-stack references.

        Note:
            The following restrictions apply to cross-stack references:
                * For each AWS account, Export names must be unique within a region.
                * You can't create cross-stack references across regions. You can use the intrinsic function Fn::ImportValue to import only values that have been exported within the same region.
                * For outputs, the value of the Name property of an Export can't use Ref or GetAtt functions that depend on a resource.
                * Similarly, the ImportValue function can't include Ref or GetAtt functions that depend on a resource.
                * You can't delete a stack if another stack references one of its outputs.
                * You can't modify or remove an output value that is referenced by another stack.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html

    .PARAMETER ValueToImport
        The stack output value that you want to import.

    .EXAMPLE
        Add-FnImportValue -ValueToImport (Add-FnSub -String "`${NetworkStackNameParameter}-SubnetID")

        When the template is exported, this will convert to: {"Fn::ImportValue":{"Fn::Sub":"${NetworkStackNameParameter}-SubnetID"}}

    .NOTES
        You can use the following functions in the Fn::ImportValue function. The value of these functions can't depend on a resource.
            Fn::Base64
            Fn::FindInMap
            Fn::If
            Fn::Join
            Fn::Select
            Fn::Split
            Fn::Sub
            Ref

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([FnImportValue])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [object]
        $ValueToImport
    )
    $obj = [FnImportValue]::new($ValueToImport)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnImportValue'

function Add-FnJoin {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::Join" to a resource property

    .DESCRIPTION
        The intrinsic function Fn::Join appends a set of values into a single value, separated by the specified delimiter. If a delimiter is the empty string, the set of values are concatenated with no delimiter.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-join.html

    .PARAMETER Delimiter
        The value you want to occur between fragments. The delimiter will occur between fragments only. It will not terminate the final value.

        This is not required. If you want to join without an added delimiter, simply exclude this parameter.

    .PARAMETER ListOfValues
        The list of values you want combined.

    .EXAMPLE
        Add-FnSelect -Index 2 -ListOfObjects (Add-FnSplit -Delimiter "," -SourceString (Add-FnImportValue -ValueToImport "AccountSubnetIds"))

        When the template is exported, this will convert to: {"Fn::Select":["2",{"Fn::Split":[",",{"Fn::ImportValue":"AccountSubnetIds"}]}]}

    .NOTES
        For the Fn::Join delimiter, you cannot use any functions. You must specify a string value.

        For the Fn::Join list of values, you can use the following functions:
            Fn::Base64
            Fn::FindInMap
            Fn::GetAtt
            Fn::GetAZs
            Fn::If
            Fn::ImportValue
            Fn::Join
            Fn::Split
            Fn::Select
            Fn::Sub
            Ref

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([FnJoin])]
    [cmdletbinding()]
    Param(
        [parameter(Position = 0)]
        [System.String]
        $Delimiter = $null,
        [parameter(Mandatory,Position = 1)]
        [object[]]
        $ListOfValues
    )
    $obj = [FnJoin]::new($Delimiter,@($ListOfValues))
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnJoin'

function Add-FnRef {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Ref" to a resource property

    .DESCRIPTION
        The intrinsic function Ref returns the value of the specified parameter or resource.

            * When you specify a parameter's logical name, it returns the value of the parameter.
            * When you specify a resource's logical name, it returns a value that you can typically use to refer to that resource, such as a physical ID.

        When you are declaring a resource in a template and you need to specify another template resource by name, you can use the Ref to refer to that other resource. In general, Ref returns the name of the resource. For example, a reference to an AWS::AutoScaling::AutoScalingGroup returns the name of that Auto Scaling group resource.

        For some resources, an identifier is returned that has another significant meaning in the context of the resource. An AWS::EC2::EIP resource, for instance, returns the IP address, and an AWS::EC2::Instance returns the instance ID.

            Tip
                You can also use Ref to add values to Output messages.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html

    .PARAMETER Ref
        The logical name of the resource or parameter you want to reference.

    .EXAMPLE
        # This uses the module's included variable that maps to the AWS Pseudo Parameter, "AWS::Region"

        Add-FnRef -Ref "$_AWSRegion"

        When the template is exported, this will convert to: {"Ref":"AWS::Region"}

    .NOTES
        You cannot use any functions in the Ref function. You must specify a string that is a resource logical ID.

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([FnRef])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [string]
        $Ref
    )
    $obj = [FnRef]::new($Ref)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnRef'

function Add-FnSelect {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::Select" to a resource property

    .DESCRIPTION
        The intrinsic function Fn::Select returns a single object from a list of objects by index.

        You can use Fn::Select to select an object from a CommaDelimitedList parameter. You might use a CommaDelimitedList parameter to combine the values of related parameters, which reduces the total number of parameters in your template.

            ** Important **
                Fn::Select does not check for null values or if the index is out of bounds of the array. Both conditions will result in a stack error, so you should be certain that the index you choose is valid, and that the list contains non-null values.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html

    .PARAMETER Index
        The index of the object to retrieve. This must be a value from zero to N-1, where N represents the number of elements in the array.

    .PARAMETER ListOfObjects
        The list of objects to select from. This list must not be null, nor can it have null entries.

    .EXAMPLE
        Add-FnSelect -Index 2 -ListOfObjects (Add-FnSplit -Delimiter "," -SourceString (Add-FnImportValue -ValueToImport "AccountSubnetIds"))

        When the template is exported, this will convert to: {"Fn::Select":["2",{"Fn::Split":[",",{"Fn::ImportValue":"AccountSubnetIds"}]}]}

    .NOTES
        For the Fn::Select index value, you can use the Ref and Fn::FindInMap functions.

        For the Fn::Select list of objects, you can use the following functions:
            Fn::FindInMap
            Fn::GetAtt
            Fn::GetAZs
            Fn::If
            Fn::Split
            Ref

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([FnSelect])]
    [cmdletbinding()]
    Param(
        [parameter(Position = 0)]
        [object]
        $Index = 0,
        [parameter(Mandatory,Position = 1)]
        [object[]]
        $ListOfObjects
    )
    $obj = [FnSelect]::new($Index,$ListOfObjects)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnSelect'

function Add-FnSplit {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::Split" to a resource property

    .DESCRIPTION
        To split a string into a list of string values so that you can select an element from the resulting string list, use the Fn::Split intrinsic function. Specify the location of splits with a delimiter, such as , (a comma). After you split a string, use the Fn::Select function to pick a specific element.

        For example, if a comma-delimited string of subnet IDs is imported to your stack template, you can split the string at each comma. From the list of subnet IDs, use the Fn::Select intrinsic function to specify a subnet ID for a resource.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-split.html

    .PARAMETER Delimiter
        A string value that determines where the source string is divided.

    .PARAMETER SourceString
        The string value that you want to split. This can be a string or object from an Add-Fn* function output

    .EXAMPLE
        Add-FnSplit -Delimiter "," -SourceString (Add-FnImportValue -ValueToImport "AccountSubnetIds")

        When the template is exported, this will convert to: {"Fn::Split":[",",{"Fn::ImportValue":"AccountSubnetIds"}]}

    .NOTES
        For the Fn::Split delimiter, you cannot use any functions. You must specify a string value.

        For the Fn::Split list of values (SourceString), you can use the following functions:
            Fn::Base64
            Fn::FindInMap
            Fn::GetAtt
            Fn::GetAZs
            Fn::If
            Fn::Join
            Fn::Select
            Ref

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([FnSplit])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [string]
        $Delimiter,
        [parameter(Mandatory,Position = 1)]
        [object]
        $SourceString
    )
    $obj = [FnSplit]::new($Delimiter,$SourceString)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnSplit'

function Add-FnSub {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::Sub" to a resource property

    .DESCRIPTION
        The intrinsic function Fn::Sub substitutes variables in an input string with values that you specify. In your templates, you can use this function to construct commands or outputs that include values that aren't available until you create or update a stack.

        ** Important **
            As Fn::Sub uses ${Var} syntax, it's important to remember to escape the $ at the head of the subbed variable when calling the function, otherwise Powershell will attempt to convert the variable into a value when adding it to the object and break the CloudFormation function's intended use.

            Please see the example below for reference.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html

    .PARAMETER String
        Input string with the Variable names surrounded in braces, i.e. "/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfig --configsets wordpress_install --region ${AWS::Region}"

        You MUST escape the dollar sign before each variable brace when using this module, otherwise Powershell will attempt to convert it to a variable and not take it as a literal string.

    .PARAMETER Mapping
        A hashtable containing mappings, with the key being the variable name and the value being what you would like to substitute for the variable. The value can be another function.

    .EXAMPLE
        Add-FnSub -String "www.`${Domain}" -Mapping @{Domain = (Add-FnRef -Ref "RootDomainName")}

        When the template is exported, this will convert to: {"Fn::Sub":["www.${Domain}",{"Domain":{"Ref":"RootDomainName"}}]}

    .NOTES
        You can use the following functions in the Fn::Sub function:
            Fn::Base64
            Fn::FindInMap
            Fn::GetAtt
            Fn::GetAZs
            Fn::If
            Fn::Join
            Fn::Select
            Ref

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType('Vaporshell.Function.Sub')]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [string]
        $String,
        [parameter(Position = 1)]
        [System.Collections.IDictionary]
        $Mapping
    )
    $obj = if ($Mapping) {
        [FnSub]::new($String,$Mapping)
    }
    else {
        [FnSub]::new($String)
    }
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnSub'

function Add-FnTransform {
    <#
    .SYNOPSIS
        Adds the intrinsic function "Fn::Transform" to a resource property

    .DESCRIPTION
        The intrinsic function Fn::Transform specifies a macro to perform custom processing on part of a stack template. Macros enable you to perform custom processing on templates, from simple actions like find-and-replace operations to extensive transformations of entire templates. For more information, see Using AWS CloudFormation Macros to Perform Custom Processing on Templates.

        You can also use Fn::Transform to call the AWS::Include Transform transform, which is a macro hosted by AWS CloudFormation.

    .LINK
        https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-transform.html

    .PARAMETER Name
        The name of the macro you want to perform the processing.

    .PARAMETER Parameters
        The list parameters, specified as a hashtable, to pass to the macro.

    .EXAMPLE
        Add-FnTransform -Name "AWS::Include" -Parameters @{Location = (Add-FnRef "InputValue")}

        This example calls the AWS::Include transform, specifying that the location to retrieve a template snippet from is passed in the InputValue parameter.

        When the template is exported, this will convert to:
            {
                "Fn::Transform" : {
                    "Name" : "AWS::Include",
                    "Parameters" : {
                        "Location" : { "Ref" : "InputValue" }
                    }
                }
            }

    .NOTES
        AWS CloudFormation passes any intrinsic function calls included in Fn::Transform to the specified macro as literal strings. For more information, see AWS CloudFormation Macro Function Interface.

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([FnTransform])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [String]
        $Name,
        [parameter(Mandatory,Position = 1)]
        [System.Collections.IDictionary]
        $Parameters
    )
    $obj = [FnTransform]@{
        Name = $Name
        Parameters = $Parameters
    }
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'Add-FnTransform'

function New-VaporCondition {
    <#
    .SYNOPSIS
        Adds a Condition object to the template

    .DESCRIPTION
        The optional Conditions section includes statements that define when a resource is created or when a property is defined. For example, you can compare whether a value is equal to another value. Based on the result of that condition, you can conditionally create resources. If you have multiple conditions, separate them with commas.

        You might use conditions when you want to reuse a template that can create resources in different contexts, such as a test environment versus a production environment. In your template, you can add an EnvironmentType input parameter, which accepts either prod or test as inputs. For the production environment, you might include Amazon EC2 instances with certain capabilities; however, for the test environment, you want to use reduced capabilities to save money. With conditions, you can define which resources are created and how they're configured for each environment type.

        Conditions are evaluated based on input parameter values that you specify when you create or update a stack. Within each condition, you can reference another condition, a parameter value, or a mapping. After you define all your conditions, you can associate them with resources and resource properties in the Resources and Outputs sections of a template.

        At stack creation or stack update, AWS CloudFormation evaluates all the conditions in your template before creating any resources. Any resources that are associated with a true condition are created. Any resources that are associated with a false condition are ignored.

        ** Important **
            During a stack update, you cannot update conditions by themselves. You can update conditions only when you include changes that add, modify, or delete resources.

        To conditionally create resources, you must include statements in at least three different sections of a template:

            Parameters section
                Define the input values that you want to evaluate in your conditions. Conditions will result in true or false based on values from these input parameter.

            Conditions section
                Define conditions by using the intrinsic condition functions. These conditions determine when AWS CloudFormation creates the associated resources.

            Resources and Outputs sections
                Associate conditions with the resources or outputs that you want to conditionally create. AWS CloudFormation creates entities that are associated with a true condition and ignores entities that are associated with a false condition. Use the Condition key and a condition's logical ID to associate it with a resource or output. To conditionally specify a property, use the Fn::If function. For more information, see Condition Functions.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html

    .PARAMETER LogicalId
        An identifier for the current condition. The logical ID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.

    .PARAMETER Condition
        Logical ID of the condition that this resource needs to be true in order to be provisioned.

    .EXAMPLE
        $template = Initialize-Vaporshell -Description "Testing Condition addition"
        $template.AddResource((
            New-VaporCondition -LogicalId "CreateProdResources" -Condition (Add-ConEquals -FirstValue (Add-FnRef -Ref "EnvType") -SecondValue "prod")
        ))

        When the template is exported, this will convert to:
            {
                "AWSTemplateFormatVersion": "2010-09-09",
                "Description": "Testing Condition addition",
                "Conditions": {
                    "CreateProdResources": {
                        "Fn::Equals": [
                            {
                                "Ref": "EnvType"
                            },
                            "prod"
                        ]
                    }
                }
            }

    .NOTES
        You can use the following intrinsic functions to define conditions:
            Fn::And
            Fn::Equals
            Fn::If
            Fn::Not
            Fn::Or

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([VSCondition])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [ValidateLogicalId()]
        [string]
        $LogicalId,
        [parameter(Mandatory,Position = 1)]
        [ConditionFunction]
        $Condition
    )
    $obj = [VSCondition]::new($PSBoundParameters)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'New-VaporCondition'

function New-VaporMapping {
    <#
    .SYNOPSIS
        Adds a Mapping object to the template

    .DESCRIPTION
        The optional Mappings section matches a key to a corresponding set of named values. For example, if you want to set values based on a region, you can create a mapping that uses the region name as a key and contains the values you want to specify for each specific region. You use the Fn::FindInMap intrinsic function to retrieve values in a map.

        You cannot include parameters, pseudo parameters, or intrinsic functions in the Mappings section.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html

    .PARAMETER LogicalId
        An identifier for the current condition. The logical ID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.

    .PARAMETER Map
        A 2 level collection of key/value pairs. If you would like your collection to remain ordered the same as called, use an ordered PSCustomObject, otherwise a hashtable is fine.

        You can use any of these 3 types for this parameter; "System.Collections.Hashtable","System.Management.Automation.PSCustomObject","Vaporshell.Mapping.Map"

    .EXAMPLE
        $template = Initialize-Vaporshell -Description "Testing Mapping addition"
        $template.AddMapping((
            New-VaporMapping -LogicalId "RegionMap" -Map ([PSCustomObject][Ordered]@{
                "us-east-1" = [PSCustomObject][Ordered]@{
                    "32" = "ami-6411e20d"
                    "64" = "ami-7a11e213"
                }
                "us-west-1" = [PSCustomObject][Ordered]@{
                    "32" = "ami-c9c7978c"
                    "64" = "ami-cfc7978a"
                }
                "eu-west-1" = [PSCustomObject][Ordered]@{
                    "32" = "ami-37c2f643"
                    "64" = "ami-31c2f645"
                }
                "ap-southeast-1" = [PSCustomObject][Ordered]@{
                    "32" = "ami-66f28c34"
                    "64" = "ami-60f28c32"
                }
                "ap-northeast-1" = [PSCustomObject][Ordered]@{
                    "32" = "ami-9c03a89d"
                    "64" = "ami-a003a8a1"
                }
            })
        ))

        When the template is exported, this will convert to:
            {
                "AWSTemplateFormatVersion": "2010-09-09",
                "Description": "Testing Mapping addition",
                "Mappings": {
                    "RegionMap": {
                        "us-east-1": {
                            "32": "ami-6411e20d",
                            "64": "ami-7a11e213"
                        },
                        "us-west-1": {
                            "32": "ami-c9c7978c",
                            "64": "ami-cfc7978a"
                        },
                        "eu-west-1": {
                            "32": "ami-37c2f643",
                            "64": "ami-31c2f645"
                        },
                        "ap-southeast-1": {
                            "32": "ami-66f28c34",
                            "64": "ami-60f28c32"
                        },
                        "ap-northeast-1": {
                            "32": "ami-9c03a89d",
                            "64": "ami-a003a8a1"
                        }
                    }
                }
            }

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([VSMapping])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [ValidateLogicalId()]
        [string]
        $LogicalId,
        [parameter(Mandatory,Position = 1)]
        [System.Collections.IDictionary]
        $Map
    )
    $obj = [VSMapping]::new($PSBoundParameters)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'New-VaporMapping'

function New-VaporMetadata {
    <#
    .SYNOPSIS
        Adds a Metadata object to the template

    .DESCRIPTION
        You can use the optional Metadata section to include arbitrary JSON or YAML objects that provide details about the template.

        ** Important **
            During a stack update, you cannot update the Metadata section by itself. You can update it only when you include changes that add, modify, or delete resources.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html

    .PARAMETER LogicalId
        The key of the metadata. The LogicalID must contain only alphanumeric characters or colons (a-z, A-Z, 0-9, :, ::) and unique within the template.

    .PARAMETER Metadata
        Key/Value pair.

        You can use any of these 3 types for this parameter; "System.Collections.Hashtable","System.Management.Automation.PSCustomObject","Vaporshell.Metadata.Data"

    .EXAMPLE
        $template = Initialize-Vaporshell -Description "Testing Metadata addition"
        $template.AddMetadata(
            (New-VaporMetadata -LogicalId "Instances" -Metadata [PSCustomObject]@{"Description" = "Information about the instances"}),
            (New-VaporMetadata -LogicalId "Databases" -Metadata [PSCustomObject]@{"Description" = "Information about the databases"})
        )

        When the template is exported, this will convert to:
            {
                "AWSTemplateFormatVersion": "2010-09-09",
                "Description": "Testing Metadata addition",
                "Metadata": {
                    "Instances": {
                        "Description": "Information about the instances"
                    },
                    "Databases": {
                        "Description": "Information about the databases"
                    }
                }
            }

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([VSMetadata])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [ValidateLogicalId()]
        [string]
        [Alias('Key')]
        $LogicalId,
        [parameter(Mandatory,Position = 1)]
        [object]
        $Metadata
    )
    $obj = [VSMetadata]::new($PSBoundParameters)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'New-VaporMetadata'

function New-VaporOutput {
    <#
    .SYNOPSIS
        Adds an Output object to the template

    .DESCRIPTION
        The optional Outputs section declares output values that you can import into other stacks (to create cross-stack references), return in response (to describe stack calls), or view on the AWS CloudFormation console. For example, you can output the S3 bucket name for a stack to make the bucket easier to find.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html

    .PARAMETER LogicalId
        An identifier for the current output. The logical ID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.

    .PARAMETER Description
        A String type that describes the output value. The description can be a maximum of 4 K in length.

    .PARAMETER Value
        The value of the property returned by the aws cloudformation describe-stacks command. The value of an output can include literals, parameter references, pseudo-parameters, a mapping value, or intrinsic functions.

    .PARAMETER Export
        The name of the resource output to be exported for a cross-stack reference.

        Note
            The following restrictions apply to cross-stack references:
                * For each AWS account, Export names must be unique within a region.
                * You can't create cross-stack references across regions. You can use the intrinsic function Fn::ImportValue to import only values that have been exported within the same region.
                * For outputs, the value of the Name property of an Export can't use Ref or GetAtt functions that depend on a resource.
                * Similarly, the ImportValue function can't include Ref or GetAtt functions that depend on a resource.
                * You can't delete a stack if another stack references one of its outputs.
                * You can't modify or remove an output value that is referenced by another stack.
                * You can use intrinsic functions to customize the Name value of an export.

    .PARAMETER Condition
        Logical ID of the condition that this output needs to be true in order to be provisioned.

    .EXAMPLE
        $template = Initialize-Vaporshell -Description "Testing Output"
        $template.AddOutput(
            (
                New-VaporOutput -LogicalId "BackupLoadBalancerDNSName" -Description "The DNSName of the backup load balancer" -Value (Add-FnGetAtt -LogicalNameOfResource "BackupLoadBalancer" -AttributeName "DNSName") -Condition "CreateProdResources"
            )
        )

        When the template is exported, this will convert to:
            {
                "AWSTemplateFormatVersion": "2010-09-09",
                "Description": "Testing Output",
                "Outputs": {
                    "BackupLoadBalancerDNSName": {
                    "Description": "The DNSName of the backup load balancer",
                    "Value": {
                        "Fn::GetAtt": [
                        "BackupLoadBalancer",
                        "DNSName"
                        ]
                    },
                    "Condition": "CreateProdResources"
                    }
                }
            }

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([VSOutput])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [ValidateLogicalId()]
        [string]
        $LogicalId,
        [parameter(Position = 1)]
        [string]
        $Description,
        [parameter(Mandatory,Position = 2)]
        $Value,
        [parameter(Position = 3)]
        [Export]
        $Export,
        [parameter(Position = 4)]
        [string]
        $Condition
    )
    $obj = [VSOutput]::new($PSBoundParameters)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'New-VaporOutput'

function New-VaporParameter {
    <#
    .SYNOPSIS
        Adds a Parameter object to the template

    .DESCRIPTION
        You can use the optional Parameters section to pass values into your template when you create a stack. With parameters, you can create templates that are customized each time you create a stack. Each parameter must contain a value when you create a stack. You can specify a default value to make the parameter optional so that you don't need to pass in a value when creating a stack. AWS CloudFormation will use the default value. For more information about creating stacks, see Working with Stacks.

        The Parameters section consists of the key name Parameters. You can have a maximum of 60 parameters in an AWS CloudFormation template.

        For each parameter, you must declare a logical name, which must be alphanumeric and unique among all logical names within the template. After you declare the parameter's logical name, you can specify the parameter's properties. You must declare parameters as one of following types: String, Number, CommaDelimitedList, or an AWS-specific type. For String, Number, and AWS-specific parameter types, you can define constraints that AWS CloudFormation uses to validate the value of the parameter.

        AWS-specific parameter types are AWS values such as Amazon EC2 key pair names and VPC IDs. AWS CloudFormation validates these parameter values against existing values in users' AWS accounts. AWS-specific parameter types are helpful in catching invalid values at the start of creating or updating a stack.

        ** Important **
            For sensitive parameter values (such as passwords), set the NoEcho property to true. That way, whenever anyone describes your stack, the parameter value is shown as asterisks (*****).

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html

    .PARAMETER LogicalId
        An identifier for the current condition. The logical ID must be alphanumeric (a-z, A-Z, 0-9) and unique within the template.

    .PARAMETER Type
        The Properties type for the parameter (PropertiesType).

        Required: Yes

        You can specify the following values for the Type property:

        String
            A literal string.

            For example, users could specify "MyUserName".

        Number
            An integer or float. AWS CloudFormation validates the parameter value as a number; however, when you use the parameter elsewhere in your template (for example, by using the Ref intrinsic function), the parameter value becomes a string.

            For example, users could specify "8888".

        List<Number>
            An array of integers or floats that are separated by commas. AWS CloudFormation validates the parameter value as numbers; however, when you use the parameter elsewhere in your template (for example, by using the Ref intrinsic function), the parameter value becomes a list of strings.

            For example, users could specify "80,20", and a Ref will result in ["80","20"].

        CommaDelimitedList
            An array of literal strings that are separated by commas. The total number of strings should be one more than the total number of commas. Also, each member string is space trimmed.

            For example, users could specify "test,dev,prod", and a Ref will result in ["test","dev","prod"].

        AWS-Specific Parameter Types

            For AWS-specific parameter types, template users must specify existing AWS values that are in their account. AWS CloudFormation supports the following AWS-specific types:

                AWS::EC2::AvailabilityZone::Name
                An Availability Zone, such as us-west-2a.

                AWS::EC2::Image::Id
                An Amazon EC2 image ID, such as ami-ff527ecf. Note that the AWS CloudFormation console won't show a drop-down list of values for this parameter type.

                AWS::EC2::Instance::Id
                An Amazon EC2 instance ID, such as i-1e731a32.

                AWS::EC2::KeyPair::KeyName
                An Amazon EC2 key pair name.

                AWS::EC2::SecurityGroup::GroupName
                An EC2-Classic or default VPC security group name, such as my-sg-abc.

                AWS::EC2::SecurityGroup::Id
                A security group ID, such as sg-a123fd85.

                AWS::EC2::Subnet::Id
                A subnet ID, such as subnet-123a351e.

                AWS::EC2::Volume::Id
                An Amazon EBS volume ID, such as vol-3cdd3f56.

                AWS::EC2::VPC::Id
                A VPC ID, such as vpc-a123baa3.

                AWS::Route53::HostedZone::Id
                An Amazon Route 53 hosted zone ID, such as Z23YXV4OVPL04A.

                List<AWS::EC2::AvailabilityZone::Name>
                An array of Availability Zones for a region, such as us-west-2a, us-west-2b.

                List<AWS::EC2::Image::Id>
                An array of Amazon EC2 image IDs, such as ami-ff527ecf, ami-e7527ed7. Note that the AWS CloudFormation console won't show a drop-down list of values for this parameter type.

                List<AWS::EC2::Instance::Id>
                An array of Amazon EC2 instance IDs, such as i-1e731a32, i-1e731a34.

                List<AWS::EC2::SecurityGroup::GroupName>
                An array of EC2-Classic or default VPC security group names, such as my-sg-abc, my-sg-def.

                List<AWS::EC2::SecurityGroup::Id>
                An array of security group IDs, such as sg-a123fd85, sg-b456fd85.

                List<AWS::EC2::Subnet::Id>
                An array of subnet IDs, such as subnet-123a351e, subnet-456b351e.

                List<AWS::EC2::Volume::Id>
                An array of Amazon EBS volume IDs, such as vol-3cdd3f56, vol-4cdd3f56.

                List<AWS::EC2::VPC::Id>
                An array of VPC IDs, such as vpc-a123baa3, vpc-b456baa3.

                List<AWS::Route53::HostedZone::Id>
                An array of Amazon Route 53 hosted zone IDs, such as Z23YXV4OVPL04A, Z23YXV4OVPL04B.

                AWS CloudFormation validates input values for these types against existing values in a user's account. For example, with the AWS::EC2::VPC::Id type, a user must enter an existing VPC ID that is in her account and in the region in which she is creating the stack.

                Group and Sort Parameters in the AWS CloudFormation Console

                When you use the AWS CloudFormation console to create or update a stack, the console alphabetically lists input parameters by their logical ID. To override the default ordering, you can use the AWS::CloudFormation::interface metaProperties key. By grouping and ordering parameters, you make it easier for users to specify parameter values. For example, you could group all VPC-related parameters so that they aren't scattered throughout an alphabetical list.

                In the metaProperties key, you can specify the groups to create, the parameters to include in each group, and the order in which the console shows each parameter within its group. You can also define friendly parameter names so that the console shows descriptive names instead of logical IDs. All parameters that you reference in the metaProperties key must be declared in the Parameters section of the template.

    .PARAMETER Default
        A value of the appropriate type for the template to use if no value is specified when a stack is created. If you define constraints for the parameter, you must specify a value that adheres to those constraints.

    .PARAMETER NoEcho
        Whether to mask the parameter value whenever anyone makes a call that describes the stack. If you set the value to true, the parameter value is masked with asterisks (*****).

    .PARAMETER AllowedPattern
        A regular expression that represents the patterns you want to allow for String types.

    .PARAMETER AllowedValues
        An array containing the list of values allowed for the parameter.

    .PARAMETER ConstraintDescription
        A string that explains the constraint when the constraint is violated.

    .PARAMETER Description
        A string of up to 4000 characters that describes the parameter.

    .PARAMETER MaxLength
        An integer value that determines the largest number of characters you want to allow for String types.

    .PARAMETER MaxValue
        A numeric value that determines the largest numeric value you want to allow for Number types.

    .PARAMETER MinLength
        An integer value that determines the smallest number of characters you want to allow for String types.

    .PARAMETER MinValue
        A numeric value that determines the smallest numeric value you want to allow for Number types.

    .EXAMPLE
        $template = Initialize-Vaporshell -Description "Testing Mapping addition"
        $template.AddParameter(
            (New-VaporParameter -LogicalId "DBPort" -Default 3306 -Description "TCP/IP port for the Propertiesbase" -Type "Number" -MinValue 1150 -MaxValue 65535),
            (New-VaporParameter -LogicalId "DBPwd" -NoEcho -Description "The Propertiesbase admin account password" -Type "String" -MinLength 1 -MaxLength 41 -AllowedPattern "^[a-zA-Z0-9]*$")
        )

        When the template is exported, this will convert to:
            {
                "AWSTemplateFormatVersion": "2010-09-09",
                "Description": "Testing Mapping addition",
                "Parameters": {
                    "DBPwd": {
                        "Type": "String",
                        "NoEcho": {
                            "IsPresent": true
                        },
                        "Description": "The Propertiesbase admin account password",
                        "MinLength": 1,
                        "MaxLength": 41,
                        "AllowedPattern": "^[a-zA-Z0-9]*$"
                    },
                    "DBPort": {
                        "Type": "Number",
                        "Default": "3306",
                        "Description": "TCP/IP port for the Propertiesbase",
                        "MinValue": 1150,
                        "MaxValue": 65535
                    }
                }
            }

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([VSParameter])]
    [cmdletbinding()]
    Param
    (
        [parameter(Mandatory,Position = 0)]
        [ValidateLogicalId()]
        [string]
        $LogicalId,
        [parameter(Mandatory,Position = 1)]
        [ValidateSet("String","Number","List<Number>","CommaDelimitedList","AWS::EC2::AvailabilityZone::Name","AWS::EC2::Image::Id","AWS::EC2::Instance::Id","AWS::EC2::KeyPair::KeyName","AWS::EC2::SecurityGroup::GroupName","AWS::EC2::SecurityGroup::Id","AWS::EC2::Subnet::Id","AWS::EC2::Volume::Id","AWS::EC2::VPC::Id","AWS::Route53::HostedZone::Id","List<AWS::EC2::AvailabilityZone::Name>","List<AWS::EC2::Image::Id>","List<AWS::EC2::Instance::Id>","List<AWS::EC2::SecurityGroup::GroupName>","List<AWS::EC2::SecurityGroup::Id>","List<AWS::EC2::Subnet::Id>","List<AWS::EC2::Volume::Id>","List<AWS::EC2::VPC::Id>","List<AWS::Route53::HostedZone::Id>")]
        [string]
        $Type,
        [parameter(Position = 2)]
        [string]
        $Default,
        [parameter(Position = 3)]
        [Switch]
        $NoEcho,
        [parameter(Position = 4)]
        [string]
        $AllowedPattern,
        [parameter(Position = 5)]
        [string[]]
        $AllowedValues,
        [parameter(Position = 6)]
        [string]
        $ConstraintDescription,
        [parameter(Position = 7)]
        [string]
        $Description,
        [parameter(Position = 8)]
        [int]
        $MaxLength,
        [parameter(Position = 9)]
        [int]
        $MaxValue,
        [parameter(Position = 10)]
        [int]
        $MinLength,
        [parameter(Position = 11)]
        [int]
        $MinValue
    )
    $obj = [VSParameter]::new($PSBoundParameters)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'New-VaporParameter'

function New-VaporResource {
    <#
    .SYNOPSIS
        Adds a Resource object to the template

    .DESCRIPTION
        The required Resources section declares the AWS resources that you want to include in the stack, such as an Amazon EC2 instance or an Amazon S3 bucket. You must declare each resource separately; however, if you have multiple resources of the same type, you can declare them together by separating them with commas.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html

    .PARAMETER LogicalId
        The logical ID must be alphanumeric (A-Za-z0-9) and unique within the template. Use the logical name to reference the resource in other parts of the template. For example, if you want to map an Amazon Elastic Block Store volume to an Amazon EC2 instance, you reference the logical IDs to associate the block stores with the instance.

        In addition to the logical ID, certain resources also have a physical ID, which is the actual assigned name for that resource, such as an EC2 instance ID or an S3 bucket name. Use the physical IDs to identify resources outside of AWS CloudFormation templates, but only after the resources have been created. For example, you might give an EC2 instance resource a logical ID of MyEC2Instance; but when AWS CloudFormation creates the instance, AWS CloudFormation automatically generates and assigns a physical ID (such as i-28f9ba55) to the instance. You can use this physical ID to identify the instance and view its properties (such as the DNS name) by using the Amazon EC2 console. For resources that support custom names, you can assign your own names (physical IDs) to help you quickly identify resources. For example, you can name an S3 bucket that stores logs as MyPerformanceLogs.

    .PARAMETER Type
        The resource type identifies the type of resource that you are declaring. For example, AWS::EC2::Instance declares an EC2 instance. For a list of all of the resource types, see AWS Resource Types Reference.

    .PARAMETER Properties
        This is a collection of Resource properties are additional options that you can specify for a resource. For example, for each EC2 instance, you must specify an Amazon Machine Image (AMI) ID for that instance.

        You can use any of these 3 types for this parameter; "System.Collections.Hashtable","System.Management.Automation.PSCustomObject","Vaporshell.Resource.Properties"

    .PARAMETER CreationPolicy
        Use the CreationPolicy attribute when you want to wait on resource configuration actions before stack creation proceeds. For example, if you install and configure software applications on an EC2 instance, you might want those applications to be running before proceeding. In such cases, you can add a CreationPolicy attribute to the instance, and then send a success signal to the instance after the applications are installed and configured.

        You must use the "Add-CreationPolicy" function here.

    .PARAMETER DeletionPolicy
        With the DeletionPolicy attribute you can preserve or (in some cases) backup a resource when its stack is deleted. You specify a DeletionPolicy attribute for each resource that you want to control. If a resource has no DeletionPolicy attribute, AWS CloudFormation deletes the resource by default.

        To keep a resource when its stack is deleted, specify Retain for that resource. You can use retain for any resource. For example, you can retain a nested stack, S3 bucket, or EC2 instance so that you can continue to use or modify those resources after you delete their stacks.

        You must use one of the following options: "Delete","Retain","Snapshot"

    .PARAMETER DependsOn
        With the DependsOn attribute you can specify that the creation of a specific resource follows another. When you add a DependsOn attribute to a resource, that resource is created only after the creation of the resource specified in the DependsOn attribute.

        This parameter takes a string or list of strings representing Logical IDs of resources that must be created prior to this resource being created.

    .PARAMETER Metadata
        The Metadata attribute enables you to associate structured data with a resource. By adding a Metadata attribute to a resource, you can add data in JSON or YAML to the resource declaration. In addition, you can use intrinsic functions (such as GetAtt and Ref), parameters, and pseudo parameters within the Metadata attribute to add those interpreted values.

        You must use a PSCustomObject containing key/value pairs here. This will be returned when describing the resource using AWS CLI.

    .PARAMETER UpdatePolicy
        Use the UpdatePolicy attribute to specify how AWS CloudFormation handles updates to the AWS::AutoScaling::AutoScalingGroup resource. AWS CloudFormation invokes one of three update policies depending on the type of change you make or whether a scheduled action is associated with the Auto Scaling group.

        You must use the "Add-UpdatePolicy" function here.

    .PARAMETER Condition
        Logical ID of the condition that this resource needs to be true in order for this resource to be provisioned.

    .EXAMPLE
        $template = Initialize-Vaporshell -Description "Testing Resource addition"
        $template.AddResource((
            New-VaporResource -LogicalId "MyInstance" -Type "AWS::EC2::Instance" -Properties [PSCustomObject]@{
                "UserProperties" = (Add-FnBase64 -ValueToEncode (Add-FnJoin -ListOfValues "Queue=",(Add-FnRef -Ref "MyQueue")))
                "AvailabilityZone" = "us-east-1a"
                "ImageId" = "ami-20b65349"
            }
        ))

        When the template is exported, this will convert to:
```json
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Testing Resource addition",
    "Resources": {
        "MyInstance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "UserProperties": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "Queue=",
                                {
                                "Ref": "MyQueue"
                                }
                            ]
                        ]
                    }
                },
                "AvailabilityZone": "us-east-1a",
                "ImageId": "ami-20b65349"
            }
        }
    }
}
```

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([VSResource])]
    [cmdletbinding()]
    Param(
        [parameter(Mandatory,Position = 0)]
        [ValidateLogicalId()]
        [string]
        $LogicalId,
        [parameter(Mandatory,Position = 1)]
        [string]
        $Type,
        [parameter(Position = 2)]
        [VSHashtable]
        $Properties,
        [parameter(Position = 3)]
        [CreationPolicy]
        $CreationPolicy,
        [parameter(Position = 4)]
        [DeletionPolicy]
        $DeletionPolicy,
        [parameter()]
        [UpdateReplacePolicy]
        $UpdateReplacePolicy,
        [parameter(Position = 5)]
        [string[]]
        $DependsOn,
        [parameter(Position = 6)]
        [System.Collections.IDictionary]
        $Metadata,
        [parameter(Position = 7)]
        [UpdatePolicy]
        $UpdatePolicy,
        [parameter(Position = 8)]
        [object]
        $Condition
    )
    $obj = [VSResource]::new($PSBoundParameters)
    Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
    $obj
}

Export-ModuleMember -Function 'New-VaporResource'

function Add-CreationPolicy {
    <#
    .SYNOPSIS
        Adds a CreationPolicy property to a resoure on the template

    .DESCRIPTION
        Associate the CreationPolicy attribute with a resource to prevent its status from reaching create complete until AWS CloudFormation receives a specified number of success signals or the timeout period is exceeded. To signal a resource, you can use the cfn-signal helper script or SignalResource API. AWS CloudFormation publishes valid signals to the stack events so that you track the number of signals sent.

        The creation policy is invoked only when AWS CloudFormation creates the associated resource. Currently, the only AWS CloudFormation resources that support creation policies are AWS::AutoScaling::AutoScalingGroup, AWS::EC2::Instance, and AWS::CloudFormation::WaitCondition.

        Use the CreationPolicy attribute when you want to wait on resource configuration actions before stack creation proceeds. For example, if you install and configure software applications on an EC2 instance, you might want those applications to be running before proceeding. In such cases, you can add a CreationPolicy attribute to the instance, and then send a success signal to the instance after the applications are installed and configured.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-creationpolicy.html

    .PARAMETER AutoScalingCreationPolicy
        For an Auto Scaling group replacement update, specifies how many instances must signal success for the update to succeed.

        Parameter accepts a PSCustomObject. Use this if you are customizing the AutoScalingCreationPolicy properties outside of MinSuccessfulInstancesPercent.

    .PARAMETER MinSuccessfulInstancesPercent
        Specifies the percentage of instances in an Auto Scaling replacement update that must signal success for the update to succeed. You can specify a value from 0 to 100. AWS CloudFormation rounds to the nearest tenth of a percent. For example, if you update five instances with a minimum successful percentage of 50, three instances must signal success. If an instance doesn't send a signal within the time specified by the Timeout property, AWS CloudFormation assumes that the instance wasn't created.

    .PARAMETER ResourceSignal
        When AWS CloudFormation creates the associated resource, configures the number of required success signals and the length of time that AWS CloudFormation waits for those signals.

        Parameter accepts a PSCustomObject. Use this if you are customizing the ResourceSignal properties outside of Count and/or Timeout.

    .PARAMETER Count
        The number of success signals AWS CloudFormation must receive before it sets the resource status as CREATE_COMPLETE. If the resource receives a failure signal or doesn't receive the specified number of signals before the timeout period expires, the resource creation fails and AWS CloudFormation rolls the stack back.

    .PARAMETER Timeout
        The length of time that AWS CloudFormation waits for the number of signals that was specified in the Count property. The timeout period starts after AWS CloudFormation starts creating the resource, and the timeout expires no sooner than the time you specify but can occur shortly thereafter. The maximum time that you can specify is 12 hours.

        The value must be in ISO8601 duration format, in the form: "PT#H#M#S", where each # is the number of hours, minutes, and seconds, respectively. For best results, specify a period of time that gives your instances plenty of time to get up and running. A shorter timeout can cause a rollback.

    .EXAMPLE
        $templateInit = Initialize-Vaporshell -Description "Testing"
        $templateInit.AddResource(
            (
                New-VaporResource -LogicalId "AutoScalingGroup" -Type "AWS::AutoScaling::AutoScalingGroup" -Properties ([PSCustomObject][Ordered]@{
                        "AvailabilityZones" = (Add-FnGetAZs -Region "$_AWSRegion")
                        "LaunchConfigurationName" = (Add-FnRef -Ref "LaunchConfig")
                        "DesiredCapacity" = "3"
                        "MinSize" = "1"
                        "MaxSize" = "4"
                    }) -CreationPolicy (Add-CreationPolicy -Count 3 -Timeout "PT15M") -UpdatePolicy (Add-UpdatePolicy -IgnoreUnmodifiedGroupSizeProperties True -MinInstancesInService 1 -MaxBatchSize 2 -WaitOnResourceSignals True -PauseTime "PT10M")
            )
        )

        When the template is exported, this will convert to:
```json
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Testing",
    "Resources": {
        "AutoScalingGroup": {
            "Type": "AWS::AutoScaling::AutoScalingGroup",
            "Properties": {
                "AvailabilityZones": {
                    "Fn::GetAZs": "AWS::Region"
                },
                "LaunchConfigurationName": {
                    "Ref": "LaunchConfig"
                },
                "DesiredCapacity": "3",
                "MinSize": "1",
                "MaxSize": "4"
            },
            "CreationPolicy": {
                "ResourceSignal": {
                    "Count": "3",
                    "Timeout": "PT15M"
                }
            },
            "UpdatePolicy": {
                "AutoScalingScheduledAction": {
                    "IgnoreUnmodifiedGroupSizeProperties": "true"
                },
                "AutoScalingRollingUpdate": {
                    "MinInstancesInService": "1",
                    "MaxBatchSize": "2",
                    "WaitOnResourceSignals": "true",
                    "PauseTime": "PT10M"
                }
            }
        }
    }
}
```

    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([CreationPolicy])]
    [CmdletBinding(DefaultParameterSetName="CountTimeout")]
    Param(
        [parameter(Position = 0)]
        [parameter(ParameterSetName="AutoScalingCreationPolicy")]
        [parameter(ParameterSetName="ResourceSignal")]
        [parameter(ParameterSetName="CountTimeout")]
        [AutoScalingCreationPolicy]
        $AutoScalingCreationPolicy,
        [parameter()]
        [parameter(ParameterSetName="MinSuccessfulInstancesPercent")]
        [parameter(ParameterSetName="ResourceSignal")]
        [parameter(ParameterSetName="CountTimeout")]
        [ValidateRange(0,100)]
        [object]
        $MinSuccessfulInstancesPercent,
        [parameter(Position = 2)]
        [parameter(ParameterSetName="AutoScalingCreationPolicy")]
        [parameter(ParameterSetName="MinSuccessfulInstancesPercent")]
        [parameter(ParameterSetName="ResourceSignal")]
        [ResourceSignal]
        $ResourceSignal,
        [parameter(Position = 3)]
        [parameter(ParameterSetName="AutoScalingCreationPolicy")]
        [parameter(ParameterSetName="MinSuccessfulInstancesPercent")]
        [parameter(ParameterSetName="CountTimeout")]
        [object]
        $Count,
        [parameter(Position = 4)]
        [parameter(ParameterSetName="AutoScalingCreationPolicy")]
        [parameter(ParameterSetName="MinSuccessfulInstancesPercent")]
        [parameter(ParameterSetName="CountTimeout")]
        [object]
        $Timeout
    )
    Begin {
        if (!($PSBoundParameters.Keys.Count)) {
            $PSCmdlet.ThrowTerminatingError((New-VSError -String "No parameters passed! Please specify at least one parameter, otherwise exclude this call of $($MyInvocation.MyCommand)."))
        }
        $obj = [CreationPolicy]::new()
        $ASCP = [AutoScalingCreationPolicy]::new()
        $RS = [ResourceSignal]::new()
    }
    Process {
        switch ($PSBoundParameters.Keys) {
            'AutoScalingCreationPolicy' {
                $obj.AutoScalingCreationPolicy = $AutoScalingCreationPolicy
            }
            'MinSuccessfulInstancesPercent' {
                $ASCP.MinSuccessfulInstancesPercent = $MinSuccessfulInstancesPercent
                $obj.AutoScalingCreationPolicy = $ASCP
            }
            'ResourceSignal' {
                $obj.ResourceSignal = $ResourceSignal
            }
            'Count' {
                $RS.Count = $Count
            }
            'Timeout' {
                $RS.Timeout = $Timeout
            }
        }
        if ($RS.Timeout -or $RS.Count) {
            $obj.ResourceSignal = $RS
        }
    }
    End {
        Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)`n"
        $obj
    }
}

Export-ModuleMember -Function 'Add-CreationPolicy'

function Add-UpdatePolicy {
    <#
    .SYNOPSIS
        Adds an UpdatePolicy property to a resoure on the template

    .DESCRIPTION
        Use the UpdatePolicy attribute to specify how AWS CloudFormation handles updates to the AWS::AutoScaling::AutoScalingGroup resource. AWS CloudFormation invokes one of three update policies depending on the type of change you make or whether a scheduled action is associated with the Auto Scaling group.

        * The AutoScalingReplacingUpdate and AutoScalingRollingUpdate policies apply only when you do one or more of the following:
            * Change the Auto Scaling group's AWS::AutoScaling::LaunchConfiguration.
            * Change the Auto Scaling group's VPCZoneIdentifier property
            * Update an Auto Scaling group that contains instances that don't match the current LaunchConfiguration.
        * If both the AutoScalingReplacingUpdate and AutoScalingRollingUpdate policies are specified, setting the WillReplace property to true gives AutoScalingReplacingUpdate precedence.
        * The AutoScalingScheduledAction policy applies when you update a stack that includes an Auto Scaling group with an associated scheduled action.

    .LINK
        http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html

    .PARAMETER AutoScalingReplacingUpdate
        To specify how AWS CloudFormation handles replacement updates for an Auto Scaling group, use the AutoScalingReplacingUpdate policy. This policy enables you to specify whether AWS CloudFormation replaces an Auto Scaling group with a new one or replaces only the instances in the Auto Scaling group.

            **Important**
                Before attempting an update, ensure that you have sufficient Amazon EC2 capacity for both your old and new Auto Scaling groups.

        Parameter accepts a PSCustomObject. Use this if you are customizing the AutoScalingReplacingUpdate properties outside of WillReplace.

    .PARAMETER WillReplace
        Specifies whether an Auto Scaling group and the instances it contains are replaced during an update. During replacement, AWS CloudFormation retains the old group until it finishes creating the new one. If the update fails, AWS CloudFormation can roll back to the old Auto Scaling group and delete the new Auto Scaling group.

        While AWS CloudFormation creates the new group, it doesn't detach or attach any instances. After successfully creating the new Auto Scaling group, AWS CloudFormation deletes the old Auto Scaling group during the cleanup process.

        When you set the WillReplace parameter, remember to specify a matching CreationPolicy. If the minimum number of instances (specified by the WillReplace property) don't signal success within the Timeout period (specified in the CreationPolicy policy), the replacement update fails and AWS CloudFormation rolls back to the old Auto Scaling group.

    .PARAMETER AutoScalingRollingUpdate
        To specify how AWS CloudFormation handles rolling updates for an Auto Scaling group, use the AutoScalingRollingUpdate policy. Rolling updates enable you to specify whether AWS CloudFormation updates instances that are in an Auto Scaling group in batches or all at once.

            **Important**
                During a rolling update, some Auto Scaling processes might make changes to the Auto Scaling group before AWS CloudFormation completes the rolling update. These changes might cause the rolling update to fail. To prevent Auto Scaling from running processes during a rolling update, use the SuspendProcesses property.

        Parameter accepts a PSCustomObject. Use this if you are customizing the AutoScalingRollingUpdate properties outside of MaxBatchSize, MinInstancesInService, WillReplace, PauseTime, SuspendProcesses, and/or WaitOnAutoScalingRollingUpdates.

    .PARAMETER MaxBatchSize
        Specifies the maximum number of instances that AWS CloudFormation updates.

    .PARAMETER MinInstancesInService
        Specifies the minimum number of instances that must be in service within the Auto Scaling group while AWS CloudFormation updates old instances.

    .PARAMETER WillReplace
        Specifies the percentage of instances in an Auto Scaling rolling update that must signal success for an update to succeed. You can specify a value from 0 to 100. AWS CloudFormation rounds to the nearest tenth of a percent. For example, if you update five instances with a minimum successful percentage of 50, three instances must signal success.

        If an instance doesn't send a signal within the time specified in the PauseTime property, AWS CloudFormation assumes that the instance wasn't updated.

        If you specify this property, you must also enable the WaitOnAutoScalingRollingUpdates and PauseTime properties.

    .PARAMETER PauseTime
        The amount of time that AWS CloudFormation pauses after making a change to a batch of instances to give those instances time to start software applications. For example, you might need to specify PauseTime when scaling up the number of instances in an Auto Scaling group.

        If you enable the WaitOnAutoScalingRollingUpdates property, PauseTime is the amount of time that AWS CloudFormation should wait for the Auto Scaling group to receive the required number of valid signals from added or replaced instances. If the PauseTime is exceeded before the Auto Scaling group receives the required number of signals, the update fails. For best results, specify a time period that gives your applications sufficient time to get started. If the update needs to be rolled back, a short PauseTime can cause the rollback to fail.

        Specify PauseTime in the ISO8601 duration format (in the format PT#H#M#S, where each # is the number of hours, minutes, and seconds, respectively). The maximum PauseTime is one hour (PT1H).

        Default: PT0S (zero seconds). If the WaitOnAutoScalingRollingUpdates property is set to true, the default is PT5M.

    .PARAMETER SuspendProcesses
        Specifies the Auto Scaling processes to suspend during a stack update. Suspending processes prevents Auto Scaling from objecterfering with a stack update. For example, you can suspend alarming so that Auto Scaling doesn't execute scaling policies associated with an alarm. For valid values, see the `ScalingProcesses.member.N parameter` for the SuspendProcesses action in the Auto Scaling API Reference.

    .PARAMETER WaitOnAutoScalingRollingUpdates
        Specifies whether the Auto Scaling group waits on signals from new instances during an update. Use this property to ensure that instances have completed installing and configuring applications before the Auto Scaling group update proceeds. AWS CloudFormation suspends the update of an Auto Scaling group after new EC2 instances are launched objecto the group. AWS CloudFormation must receive a signal from each new instance within the specified PauseTime before continuing the update. To signal the Auto Scaling group, use the cfn-signal helper script or SignalResource API.

        To have instances wait for an Elastic Load Balancing health check before they signal success, add a health-check verification by using the cfn-init helper script. For an example, see the `verify_instance_health` command in the Auto Scaling rolling updates sample template.

    .PARAMETER AutoScalingScheduledAction
        To specify how AWS CloudFormation handles updates for the MinSize, MaxSize, and DesiredCapacity properties when the AWS::AutoScaling::AutoScalingGroup resource has an associated scheduled action, use the AutoScalingScheduledAction policy.

        With scheduled actions, the group size properties of an Auto Scaling group can change at any time. When you update a stack with an Auto Scaling group and scheduled action, AWS CloudFormation always sets the group size property values of your Auto Scaling group to the values that are defined in the AWS::AutoScaling::AutoScalingGroup resource of your template, even if a scheduled action is in effect.

        If you do not want AWS CloudFormation to change any of the group size property values when you have a scheduled action in effect, use the AutoScalingScheduledAction update policy to prevent AWS CloudFormation from changing the MinSize, MaxSize, or DesiredCapacity properties unless you have modified these values in your template.

        Parameter accepts a PSCustomObject. Use this if you are customizing the AutoScalingScheduledAction properties outside of IgnoreUnmodifiedGroupSizeProperties.

    .PARAMETER IgnoreUnmodifiedGroupSizeProperties
        Specifies whether AWS CloudFormation ignores differences in group size properties between your current Auto Scaling group and the Auto Scaling group described in the AWS::AutoScaling::AutoScalingGroup resource of your template during a stack update. If you modify any of the group size property values in your template, AWS CloudFormation uses the modified values and updates your Auto Scaling group.

    .EXAMPLE
        $templateInit = Initialize-Vaporshell -Description "Testing"
        $templateInit.AddResource(
            (
                New-VaporResource -LogicalId "AutoScalingGroup" -Type "AWS::AutoScaling::AutoScalingGroup" -Properties ([PSCustomObject][Ordered]@{
                        "AvailabilityZones" = (Add-FnGetAZs -Region "$_AWSRegion")
                        "LaunchConfigurationName" = (Add-FnRef -Ref "LaunchConfig")
                        "DesiredCapacity" = "3"
                        "MinSize" = "1"
                        "MaxSize" = "4"
                    }) -CreationPolicy (Add-CreationPolicy -Count 3 -Timeout "PT15M") -UpdatePolicy (Add-UpdatePolicy -IgnoreUnmodifiedGroupSizeProperties True -MinInstancesInService 1 -MaxBatchSize 2 -WaitOnResourceSignals True -PauseTime "PT10M")
            )
        )

        When the template is exported, this will convert to:
```json
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Testing",
    "Resources": {
        "AutoScalingGroup": {
            "Type": "AWS::AutoScaling::AutoScalingGroup",
            "Properties": {
                "AvailabilityZones": {
                    "Fn::GetAZs": "AWS::Region"
                },
                "LaunchConfigurationName": {
                    "Ref": "LaunchConfig"
                },
                "DesiredCapacity": "3",
                "MinSize": "1",
                "MaxSize": "4"
            },
            "CreationPolicy": {
                "ResourceSignal": {
                    "Count": "3",
                    "Timeout": "PT15M"
                }
            },
            "UpdatePolicy": {
                "AutoScalingScheduledAction": {
                    "IgnoreUnmodifiedGroupSizeProperties": "true"
                },
                "AutoScalingRollingUpdate": {
                    "MinInstancesInService": "1",
                    "MaxBatchSize": "2",
                    "WaitOnResourceSignals": "true",
                    "PauseTime": "PT10M"
                }
            }
        }
    }
}
```
    .FUNCTIONALITY
        Vaporshell
    #>

    [OutputType([UpdatePolicy])]
    [cmdletbinding(DefaultParameterSetName="AutoScalingRollingUpdateDetails")]
    Param(
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingRollingUpdate")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [AutoScalingReplacingUpdate]
        $AutoScalingReplacingUpdate,
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdate")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [object]
        $WillReplace,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdate")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [AutoScalingRollingUpdate]
        $AutoScalingRollingUpdate,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [object]
        $MaxBatchSize,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [object]
        $MinInstancesInService,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdate")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdateDetails")]
        [object]
        $MinSuccessfulInstancesPercent,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdate")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdateDetails")]
        [object]
        $PauseTime,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdate")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdateDetails")]
        [AutoScalingProcess[]]
        $SuspendProcesses,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdate")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdateDetails")]
        [object]
        $WaitOnResourceSignals,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdate")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdate")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdateDetails")]
        [AutoScalingScheduledAction]
        $AutoScalingScheduledAction,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdate")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdate")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdateDetails")]
        [object]
        $IgnoreUnmodifiedGroupSizeProperties,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdate")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdate")]
        [CodeDeployLambdaAliasUpdate]
        $CodeDeployLambdaAliasUpdate,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdate")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdateDetails")]
        [object]
        $AfterAllowTrafficHook,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdate")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdateDetails")]
        [object]
        $ApplicationName,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdate")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdateDetails")]
        [object]
        $BeforeAllowTrafficHook,
        [parameter(ParameterSetName="AutoScalingReplacingUpdate")]
        [parameter(ParameterSetName="AutoScalingReplacingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingRollingUpdate")]
        [parameter(ParameterSetName="AutoScalingRollingUpdateDetails")]
        [parameter(ParameterSetName="AutoScalingScheduledAction")]
        [parameter(ParameterSetName="AutoScalingScheduledActionDetails")]
        [parameter(ParameterSetName="CodeDeployLambdaAliasUpdateDetails")]
        [object]
        $DeploymentGroupName
    )
    Begin {
        if (!($PSBoundParameters.Keys.Count)) {
            $PSCmdlet.ThrowTerminatingError((New-VSError -object "No parameters passed! Please specify at least one parameter, otherwise exclude this call of $($MyInvocation.MyCommand)."))
        }
        $obj = [UpdatePolicy]::new()
        $ASRepU = [AutoScalingReplacingUpdate]::new()
        $ASRolU = [AutoScalingRollingUpdate]::new()
        $ASSA = [AutoScalingScheduledAction]::new()
        $ASSA = [AutoScalingScheduledAction]::new()
        $CDLA = [CodeDeployLambdaAliasUpdate]::new()
    }
    Process {
        switch ($PSBoundParameters.Keys) {
            'AutoScalingReplacingUpdate' {
                $obj.AutoScalingReplacingUpdate = $AutoScalingReplacingUpdate
            }
            'WillReplace' {
                $ASRepU.WillReplace = $WillReplace
                $obj.AutoScalingReplacingUpdate = $ASRepU
            }
            'AutoScalingRollingUpdate' {
                $obj.AutoScalingRollingUpdate = $AutoScalingRollingUpdate
            }
            'MaxBatchSize' {
                $ASRolU.MaxBatchSize = $MaxBatchSize
            }
            'MinInstancesInService' {
                $ASRolU.MinInstancesInService = $MinInstancesInService
            }
            'MinSuccessfulInstancesPercent' {
                $ASRolU.MinSuccessfulInstancesPercent = $MinSuccessfulInstancesPercent
            }
            'PauseTime' {
                $ASRolU.PauseTime = $PauseTime
            }
            'SuspendProcesses' {
                $ASRolU.SuspendProcesses = $SuspendProcesses
            }
            'WaitOnResourceSignals' {
                $ASRolU.WaitOnResourceSignals = $WaitOnResourceSignals
            }
            'AutoScalingScheduledAction' {
                $obj.AutoScalingScheduledAction = $AutoScalingScheduledAction
            }
            'IgnoreUnmodifiedGroupSizeProperties' {
                $ASSA.IgnoreUnmodifiedGroupSizeProperties = $IgnoreUnmodifiedGroupSizeProperties
                $obj.AutoScalingScheduledAction = $ASSA
            }
            'CodeDeployLambdaAliasUpdate' {
                $obj.CodeDeployLambdaAliasUpdate = $CodeDeployLambdaAliasUpdate
            }
            'AfterAllowTrafficHook' {
                $CDLA.AfterAllowTrafficHook = $AfterAllowTrafficHook
            }
            'ApplicationName' {
                $CDLA.ApplicationName = $ApplicationName
            }
            'BeforeAllowTrafficHook' {
                $CDLA.BeforeAllowTrafficHook = $BeforeAllowTrafficHook
            }
            'DeploymentGroupName' {
                $CDLA.DeploymentGroupName = $DeploymentGroupName
            }
        }
        foreach ($prop in @('MaxBatchSize','MinInstancesInService','MinSuccessfulInstancesPercent','PauseTime','SuspendProcesses','WaitOnResourceSignals')) {
            if ($prop -in $PSBoundParameters.Keys) {
                $obj.AutoScalingRollingUpdate = $ASRolU
                break
            }
        }
        foreach ($prop in @('AfterAllowTrafficHook','ApplicationName','BeforeAllowTrafficHook','DeploymentGroupName')) {
            if ($prop -in $PSBoundParameters.Keys) {
                $obj.CodeDeployLambdaAliasUpdate = $CDLA
                break
            }
        }
    }
    End {
        Write-Verbose "Resulting JSON from $($MyInvocation.MyCommand): `n$($obj.ToJson() | Format-Json)"
        $obj
    }
}

Export-ModuleMember -Function 'Add-UpdatePolicy'

function Add-PolicyAction {
    <#
    .SYNOPSIS
    Adds a tab-completing Policy Action for an IAM policy document

    .DESCRIPTION
    Adds a tab-completing Policy Action for an IAM policy document

    .PARAMETER Action
    The tab-completing list of available actions.

    .PARAMETER Custom
    Anything custom, i.e. containing wildcards like s3:List*

    .EXAMPLE
    $policyDoc = [PSCustomObject]@{
        Version = '2012-10-17'
        Statement = @(
            @{
                Effect = 'Allow'
                Action = @(
                    Add-PolicyAction "ssm:*"
                )
                Resource = $documentArn
            }
        )
    }
    $newVSIAMPolicySplat = @{
        LogicalId = "CloudWatchSSMRunCommandPolicy"
        PolicyName = "CloudWatchSSMRunCommandPolicy"
        PolicyDocument = $policyDoc
    }
    $iamPolicy = New-VSIAMPolicy @newVSIAMPolicySplat
    #>

    [CmdletBinding(DefaultParameterSetName = "Custom")]
    Param(
        [parameter(Mandatory = $true,Position = 0,ParameterSetName = "Action")]
        [ValidateSet('a4b:AssociateDeviceWithRoom','a4b:AssociateSkillGroupWithRoom','a4b:CreateProfile','a4b:CreateRoom','a4b:CreateSkillGroup','a4b:CreateUser','a4b:DeleteProfile','a4b:DeleteRoom','a4b:DeleteRoomSkillParameter','a4b:DeleteSkillGroup','a4b:DeleteUser','a4b:DisassociateDeviceFromRoom','a4b:DisassociateSkillGroupFromRoom','a4b:GetDevice','a4b:GetProfile','a4b:GetRoom','a4b:GetRoomSkillParameter','a4b:GetSkillGroup','a4b:ListSkills','a4b:ListTags','a4b:PutRoomSkillParameter','a4b:ResolveRoom','a4b:RevokeInvitation','a4b:SearchDevices','a4b:SearchProfiles','a4b:SearchRooms','a4b:SearchSkillGroups','a4b:SearchUsers','a4b:SendInvitation','a4b:StartDeviceSync','a4b:TagResource','a4b:UntagResource','a4b:UpdateDevice','a4b:UpdateProfile','a4b:UpdateRoom','a4b:UpdateSkillGroup','acm:AddTagsToCertificate','acm:DeleteCertificate','acm:DescribeCertificate','acm:GetCertificate','acm:ImportCertificate','acm:ListCertificates','acm:ListTagsForCertificate','acm:RemoveTagsFromCertificate','acm:RequestCertificate','acm:ResendValidationEmail','apigateway:DELETE','apigateway:GET','apigateway:HEAD','apigateway:OPTIONS','apigateway:PATCH','apigateway:POST','apigateway:PUT','application-autoscaling:DeleteScalingPolicy','application-autoscaling:DeleteScheduledAction','application-autoscaling:DeregisterScalableTarget','application-autoscaling:DescribeScalableTargets','application-autoscaling:DescribeScalingActivities','application-autoscaling:DescribeScalingPolicies','application-autoscaling:DescribeScheduledActions','application-autoscaling:PutScalingPolicy','application-autoscaling:PutScheduledAction','application-autoscaling:RegisterScalableTarget','appstream:AssociateFleet','appstream:CreateDirectoryConfig','appstream:CreateFleet','appstream:CreateImageBuilder','appstream:CreateImageBuilderStreamingURL','appstream:CreateStack','appstream:CreateStreamingURL','appstream:DeleteDirectoryConfig','appstream:DeleteFleet','appstream:DeleteImage','appstream:DeleteImageBuilder','appstream:DeleteStack','appstream:DescribeDirectoryConfigs','appstream:DescribeFleets','appstream:DescribeImageBuilders','appstream:DescribeImages','appstream:DescribeSessions','appstream:DescribeStacks','appstream:DisassociateFleet','appstream:ExpireSession','appstream:ListAssociatedFleets','appstream:ListAssociatedStacks','appstream:ListTagsForResource','appstream:StartFleet','appstream:StartImageBuilder','appstream:StopFleet','appstream:StopImageBuilder','appstream:Stream','appstream:TagResource','appstream:UntagResource','appstream:UpdateDirectoryConfig','appstream:UpdateFleet','appstream:UpdateStack','appsync:CreateApiKey','appsync:CreateDataSource','appsync:CreateGraphqlApi','appsync:CreateResolver','appsync:CreateType','appsync:DeleteApiKey','appsync:DeleteDataSource','appsync:DeleteGraphqlApi','appsync:DeleteResolver','appsync:DeleteType','appsync:GetDataSource','appsync:GetGraphqlApi','appsync:GetIntrospectionSchema','appsync:GetResolver','appsync:GetSchemaCreationStatus','appsync:GetType','appsync:GraphQL','appsync:ListApiKeys','appsync:ListDataSources','appsync:ListGraphqlApis','appsync:ListResolvers','appsync:ListTypes','appsync:StartSchemaCreation','appsync:UpdateApiKey','appsync:UpdateDataSource','appsync:UpdateGraphqlApi','appsync:UpdateResolver','appsync:UpdateType','artifact:AcceptAgreement','artifact:DownloadAgreement','artifact:Get','artifact:TerminateAgreement','athena:BatchGetNamedQuery','athena:BatchGetQueryExecution','athena:CancelQueryExecution','athena:CreateNamedQuery','athena:DeleteNamedQuery','athena:GetCatalogs','athena:GetExecutionEngine','athena:GetExecutionEngines','athena:GetNamedQuery','athena:GetNamespace','athena:GetNamespaces','athena:GetQueryExecution','athena:GetQueryExecutions','athena:GetQueryResults','athena:GetTable','athena:GetTables','athena:ListNamedQueries','athena:ListQueryExecutions','athena:RunQuery','athena:StartQueryExecution','athena:StopQueryExecution','autoscaling:AttachInstances','autoscaling:AttachLoadBalancers','autoscaling:AttachLoadBalancerTargetGroups','autoscaling:CompleteLifecycleAction','autoscaling:CreateAutoScalingGroup','autoscaling:CreateLaunchConfiguration','autoscaling:CreateOrUpdateTags','autoscaling:DeleteAutoScalingGroup','autoscaling:DeleteLaunchConfiguration','autoscaling:DeleteLifecycleHook','autoscaling:DeleteNotificationConfiguration','autoscaling:DeletePolicy','autoscaling:DeleteScheduledAction','autoscaling:DeleteTags','autoscaling:DescribeAccountLimits','autoscaling:DescribeAdjustmentTypes','autoscaling:DescribeAutoScalingGroups','autoscaling:DescribeAutoScalingInstances','autoscaling:DescribeAutoScalingNotificationTypes','autoscaling:DescribeLaunchConfigurations','autoscaling:DescribeLifecycleHooks','autoscaling:DescribeLifecycleHookTypes','autoscaling:DescribeLoadBalancers','autoscaling:DescribeLoadBalancerTargetGroups','autoscaling:DescribeMetricCollectionTypes','autoscaling:DescribeNotificationConfigurations','autoscaling:DescribePolicies','autoscaling:DescribeScalingActivities','autoscaling:DescribeScalingProcessTypes','autoscaling:DescribeScheduledActions','autoscaling:DescribeTags','autoscaling:DescribeTerminationPolicyTypes','autoscaling:DetachInstances','autoscaling:DetachLoadBalancers','autoscaling:DetachLoadBalancerTargetGroups','autoscaling:DisableMetricsCollection','autoscaling:EnableMetricsCollection','autoscaling:EnterStandby','autoscaling:ExecutePolicy','autoscaling:ExitStandby','autoscaling:PutLifecycleHook','autoscaling:PutNotificationConfiguration','autoscaling:PutScalingPolicy','autoscaling:PutScheduledUpdateGroupAction','autoscaling:RecordLifecycleActionHeartbeat','autoscaling:ResumeProcesses','autoscaling:SetDesiredCapacity','autoscaling:SetInstanceHealth','autoscaling:SetInstanceProtection','autoscaling:SuspendProcesses','autoscaling:TerminateInstanceInAutoScalingGroup','autoscaling:UpdateAutoScalingGroup','autoscaling-plans:CreateScalingPlan','autoscaling-plans:DeleteScalingPlan','autoscaling-plans:DescribeScalingPlanResources','autoscaling-plans:DescribeScalingPlans','aws-marketplace:BatchMeterUsage','aws-marketplace:MeterUsage','aws-marketplace:ResolveCustomer','aws-marketplace:Subscribe','aws-marketplace:Unsubscribe','aws-marketplace:ViewSubscriptions','aws-marketplace-management:uploadFiles','aws-marketplace-management:viewMarketing','aws-marketplace-management:viewReports','aws-marketplace-management:viewSupport','aws-portal:ModifyAccount','aws-portal:ModifyBilling','aws-portal:ModifyPaymentMethods','aws-portal:ViewAccount','aws-portal:ViewBilling','aws-portal:ViewPaymentMethods','aws-portal:ViewUsage','batch:CancelJob','batch:CreateComputeEnvironment','batch:CreateJobQueue','batch:DeleteComputeEnvironment','batch:DeleteJobQueue','batch:DeregisterJobDefinition','batch:DescribeComputeEnvironments','batch:DescribeJobDefinitions','batch:DescribeJobQueues','batch:DescribeJobs','batch:ListJobs','batch:RegisterJobDefinition','batch:SubmitJob','batch:TerminateJob','batch:UpdateComputeEnvironment','batch:UpdateJobQueue','budgets:ModifyBudget','budgets:ViewBudget','ce:GetCostAndUsage','ce:GetDimensionValues','ce:GetReservationUtilization','ce:GetTags','chime:AcceptDelegate','chime:ActivateUsers','chime:AddDomain','chime:AddOrUpdateGroups','chime:AuthorizeDirectory','chime:ConnectDirectory','chime:CreateAccount','chime:CreateCDRBucket','chime:DeleteAccount','chime:DeleteCDRBucket','chime:DeleteDelegate','chime:DeleteDomain','chime:DeleteGroups','chime:DisconnectDirectory','chime:GetAccount','chime:GetAccountResource','chime:GetAccountSettings','chime:GetCDRBucket','chime:GetDomain','chime:GetUser','chime:GetUserByEmail','chime:InviteDelegate','chime:InviteUsers','chime:ListAccounts','chime:ListCDRBucket','chime:ListDelegates','chime:ListDirectories','chime:ListDomains','chime:ListGroups','chime:ListUsers','chime:LogoutUser','chime:RenameAccount','chime:RenewDelegate','chime:ResetAccountResource','chime:ResetPersonalPin','chime:SubmitSupportRequest','chime:SuspendUsers','chime:UnauthorizeDirectory','chime:UpdateAccountResource','chime:UpdateAccountSettings','chime:UpdateCDRBucket','chime:UpdateSupportedLicenses','chime:UpdateUserLicenses','chime:ValidateAccountResource','chime:ValidateDelegate','cloud9:CreateEnvironmentEC2','cloud9:CreateEnvironmentMembership','cloud9:CreateEnvironmentSSH','cloud9:DeleteEnvironment','cloud9:DeleteEnvironmentMembership','cloud9:DescribeEnvironmentMemberships','cloud9:DescribeEnvironments','cloud9:DescribeEnvironmentStatus','cloud9:GetUserPublicKey','cloud9:ListEnvironments','cloud9:UpdateEnvironment','cloud9:UpdateEnvironmentMembership','cloud9:ValidateEnvironmentName','clouddirectory:AddFacetToObject','clouddirectory:ApplySchema','clouddirectory:AttachObject','clouddirectory:AttachPolicy','clouddirectory:AttachToIndex','clouddirectory:AttachTypedLink','clouddirectory:BatchRead','clouddirectory:BatchWrite','clouddirectory:CreateDirectory','clouddirectory:CreateFacet','clouddirectory:CreateIndex','clouddirectory:CreateObject','clouddirectory:CreateSchema','clouddirectory:CreateTypedLinkFacet','clouddirectory:DeleteDirectory','clouddirectory:DeleteFacet','clouddirectory:DeleteObject','clouddirectory:DeleteSchema','clouddirectory:DeleteTypedLinkFacet','clouddirectory:DetachFromIndex','clouddirectory:DetachObject','clouddirectory:DetachPolicy','clouddirectory:DetachTypedLink','clouddirectory:DisableDirectory','clouddirectory:EnableDirectory','clouddirectory:GetDirectory','clouddirectory:GetFacet','clouddirectory:GetObjectInformation','clouddirectory:GetSchemaAsJson','clouddirectory:GetTypedLinkFacetInformation','clouddirectory:ListAppliedSchemaArns','clouddirectory:ListAttachedIndices','clouddirectory:ListDevelopmentSchemaArns','clouddirectory:ListDirectories','clouddirectory:ListFacetAttributes','clouddirectory:ListFacetNames','clouddirectory:ListIncomingTypedLinks','clouddirectory:ListIndex','clouddirectory:ListObjectAttributes','clouddirectory:ListObjectChildren','clouddirectory:ListObjectParentPaths','clouddirectory:ListObjectParents','clouddirectory:ListObjectPolicies','clouddirectory:ListOutgoingTypedLinks','clouddirectory:ListPolicyAttachments','clouddirectory:ListPublishedSchemaArns','clouddirectory:ListTagsForResource','clouddirectory:ListTypedLinkFacetAttributes','clouddirectory:ListTypedLinkFacetNames','clouddirectory:LookupPolicy','clouddirectory:PublishSchema','clouddirectory:PutSchemaFromJson','clouddirectory:RemoveFacetFromObject','clouddirectory:TagResource','clouddirectory:UntagResource','clouddirectory:UpdateFacet','clouddirectory:UpdateObjectAttributes','clouddirectory:UpdateSchema','clouddirectory:UpdateTypedLinkFacet','cloudformation:CancelUpdateStack','cloudformation:ContinueUpdateRollback','cloudformation:CreateChangeSet','cloudformation:CreateStack','cloudformation:CreateUploadBucket','cloudformation:DeleteChangeSet','cloudformation:DeleteStack','cloudformation:DescribeAccountLimits','cloudformation:DescribeChangeSet','cloudformation:DescribeStackEvents','cloudformation:DescribeStackResource','cloudformation:DescribeStackResources','cloudformation:DescribeStacks','cloudformation:EstimateTemplateCost','cloudformation:ExecuteChangeSet','cloudformation:GetStackPolicy','cloudformation:GetTemplate','cloudformation:GetTemplateSummary','cloudformation:ListChangeSets','cloudformation:ListExports','cloudformation:ListImports','cloudformation:ListStackResources','cloudformation:ListStacks','cloudformation:PreviewStackUpdate','cloudformation:SetStackPolicy','cloudformation:SignalResource','cloudformation:UpdateStack','cloudformation:UpdateTerminationProtection','cloudformation:ValidateTemplate','cloudfront:CreateCloudFrontOriginAccessIdentity','cloudfront:CreateDistribution','cloudfront:CreateDistributionWithTags','cloudfront:CreateInvalidation','cloudfront:CreateStreamingDistribution','cloudfront:CreateStreamingDistributionWithTags','cloudfront:DeleteCloudFrontOriginAccessIdentity','cloudfront:DeleteDistribution','cloudfront:DeleteStreamingDistribution','cloudfront:GetCloudFrontOriginAccessIdentity','cloudfront:GetCloudFrontOriginAccessIdentityConfig','cloudfront:GetDistribution','cloudfront:GetDistributionConfig','cloudfront:GetInvalidation','cloudfront:GetStreamingDistribution','cloudfront:GetStreamingDistributionConfig','cloudfront:ListCloudFrontOriginAccessIdentities','cloudfront:ListDistributions','cloudfront:ListDistributionsByWebACLId','cloudfront:ListInvalidations','cloudfront:ListStreamingDistributions','cloudfront:ListTagsForResource','cloudfront:TagResource','cloudfront:UntagResource','cloudfront:UpdateCloudFrontOriginAccessIdentity','cloudfront:UpdateDistribution','cloudfront:UpdateStreamingDistribution','cloudhsm:AddTagsToResource','cloudhsm:CreateHapg','cloudhsm:CreateHsm','cloudhsm:CreateLunaClient','cloudhsm:DeleteHapg','cloudhsm:DeleteHsm','cloudhsm:DeleteLunaClient','cloudhsm:DescribeHapg','cloudhsm:DescribeHsm','cloudhsm:DescribeLunaClient','cloudhsm:GetConfig','cloudhsm:ListAvailableZones','cloudhsm:ListHapgs','cloudhsm:ListHsms','cloudhsm:ListLunaClients','cloudhsm:ListTagsForResource','cloudhsm:ModifyHapg','cloudhsm:ModifyHsm','cloudhsm:ModifyLunaClient','cloudhsm:RemoveTagsFromResource','cloudsearch:AddTags','cloudsearch:BuildSuggesters','cloudsearch:CreateDomain','cloudsearch:DefineAnalysisScheme','cloudsearch:DefineExpression','cloudsearch:DefineIndexField','cloudsearch:DefineSuggester','cloudsearch:DeleteAnalysisScheme','cloudsearch:DeleteDomain','cloudsearch:DeleteExpression','cloudsearch:DeleteIndexField','cloudsearch:DeleteSuggester','cloudsearch:DescribeAnalysisSchemes','cloudsearch:DescribeAvailabilityOptions','cloudsearch:DescribeDomains','cloudsearch:DescribeExpressions','cloudsearch:DescribeIndexFields','cloudsearch:DescribeScalingParameters','cloudsearch:DescribeServiceAccessPolicies','cloudsearch:DescribeSuggesters','cloudsearch:document','cloudsearch:IndexDocuments','cloudsearch:ListDomainNames','cloudsearch:ListTags','cloudsearch:RemoveTags','cloudsearch:search','cloudsearch:suggest','cloudsearch:UpdateAvailabilityOptions','cloudsearch:UpdateScalingParameters','cloudsearch:UpdateServiceAccessPolicies','cloudtrail:AddTags','cloudtrail:CreateTrail','cloudtrail:DeleteTrail','cloudtrail:DescribeTrails','cloudtrail:GetEventSelectors','cloudtrail:GetTrailStatus','cloudtrail:ListPublicKeys','cloudtrail:ListTags','cloudtrail:LookupEvents','cloudtrail:PutEventSelectors','cloudtrail:RemoveTags','cloudtrail:StartLogging','cloudtrail:StopLogging','cloudtrail:UpdateTrail','cloudwatch:DeleteAlarms','cloudwatch:DeleteDashboards','cloudwatch:DescribeAlarmHistory','cloudwatch:DescribeAlarms','cloudwatch:DescribeAlarmsForMetric','cloudwatch:DisableAlarmActions','cloudwatch:EnableAlarmActions','cloudwatch:GetDashboard','cloudwatch:GetMetricData','cloudwatch:GetMetricStatistics','cloudwatch:ListDashboards','cloudwatch:ListMetrics','cloudwatch:PutDashboard','cloudwatch:PutMetricAlarm','cloudwatch:PutMetricData','cloudwatch:SetAlarmState','codebuild:BatchDeleteBuilds','codebuild:BatchGetBuilds','codebuild:BatchGetProjects','codebuild:CreateProject','codebuild:DeleteProject','codebuild:ListBuilds','codebuild:ListBuildsForProject','codebuild:ListConnectedOAuthAccounts','codebuild:ListCuratedEnvironmentImages','codebuild:ListProjects','codebuild:ListRepositories','codebuild:PersistOAuthToken','codebuild:StartBuild','codebuild:StopBuild','codebuild:UpdateProject','codecommit:BatchGetPullRequests','codecommit:BatchGetRepositories','codecommit:CancelUploadArchive','codecommit:CreateBranch','codecommit:CreatePullRequest','codecommit:CreateRepository','codecommit:DeleteBranch','codecommit:DeleteCommentContent','codecommit:DeleteRepository','codecommit:DescribePullRequestEvents','codecommit:GetBlob','codecommit:GetBranch','codecommit:GetComment','codecommit:GetCommentsForComparedCommit','codecommit:GetCommentsForPullRequest','codecommit:GetCommit','codecommit:GetCommitHistory','codecommit:GetCommitsFromMergeBase','codecommit:GetDifferences','codecommit:GetMergeConflicts','codecommit:GetObjectIdentifier','codecommit:GetPullRequest','codecommit:GetReferences','codecommit:GetRepository','codecommit:GetRepositoryTriggers','codecommit:GetTree','codecommit:GetUploadArchiveStatus','codecommit:GitPull','codecommit:GitPush','codecommit:ListBranches','codecommit:ListPullRequests','codecommit:ListRepositories','codecommit:MergePullRequestByFastForward','codecommit:PostCommentForComparedCommit','codecommit:PostCommentForPullRequest','codecommit:PostCommentReply','codecommit:PutFile','codecommit:PutRepositoryTriggers','codecommit:TestRepositoryTriggers','codecommit:UpdateComment','codecommit:UpdateDefaultBranch','codecommit:UpdatePullRequestDescription','codecommit:UpdatePullRequestStatus','codecommit:UpdatePullRequestTitle','codecommit:UpdateRepositoryDescription','codecommit:UpdateRepositoryName','codecommit:UploadArchive','codedeploy:AddTagsToOnPremisesInstances','codedeploy:BatchGetApplicationRevisions','codedeploy:BatchGetApplications','codedeploy:BatchGetDeploymentGroups','codedeploy:BatchGetDeploymentInstances','codedeploy:BatchGetDeployments','codedeploy:BatchGetOnPremisesInstances','codedeploy:ContinueDeployment','codedeploy:CreateApplication','codedeploy:CreateDeployment','codedeploy:CreateDeploymentConfig','codedeploy:CreateDeploymentGroup','codedeploy:DeleteApplication','codedeploy:DeleteDeploymentConfig','codedeploy:DeleteDeploymentGroup','codedeploy:DeregisterOnPremisesInstance','codedeploy:GetApplication','codedeploy:GetApplicationRevision','codedeploy:GetDeployment','codedeploy:GetDeploymentConfig','codedeploy:GetDeploymentGroup','codedeploy:GetDeploymentInstance','codedeploy:GetOnPremisesInstance','codedeploy:ListApplicationRevisions','codedeploy:ListApplications','codedeploy:ListDeploymentConfigs','codedeploy:ListDeploymentGroups','codedeploy:ListDeploymentInstances','codedeploy:ListDeployments','codedeploy:ListOnPremisesInstances','codedeploy:RegisterApplicationRevision','codedeploy:RegisterOnPremisesInstance','codedeploy:RemoveTagsFromOnPremisesInstances','codedeploy:StopDeployment','codedeploy:UpdateApplication','codedeploy:UpdateDeploymentGroup','codepipeline:AcknowledgeJob','codepipeline:AcknowledgeThirdPartyJob','codepipeline:CreateCustomActionType','codepipeline:CreatePipeline','codepipeline:DeleteCustomActionType','codepipeline:DeletePipeline','codepipeline:DisableStageTransition','codepipeline:EnableStageTransition','codepipeline:GetJobDetails','codepipeline:GetPipeline','codepipeline:GetPipelineExecution','codepipeline:GetPipelineState','codepipeline:GetThirdPartyJobDetails','codepipeline:ListActionTypes','codepipeline:ListPipelineExecutions','codepipeline:ListPipelines','codepipeline:PollForJobs','codepipeline:PollForThirdPartyJobs','codepipeline:PutActionRevision','codepipeline:PutApprovalResult','codepipeline:PutJobFailureResult','codepipeline:PutJobSuccessResult','codepipeline:PutThirdPartyJobFailureResult','codepipeline:PutThirdPartyJobSuccessResult','codepipeline:RetryStageExecution','codepipeline:StartPipelineExecution','codepipeline:UpdatePipeline','codestar:AssociateTeamMember','codestar:CreateProject','codestar:CreateUserProfile','codestar:DeleteExtendedAccess','codestar:DeleteProject','codestar:DeleteUserProfile','codestar:DescribeProject','codestar:DescribeUserProfile','codestar:DisassociateTeamMember','codestar:GetExtendedAccess','codestar:ListProjects','codestar:ListResources','codestar:ListTeamMembers','codestar:ListUserProfiles','codestar:PutExtendedAccess','codestar:UpdateProject','codestar:UpdateTeamMember','codestar:UpdateUserProfile','codestar:VerifyServiceRole','cognito-identity:CreateIdentityPool','cognito-identity:DeleteIdentities','cognito-identity:DeleteIdentityPool','cognito-identity:DescribeIdentity','cognito-identity:DescribeIdentityPool','cognito-identity:GetCredentialsForIdentity','cognito-identity:GetId','cognito-identity:GetIdentityPoolRoles','cognito-identity:GetOpenIdToken','cognito-identity:GetOpenIdTokenForDeveloperIdentity','cognito-identity:ListIdentities','cognito-identity:ListIdentityPools','cognito-identity:LookupDeveloperIdentity','cognito-identity:MergeDeveloperIdentities','cognito-identity:SetIdentityPoolRoles','cognito-identity:UnlinkDeveloperIdentity','cognito-identity:UnlinkIdentity','cognito-identity:UpdateIdentityPool','cognito-idp:AddCustomAttributes','cognito-idp:AdminAddUserToGroup','cognito-idp:AdminConfirmSignUp','cognito-idp:AdminCreateUser','cognito-idp:AdminDeleteUser','cognito-idp:AdminDeleteUserAttributes','cognito-idp:AdminDisableUser','cognito-idp:AdminEnableUser','cognito-idp:AdminForgetDevice','cognito-idp:AdminGetDevice','cognito-idp:AdminGetUser','cognito-idp:AdminInitiateAuth','cognito-idp:AdminListDevices','cognito-idp:AdminListGroupsForUser','cognito-idp:AdminListUserAuthEvents','cognito-idp:AdminRemoveUserFromGroup','cognito-idp:AdminResetUserPassword','cognito-idp:AdminRespondToAuthChallenge','cognito-idp:AdminSetUserMFAPreference','cognito-idp:AdminSetUserSettings','cognito-idp:AdminUpdateAuthEventFeedback','cognito-idp:AdminUpdateDeviceStatus','cognito-idp:AdminUpdateUserAttributes','cognito-idp:AdminUserGlobalSignOut','cognito-idp:ChangePassword','cognito-idp:ConfirmDevice','cognito-idp:ConfirmForgotPassword','cognito-idp:ConfirmSignUp','cognito-idp:CreateGroup','cognito-idp:CreateUserImportJob','cognito-idp:CreateUserPool','cognito-idp:CreateUserPoolClient','cognito-idp:DeleteGroup','cognito-idp:DeleteUser','cognito-idp:DeleteUserAttributes','cognito-idp:DeleteUserPool','cognito-idp:DeleteUserPoolClient','cognito-idp:DescribeRiskConfiguration','cognito-idp:DescribeUserImportJob','cognito-idp:DescribeUserPool','cognito-idp:DescribeUserPoolClient','cognito-idp:ForgetDevice','cognito-idp:ForgotPassword','cognito-idp:GetCSVHeader','cognito-idp:GetDevice','cognito-idp:GetGroup','cognito-idp:GetUser','cognito-idp:GetUserAttributeVerificationCode','cognito-idp:GetUserPoolMfaConfig','cognito-idp:GlobalSignOut','cognito-idp:InitiateAuth','cognito-idp:ListDevices','cognito-idp:ListGroups','cognito-idp:ListUserImportJobs','cognito-idp:ListUserPoolClients','cognito-idp:ListUsersInGroup','cognito-idp:ResendConfirmationCode','cognito-idp:RespondToAuthChallenge','cognito-idp:SetRiskConfiguration','cognito-idp:SetUserMFAPreference','cognito-idp:SetUserPoolMfaConfig','cognito-idp:SetUserSettings','cognito-idp:SignUp','cognito-idp:StartUserImportJob','cognito-idp:StopUserImportJob','cognito-idp:UpdateAuthEventFeedback','cognito-idp:UpdateDeviceStatus','cognito-idp:UpdateGroup','cognito-idp:UpdateUserAttributes','cognito-idp:UpdateUserPool','cognito-idp:UpdateUserPoolClient','cognito-idp:VerifyUserAttribute','cognito-sync:BulkPublish','cognito-sync:DeleteDataset','cognito-sync:DescribeDataset','cognito-sync:DescribeIdentityPoolUsage','cognito-sync:DescribeIdentityUsage','cognito-sync:GetBulkPublishDetails','cognito-sync:GetCognitoEvents','cognito-sync:GetIdentityPoolConfiguration','cognito-sync:ListDatasets','cognito-sync:ListIdentityPoolUsage','cognito-sync:ListRecords','cognito-sync:QueryRecords','cognito-sync:RegisterDevice','cognito-sync:SetCognitoEvents','cognito-sync:SetDatasetConfiguration','cognito-sync:SetIdentityPoolConfiguration','cognito-sync:SubscribeToDataset','cognito-sync:UnsubscribeFromDataset','cognito-sync:UpdateRecords','comprehend:BatchDetectDominantLanguage','comprehend:BatchDetectEntities','comprehend:BatchDetectKeyPhrases','comprehend:BatchDetectSentiment','comprehend:DescribeTopicsDetectionJob','comprehend:DetectDominantLanguage','comprehend:DetectEntities','comprehend:DetectKeyPhrases','comprehend:DetectSentiment','comprehend:ListTopicsDetectionJobs','comprehend:StartTopicsDetectionJob','config:DeleteConfigRule','config:DeleteConfigurationRecorder','config:DeleteDeliveryChannel','config:DeleteEvaluationResults','config:DeliverConfigSnapshot','config:DescribeComplianceByConfigRule','config:DescribeComplianceByResource','config:DescribeConfigRuleEvaluationStatus','config:DescribeConfigRules','config:DescribeConfigurationRecorders','config:DescribeConfigurationRecorderStatus','config:DescribeDeliveryChannels','config:DescribeDeliveryChannelStatus','config:GetComplianceDetailsByConfigRule','config:GetComplianceDetailsByResource','config:GetComplianceSummaryByConfigRule','config:GetComplianceSummaryByResourceType','config:GetResourceConfigHistory','config:GetResources','config:GetTagKeys','config:ListDiscoveredResources','config:PutConfigRule','config:PutConfigurationRecorder','config:PutDeliveryChannel','config:PutEvaluations','config:StartConfigRulesEvaluation','config:StartConfigurationRecorder','config:StopConfigurationRecorder','connect:CreateInstance','connect:DescribeInstance','connect:DestroyInstance','connect:GetFederationToken','connect:GetFederationTokens','connect:ListInstances','connect:ModifyInstance','crowd:GetTask','crowd:PutTask','cur:DeleteReportDefinition','cur:DescribeReportDefinitions','cur:PutReportDefinition','datapipeline:ActivatePipeline','datapipeline:AddTags','datapipeline:CreatePipeline','datapipeline:DeactivatePipeline','datapipeline:DeletePipeline','datapipeline:DescribeObjects','datapipeline:DescribePipelines','datapipeline:EvaluateExpression','datapipeline:GetAccountLimits','datapipeline:GetPipelineDefinition','datapipeline:ListPipelines','datapipeline:PollForTask','datapipeline:PutAccountLimits','datapipeline:PutPipelineDefinition','datapipeline:QueryObjects','datapipeline:RemoveTags','datapipeline:ReportTaskProgress','datapipeline:ReportTaskRunnerHeartbeat','datapipeline:SetStatus','datapipeline:SetTaskStatus','datapipeline:ValidatePipelineDefinition','dax:BatchGetItem','dax:BatchWriteItem','dax:CreateCluster','dax:CreateParameterGroup','dax:CreateSubnetGroup','dax:DecreaseReplicationFactor','dax:DeleteCluster','dax:DeleteItem','dax:DeleteParameterGroup','dax:DeleteSubnetGroup','dax:DescribeClusters','dax:DescribeDefaultParameters','dax:DescribeEvents','dax:DescribeParameterGroups','dax:DescribeParameters','dax:DescribeSubnetGroups','dax:DescribeTable','dax:GetItem','dax:IncreaseReplicationFactor','dax:ListTables','dax:ListTags','dax:PutItem','dax:Query','dax:RebootNode','dax:Scan','dax:TagResource','dax:UntagResource','dax:UpdateCluster','dax:UpdateItem','dax:UpdateParameterGroup','dax:UpdateSubnetGroup','devicefarm:CreateDevicePool','devicefarm:CreateNetworkProfile','devicefarm:CreateProject','devicefarm:CreateRemoteAccessSession','devicefarm:CreateUpload','devicefarm:DeleteDevicePool','devicefarm:DeleteNetworkProfile','devicefarm:DeleteProject','devicefarm:DeleteRemoteAccessSession','devicefarm:DeleteRun','devicefarm:DeleteUpload','devicefarm:GetAccountSettings','devicefarm:GetDevice','devicefarm:GetDevicePool','devicefarm:GetDevicePoolCompatibility','devicefarm:GetJob','devicefarm:GetNetworkProfile','devicefarm:GetOfferingStatus','devicefarm:GetProject','devicefarm:GetRemoteAccessSession','devicefarm:GetRun','devicefarm:GetSuite','devicefarm:GetTest','devicefarm:GetUpload','devicefarm:InstallToRemoteAccessSession','devicefarm:ListArtifacts','devicefarm:ListDevicePools','devicefarm:ListDevices','devicefarm:ListJobs','devicefarm:ListNetworkProfiles','devicefarm:ListOfferings','devicefarm:ListOfferingTransactions','devicefarm:ListProjects','devicefarm:ListRemoteAccessSessions','devicefarm:ListRuns','devicefarm:ListSamples','devicefarm:ListSuites','devicefarm:ListTests','devicefarm:ListUniqueProblems','devicefarm:ListUploads','devicefarm:PurchaseOffering','devicefarm:RenewOffering','devicefarm:ScheduleRun','devicefarm:StopRemoteAccessSession','devicefarm:StopRun','devicefarm:UpdateDevicePool','devicefarm:UpdateNetworkProfile','devicefarm:UpdateProject','directconnect:AllocateConnectionOnInterconnect','directconnect:AllocatePrivateVirtualInterface','directconnect:AllocatePublicVirtualInterface','directconnect:ConfirmConnection','directconnect:ConfirmPrivateVirtualInterface','directconnect:ConfirmPublicVirtualInterface','directconnect:CreateConnection','directconnect:CreateInterconnect','directconnect:CreatePrivateVirtualInterface','directconnect:CreatePublicVirtualInterface','directconnect:DeleteConnection','directconnect:DeleteInterconnect','directconnect:DeleteVirtualInterface','directconnect:DescribeConnectionLoa','directconnect:DescribeConnections','directconnect:DescribeConnectionsOnInterconnect','directconnect:DescribeInterconnectLoa','directconnect:DescribeInterconnects','directconnect:DescribeLocations','directconnect:DescribeVirtualGateways','directconnect:DescribeVirtualInterfaces','discovery:AssociateConfigurationItemsToApplication','discovery:CreateApplication','discovery:CreateTags','discovery:DeleteApplications','discovery:DeleteTags','discovery:DescribeAgents','discovery:DescribeConfigurations','discovery:DescribeExportConfigurations','discovery:DescribeTags','discovery:DisassociateConfigurationItemsFromApplication','discovery:ExportConfigurations','discovery:GetDiscoverySummary','discovery:ListConfigurations','discovery:ListServerNeighbors','discovery:StartDataCollectionByAgentIds','discovery:StartExportTask','discovery:StopDataCollectionByAgentIds','discovery:UpdateApplication','dms:AddTagsToResource','dms:CreateEndpoint','dms:CreateReplicationInstance','dms:CreateReplicationSubnetGroup','dms:CreateReplicationTask','dms:DeleteEndpoint','dms:DeleteEventSubscription','dms:DeleteReplicationInstance','dms:DeleteReplicationSubnetGroup','dms:DeleteReplicationTask','dms:DescribeAccountAttributes','dms:DescribeCertificates','dms:DescribeConnections','dms:DescribeEndpoints','dms:DescribeEndpointTypes','dms:DescribeEventCategories','dms:DescribeEvents','dms:DescribeEventSubscriptions','dms:DescribeOrderableReplicationInstances','dms:DescribeRefreshSchemasStatus','dms:DescribeReplicationInstances','dms:DescribeReplicationSubnetGroups','dms:DescribeReplicationTasks','dms:DescribeSchemas','dms:DescribeTableStatistics','dms:ListTagsForResource','dms:ModifyEndpoint','dms:ModifyEventSubscription','dms:ModifyReplicationInstance','dms:ModifyReplicationSubnetGroup','dms:ModifyReplicationTask','dms:RefreshSchemas','dms:RemoveTagsFromResource','dms:StartReplicationTask','dms:StopReplicationTask','dms:TestConnection','ds:AddIpRoutes','ds:AddTagsToResource','ds:AuthorizeApplication','ds:CancelSchemaExtension','ds:ConnectDirectory','ds:CreateAlias','ds:CreateComputer','ds:CreateConditionalForwarder','ds:CreateDirectory','ds:CreateMicrosoftAD','ds:CreateSnapshot','ds:CreateTrust','ds:DeleteConditionalForwarder','ds:DeleteDirectory','ds:DeleteSnapshot','ds:DeleteTrust','ds:DeregisterEventTopic','ds:DescribeConditionalForwarders','ds:DescribeDirectories','ds:DescribeEventTopics','ds:DescribeSnapshots','ds:DescribeTrusts','ds:DisableRadius','ds:DisableSso','ds:EnableRadius','ds:EnableSso','ds:GetDirectoryLimits','ds:GetSnapshotLimits','ds:ListAuthorizedApplications','ds:ListIpRoutes','ds:ListSchemaExtensions','ds:ListTagsForResource','ds:RegisterEventTopic','ds:RemoveIpRoutes','ds:RemoveTagsFromResource','ds:RestoreFromSnapshot','ds:StartSchemaExtension','ds:UnauthorizeApplication','ds:UpdateConditionalForwarder','ds:UpdateRadius','ds:VerifyTrust','dynamodb:BatchGetItem','dynamodb:BatchWriteItem','dynamodb:CreateBackup','dynamodb:CreateTable','dynamodb:DeleteBackup','dynamodb:DeleteItem','dynamodb:DeleteTable','dynamodb:DescribeBackup','dynamodb:DescribeContinuousBackups','dynamodb:DescribeLimits','dynamodb:DescribeReservedCapacity','dynamodb:DescribeReservedCapacityOfferings','dynamodb:DescribeStream','dynamodb:DescribeTable','dynamodb:DescribeTimeToLive','dynamodb:GetItem','dynamodb:GetRecords','dynamodb:GetShardIterator','dynamodb:ListBackups','dynamodb:ListStreams','dynamodb:ListTables','dynamodb:ListTagsOfResource','dynamodb:PurchaseReservedCapacityOfferings','dynamodb:PutItem','dynamodb:Query','dynamodb:RestoreTableFromBackup','dynamodb:RestoreTableToPointInTime','dynamodb:Scan','dynamodb:TagResource','dynamodb:UntagResource','dynamodb:UpdateContinuousBackups','dynamodb:UpdateItem','dynamodb:UpdateTable','dynamodb:UpdateTimeToLive','ec2:AcceptReservedInstancesExchangeQuote','ec2:AcceptVpcEndpointConnections','ec2:AcceptVpcPeeringConnection','ec2:AllocateAddress','ec2:AllocateHosts','ec2:AssignIpv6Addresses','ec2:AssignPrivateIpAddresses','ec2:AssociateAddress','ec2:AssociateDhcpOptions','ec2:AssociateIamInstanceProfile','ec2:AssociateRouteTable','ec2:AssociateSubnetCidrBlock','ec2:AssociateVpcCidrBlock','ec2:AttachClassicLinkVpc','ec2:AttachInternetGateway','ec2:AttachNetworkInterface','ec2:AttachVolume','ec2:AttachVpnGateway','ec2:AuthorizeSecurityGroupEgress','ec2:AuthorizeSecurityGroupIngress','ec2:BundleInstance','ec2:CancelBundleTask','ec2:CancelConversionTask','ec2:CancelExportTask','ec2:CancelImportTask','ec2:CancelReservedInstancesListing','ec2:CancelSpotFleetRequests','ec2:CancelSpotInstanceRequests','ec2:ConfirmProductInstance','ec2:CopyFpgaImage','ec2:CopyImage','ec2:CopySnapshot','ec2:CreateCustomerGateway','ec2:CreateDefaultSubnet','ec2:CreateDefaultVpc','ec2:CreateDhcpOptions','ec2:CreateEgressOnlyInternetGateway','ec2:CreateFlowLogs','ec2:CreateFpgaImage','ec2:CreateImage','ec2:CreateInstanceExportTask','ec2:CreateInternetGateway','ec2:CreateKeyPair','ec2:CreateLaunchTemplate','ec2:CreateLaunchTemplateVersion','ec2:CreateNatGateway','ec2:CreateNetworkAcl','ec2:CreateNetworkAclEntry','ec2:CreateNetworkInterface','ec2:CreateNetworkInterfacePermission','ec2:CreatePlacementGroup','ec2:CreateReservedInstancesListing','ec2:CreateRoute','ec2:CreateRouteTable','ec2:CreateSecurityGroup','ec2:CreateSnapshot','ec2:CreateSpotDatafeedSubscription','ec2:CreateSubnet','ec2:CreateTags','ec2:CreateVolume','ec2:CreateVpc','ec2:CreateVpcEndpoint','ec2:CreateVpcEndpointConnectionNotification','ec2:CreateVpcEndpointServiceConfiguration','ec2:CreateVpcPeeringConnection','ec2:CreateVpnConnection','ec2:CreateVpnConnectionRoute','ec2:CreateVpnGateway','ec2:DeleteCustomerGateway','ec2:DeleteDhcpOptions','ec2:DeleteEgressOnlyInternetGateway','ec2:DeleteFlowLogs','ec2:DeleteFpgaImage','ec2:DeleteInternetGateway','ec2:DeleteKeyPair','ec2:DeleteLaunchTemplate','ec2:DeleteLaunchTemplateVersions','ec2:DeleteNatGateway','ec2:DeleteNetworkAcl','ec2:DeleteNetworkAclEntry','ec2:DeleteNetworkInterface','ec2:DeleteNetworkInterfacePermission','ec2:DeletePlacementGroup','ec2:DeleteRoute','ec2:DeleteRouteTable','ec2:DeleteSecurityGroup','ec2:DeleteSnapshot','ec2:DeleteSpotDatafeedSubscription','ec2:DeleteSubnet','ec2:DeleteTags','ec2:DeleteVolume','ec2:DeleteVpc','ec2:DeleteVpcEndpointConnectionNotifications','ec2:DeleteVpcEndpoints','ec2:DeleteVpcEndpointServiceConfigurations','ec2:DeleteVpcPeeringConnection','ec2:DeleteVpnConnection','ec2:DeleteVpnConnectionRoute','ec2:DeleteVpnGateway','ec2:DeregisterImage','ec2:DescribeAccountAttributes','ec2:DescribeAddresses','ec2:DescribeAvailabilityZones','ec2:DescribeBundleTasks','ec2:DescribeClassicLinkInstances','ec2:DescribeConversionTasks','ec2:DescribeCustomerGateways','ec2:DescribeDhcpOptions','ec2:DescribeEgressOnlyInternetGateways','ec2:DescribeElasticGpus','ec2:DescribeExportTasks','ec2:DescribeFlowLogs','ec2:DescribeFpgaImageAttribute','ec2:DescribeFpgaImages','ec2:DescribeHostReservationOfferings','ec2:DescribeHostReservations','ec2:DescribeHosts','ec2:DescribeIamInstanceProfileAssociations','ec2:DescribeIdentityIdFormat','ec2:DescribeIdFormat','ec2:DescribeImageAttribute','ec2:DescribeImages','ec2:DescribeImportImageTasks','ec2:DescribeImportSnapshotTasks','ec2:DescribeInstanceAttribute','ec2:DescribeInstanceCreditSpecifications','ec2:DescribeInstances','ec2:DescribeInstanceStatus','ec2:DescribeInternetGateways','ec2:DescribeKeyPairs','ec2:DescribeLaunchTemplates','ec2:DescribeLaunchTemplateVersions','ec2:DescribeMovingAddresses','ec2:DescribeNatGateways','ec2:DescribeNetworkAcls','ec2:DescribeNetworkInterfaceAttribute','ec2:DescribeNetworkInterfacePermissions','ec2:DescribeNetworkInterfaces','ec2:DescribePlacementGroups','ec2:DescribePrefixLists','ec2:DescribeRegions','ec2:DescribeReservedInstances','ec2:DescribeReservedInstancesListings','ec2:DescribeReservedInstancesModifications','ec2:DescribeReservedInstancesOfferings','ec2:DescribeRouteTables','ec2:DescribeScheduledInstanceAvailability','ec2:DescribeScheduledInstances','ec2:DescribeSecurityGroupReferences','ec2:DescribeSecurityGroups','ec2:DescribeSnapshotAttribute','ec2:DescribeSnapshots','ec2:DescribeSpotDatafeedSubscription','ec2:DescribeSpotFleetInstances','ec2:DescribeSpotFleetRequestHistory','ec2:DescribeSpotFleetRequests','ec2:DescribeSpotInstanceRequests','ec2:DescribeSpotPriceHistory','ec2:DescribeStaleSecurityGroups','ec2:DescribeSubnets','ec2:DescribeTags','ec2:DescribeVolumeAttribute','ec2:DescribeVolumes','ec2:DescribeVolumesModifications','ec2:DescribeVolumeStatus','ec2:DescribeVpcAttribute','ec2:DescribeVpcClassicLink','ec2:DescribeVpcClassicLinkDnsSupport','ec2:DescribeVpcEndpointConnectionNotifications','ec2:DescribeVpcEndpointConnections','ec2:DescribeVpcEndpoints','ec2:DescribeVpcEndpointServiceConfigurations','ec2:DescribeVpcEndpointServicePermissions','ec2:DescribeVpcEndpointServices','ec2:DescribeVpcPeeringConnections','ec2:DescribeVpcs','ec2:DescribeVpnConnections','ec2:DescribeVpnGateways','ec2:DetachClassicLinkVpc','ec2:DetachInternetGateway','ec2:DetachNetworkInterface','ec2:DetachVolume','ec2:DetachVpnGateway','ec2:DisableVgwRoutePropagation','ec2:DisableVpcClassicLink','ec2:DisableVpcClassicLinkDnsSupport','ec2:DisassociateAddress','ec2:DisassociateIamInstanceProfile','ec2:DisassociateRouteTable','ec2:DisassociateSubnetCidrBlock','ec2:DisassociateVpcCidrBlock','ec2:EnableVgwRoutePropagation','ec2:EnableVolumeIO','ec2:EnableVpcClassicLink','ec2:EnableVpcClassicLinkDnsSupport','ec2:GetConsoleOutput','ec2:GetConsoleScreenshot','ec2:GetHostReservationPurchasePreview','ec2:GetLaunchTemplateData','ec2:GetPasswordData','ec2:GetReservedInstancesExchangeQuote','ec2:ImportImage','ec2:ImportInstance','ec2:ImportKeyPair','ec2:ImportSnapshot','ec2:ImportVolume','ec2:ModifyFpgaImageAttribute','ec2:ModifyHosts','ec2:ModifyIdentityIdFormat','ec2:ModifyIdFormat','ec2:ModifyImageAttribute','ec2:ModifyInstanceAttribute','ec2:ModifyInstanceCreditSpecification','ec2:ModifyInstancePlacement','ec2:ModifyLaunchTemplate','ec2:ModifyNetworkInterfaceAttribute','ec2:ModifyReservedInstances','ec2:ModifySnapshotAttribute','ec2:ModifySpotFleetRequest','ec2:ModifySubnetAttribute','ec2:ModifyVolume','ec2:ModifyVolumeAttribute','ec2:ModifyVpcAttribute','ec2:ModifyVpcEndpoint','ec2:ModifyVpcEndpointConnectionNotification','ec2:ModifyVpcEndpointServiceConfiguration','ec2:ModifyVpcEndpointServicePermissions','ec2:ModifyVpcPeeringConnectionOptions','ec2:ModifyVpcTenancy','ec2:MonitorInstances','ec2:MoveAddressToVpc','ec2:PurchaseHostReservation','ec2:PurchaseReservedInstancesOffering','ec2:PurchaseScheduledInstances','ec2:RebootInstances','ec2:RegisterImage','ec2:RejectVpcEndpointConnections','ec2:RejectVpcPeeringConnection','ec2:ReleaseAddress','ec2:ReleaseHosts','ec2:ReplaceIamInstanceProfileAssociation','ec2:ReplaceNetworkAclAssociation','ec2:ReplaceNetworkAclEntry','ec2:ReplaceRoute','ec2:ReplaceRouteTableAssociation','ec2:ReportInstanceStatus','ec2:RequestSpotFleet','ec2:RequestSpotInstances','ec2:ResetFpgaImageAttribute','ec2:ResetImageAttribute','ec2:ResetInstanceAttribute','ec2:ResetNetworkInterfaceAttribute','ec2:ResetSnapshotAttribute','ec2:RestoreAddressToClassic','ec2:RevokeSecurityGroupEgress','ec2:RevokeSecurityGroupIngress','ec2:RunInstances','ec2:RunScheduledInstances','ec2:StartInstances','ec2:StopInstances','ec2:TerminateInstances','ec2:UnassignIpv6Addresses','ec2:UnassignPrivateIpAddresses','ec2:UnmonitorInstances','ec2:UpdateSecurityGroupRuleDescriptionsEgress','ec2:UpdateSecurityGroupRuleDescriptionsIngress','ec2messages:AcknowledgeMessage','ec2messages:DeleteMessage','ec2messages:FailMessage','ec2messages:GetEndpoint','ec2messages:GetMessages','ec2messages:SendReply','ecr:BatchCheckLayerAvailability','ecr:BatchDeleteImage','ecr:BatchGetImage','ecr:CompleteLayerUpload','ecr:CreateRepository','ecr:DeleteRepository','ecr:DeleteRepositoryPolicy','ecr:DescribeImages','ecr:DescribeRepositories','ecr:GetAuthorizationToken','ecr:GetDownloadUrlForLayer','ecr:GetRepositoryPolicy','ecr:InitiateLayerUpload','ecr:ListImages','ecr:PutImage','ecr:SetRepositoryPolicy','ecr:UploadLayerPart','ecs:CreateCluster','ecs:CreateService','ecs:DeleteCluster','ecs:DeleteService','ecs:DeregisterContainerInstance','ecs:DeregisterTaskDefinition','ecs:DescribeClusters','ecs:DescribeContainerInstances','ecs:DescribeServices','ecs:DescribeTaskDefinition','ecs:DescribeTasks','ecs:DiscoverPollEndpoint','ecs:ListClusters','ecs:ListContainerInstances','ecs:ListServices','ecs:ListTaskDefinitionFamilies','ecs:ListTaskDefinitions','ecs:ListTasks','ecs:Poll','ecs:RegisterContainerInstance','ecs:RegisterTaskDefinition','ecs:RunTask','ecs:StartTask','ecs:StartTelemetrySession','ecs:StopTask','ecs:SubmitContainerStateChange','ecs:SubmitTaskStateChange','ecs:UpdateContainerAgent','ecs:UpdateContainerInstancesState','ecs:UpdateService','elasticache:AddTagsToResource','elasticache:AuthorizeCacheSecurityGroupIngress','elasticache:CopySnapshot','elasticache:CreateCacheCluster','elasticache:CreateCacheParameterGroup','elasticache:CreateCacheSecurityGroup','elasticache:CreateCacheSubnetGroup','elasticache:CreateReplicationGroup','elasticache:CreateSnapshot','elasticache:DeleteCacheCluster','elasticache:DeleteCacheParameterGroup','elasticache:DeleteCacheSecurityGroup','elasticache:DeleteCacheSubnetGroup','elasticache:DeleteReplicationGroup','elasticache:DeleteSnapshot','elasticache:DescribeCacheClusters','elasticache:DescribeCacheEngineVersions','elasticache:DescribeCacheParameterGroups','elasticache:DescribeCacheParameters','elasticache:DescribeCacheSecurityGroups','elasticache:DescribeCacheSubnetGroups','elasticache:DescribeEngineDefaultParameters','elasticache:DescribeEvents','elasticache:DescribeReplicationGroups','elasticache:DescribeReservedCacheNodes','elasticache:DescribeReservedCacheNodesOfferings','elasticache:DescribeSnapshots','elasticache:ListAllowedNodeTypeModifications','elasticache:ListTagsForResource','elasticache:ModifyCacheCluster','elasticache:ModifyCacheParameterGroup','elasticache:ModifyCacheSubnetGroup','elasticache:ModifyReplicationGroup','elasticache:PurchaseReservedCacheNodesOffering','elasticache:RebootCacheCluster','elasticache:RemoveTagsFromResource','elasticache:ResetCacheParameterGroup','elasticache:RevokeCacheSecurityGroupIngress','elasticbeanstalk:AbortEnvironmentUpdate','elasticbeanstalk:ApplyEnvironmentManagedAction','elasticbeanstalk:CheckDNSAvailability','elasticbeanstalk:ComposeEnvironments','elasticbeanstalk:CreateApplication','elasticbeanstalk:CreateApplicationVersion','elasticbeanstalk:CreateConfigurationTemplate','elasticbeanstalk:CreateEnvironment','elasticbeanstalk:CreatePlatformVersion','elasticbeanstalk:CreateStorageLocation','elasticbeanstalk:DeleteApplication','elasticbeanstalk:DeleteApplicationVersion','elasticbeanstalk:DeleteConfigurationTemplate','elasticbeanstalk:DeleteEnvironmentConfiguration','elasticbeanstalk:DeletePlatformVersion','elasticbeanstalk:DescribeApplications','elasticbeanstalk:DescribeApplicationVersions','elasticbeanstalk:DescribeConfigurationOptions','elasticbeanstalk:DescribeConfigurationSettings','elasticbeanstalk:DescribeEnvironmentHealth','elasticbeanstalk:DescribeEnvironmentManagedActionHistory','elasticbeanstalk:DescribeEnvironmentManagedActions','elasticbeanstalk:DescribeEnvironmentResources','elasticbeanstalk:DescribeEnvironments','elasticbeanstalk:DescribeEvents','elasticbeanstalk:DescribeInstancesHealth','elasticbeanstalk:DescribePlatformVersion','elasticbeanstalk:ListAvailableSolutionStacks','elasticbeanstalk:ListPlatformVersions','elasticbeanstalk:RebuildEnvironment','elasticbeanstalk:RequestEnvironmentInfo','elasticbeanstalk:RestartAppServer','elasticbeanstalk:RetrieveEnvironmentInfo','elasticbeanstalk:SwapEnvironmentCNAMEs','elasticbeanstalk:TerminateEnvironment','elasticbeanstalk:UpdateApplication','elasticbeanstalk:UpdateApplicationResourceLifecycle','elasticbeanstalk:UpdateApplicationVersion','elasticbeanstalk:UpdateConfigurationTemplate','elasticbeanstalk:UpdateEnvironment','elasticbeanstalk:ValidateConfigurationSettings','elasticfilesystem:CreateFileSystem','elasticfilesystem:CreateMountTarget','elasticfilesystem:CreateTags','elasticfilesystem:DeleteFileSystem','elasticfilesystem:DeleteMountTarget','elasticfilesystem:DeleteTags','elasticfilesystem:DescribeFileSystems','elasticfilesystem:DescribeMountTargets','elasticfilesystem:DescribeMountTargetSecurityGroups','elasticfilesystem:DescribeTags','elasticfilesystem:ModifyMountTargetSecurityGroups','elasticloadbalancing:AddTags','elasticloadbalancing:ApplySecurityGroupsToLoadBalancer','elasticloadbalancing:AttachLoadBalancerToSubnets','elasticloadbalancing:ConfigureHealthCheck','elasticloadbalancing:CreateAppCookieStickinessPolicy','elasticloadbalancing:CreateLBCookieStickinessPolicy','elasticloadbalancing:CreateListener','elasticloadbalancing:CreateLoadBalancer','elasticloadbalancing:CreateLoadBalancerListeners','elasticloadbalancing:CreateLoadBalancerPolicy','elasticloadbalancing:CreateRule','elasticloadbalancing:CreateTargetGroup','elasticloadbalancing:DeleteListener','elasticloadbalancing:DeleteLoadBalancer','elasticloadbalancing:DeleteLoadBalancerListeners','elasticloadbalancing:DeleteLoadBalancerPolicy','elasticloadbalancing:DeleteRule','elasticloadbalancing:DeleteTargetGroup','elasticloadbalancing:DeregisterInstancesFromLoadBalancer','elasticloadbalancing:DeregisterTargets','elasticloadbalancing:DescribeInstanceHealth','elasticloadbalancing:DescribeListeners','elasticloadbalancing:DescribeLoadBalancerAttributes','elasticloadbalancing:DescribeLoadBalancerPolicies','elasticloadbalancing:DescribeLoadBalancerPolicyTypes','elasticloadbalancing:DescribeLoadBalancers','elasticloadbalancing:DescribeRules','elasticloadbalancing:DescribeSSLPolicies','elasticloadbalancing:DescribeTags','elasticloadbalancing:DescribeTargetGroupAttributes','elasticloadbalancing:DescribeTargetGroups','elasticloadbalancing:DescribeTargetHealth','elasticloadbalancing:DetachLoadBalancerFromSubnets','elasticloadbalancing:DisableAvailabilityZonesForLoadBalancer','elasticloadbalancing:EnableAvailabilityZonesForLoadBalancer','elasticloadbalancing:ModifyListener','elasticloadbalancing:ModifyLoadBalancerAttributes','elasticloadbalancing:ModifyRule','elasticloadbalancing:ModifyTargetGroup','elasticloadbalancing:ModifyTargetGroupAttributes','elasticloadbalancing:RegisterInstancesWithLoadBalancer','elasticloadbalancing:RegisterTargets','elasticloadbalancing:RemoveTags','elasticloadbalancing:SetIpAddressType','elasticloadbalancing:SetLoadBalancerListenerSSLCertificate','elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer','elasticloadbalancing:SetLoadBalancerPoliciesOfListener','elasticloadbalancing:SetRulePriorities','elasticloadbalancing:SetSecurityGroups','elasticloadbalancing:SetSubnets','elasticmapreduce:AddInstanceGroups','elasticmapreduce:AddJobFlowSteps','elasticmapreduce:AddTags','elasticmapreduce:CancelSteps','elasticmapreduce:CreateSecurityConfiguration','elasticmapreduce:DeleteSecurityConfiguration','elasticmapreduce:DescribeCluster','elasticmapreduce:DescribeJobFlows','elasticmapreduce:DescribeSecurityConfiguration','elasticmapreduce:DescribeStep','elasticmapreduce:ListBootstrapActions','elasticmapreduce:ListClusters','elasticmapreduce:ListInstanceGroups','elasticmapreduce:ListInstances','elasticmapreduce:ListSecurityConfigurations','elasticmapreduce:ListSteps','elasticmapreduce:ModifyInstanceGroups','elasticmapreduce:PutAutoScalingPolicy','elasticmapreduce:RemoveAutoScalingPolicy','elasticmapreduce:RemoveTags','elasticmapreduce:RunJobFlow','elasticmapreduce:SetTerminationProtection','elasticmapreduce:SetVisibleToAllUsers','elasticmapreduce:TerminateJobFlows','elasticmapreduce:ViewEventsFromAllClustersInConsole','elastictranscoder:CancelJob','elastictranscoder:CreateJob','elastictranscoder:CreatePipeline','elastictranscoder:CreatePreset','elastictranscoder:DeletePipeline','elastictranscoder:DeletePreset','elastictranscoder:ListJobsByPipeline','elastictranscoder:ListJobsByStatus','elastictranscoder:ListPipelines','elastictranscoder:ListPresets','elastictranscoder:ReadJob','elastictranscoder:ReadPipeline','elastictranscoder:ReadPreset','elastictranscoder:TestRole','elastictranscoder:UpdatePipeline','elastictranscoder:UpdatePipelineNotifications','elastictranscoder:UpdatePipelineStatus','es:AddTags','es:CreateElasticsearchDomain','es:DeleteElasticsearchDomain','es:DescribeElasticsearchDomain','es:DescribeElasticsearchDomainConfig','es:DescribeElasticsearchDomains','es:ESHttpDelete','es:ESHttpGet','es:ESHttpHead','es:ESHttpPost','es:ESHttpPut','es:ListDomainNames','es:ListTags','es:RemoveTags','es:UpdateElasticsearchDomainConfig','events:DeleteRule','events:DescribeRule','events:DisableRule','events:EnableRule','events:ListRuleNamesByTarget','events:ListRules','events:ListTargetsByRule','events:PutEvents','events:PutRule','events:PutTargets','events:RemoveTargets','events:TestEventPattern','execute-api:InvalidateCache','execute-api:Invoke','firehose:CreateDeliveryStream','firehose:DeleteDeliveryStream','firehose:DescribeDeliveryStream','firehose:ListDeliveryStreams','firehose:PutRecord','firehose:PutRecordBatch','firehose:UpdateDestination','freertos:CreateSoftwareConfiguration','freertos:DeleteSoftwareConfiguration','freertos:DescribeHardwarePlatform','freertos:DescribeSoftwareConfiguration','freertos:GetSoftwareURL','freertos:GetSoftwareURLForConfiguration','freertos:ListFreeRTOSVersions','freertos:ListHardwarePlatforms','freertos:ListHardwareVendors','freertos:ListSoftwareConfigurations','freertos:UpdateSoftwareConfiguration','gamelift:CreateAlias','gamelift:CreateBuild','gamelift:CreateFleet','gamelift:CreateGameSession','gamelift:CreatePlayerSession','gamelift:CreatePlayerSessions','gamelift:DeleteAlias','gamelift:DeleteBuild','gamelift:DeleteFleet','gamelift:DeleteScalingPolicy','gamelift:DescribeAlias','gamelift:DescribeBuild','gamelift:DescribeEC2InstanceLimits','gamelift:DescribeFleetAttributes','gamelift:DescribeFleetCapacity','gamelift:DescribeFleetEvents','gamelift:DescribeFleetPortSettings','gamelift:DescribeFleetUtilization','gamelift:DescribeGameSessionDetails','gamelift:DescribeGameSessions','gamelift:DescribeInstances','gamelift:DescribePlayerSessions','gamelift:DescribeRuntimeConfiguration','gamelift:DescribeScalingPolicies','gamelift:GetGameSessionLogUrl','gamelift:GetInstanceAccess','gamelift:ListAliases','gamelift:ListBuilds','gamelift:ListFleets','gamelift:PutScalingPolicy','gamelift:RequestUploadCredentials','gamelift:ResolveAlias','gamelift:SearchGameSessions','gamelift:UpdateAlias','gamelift:UpdateBuild','gamelift:UpdateFleetAttributes','gamelift:UpdateFleetCapacity','gamelift:UpdateFleetPortSettings','gamelift:UpdateGameSession','gamelift:UpdateRuntimeConfiguration','glacier:AbortMultipartUpload','glacier:AbortVaultLock','glacier:AddTagsToVault','glacier:CompleteMultipartUpload','glacier:CompleteVaultLock','glacier:CreateVault','glacier:DeleteArchive','glacier:DeleteVault','glacier:DeleteVaultAccessPolicy','glacier:DeleteVaultNotifications','glacier:DescribeJob','glacier:DescribeVault','glacier:GetDataRetrievalPolicy','glacier:GetJobOutput','glacier:GetVaultAccessPolicy','glacier:GetVaultLock','glacier:GetVaultNotifications','glacier:InitiateJob','glacier:InitiateMultipartUpload','glacier:InitiateVaultLock','glacier:ListJobs','glacier:ListMultipartUploads','glacier:ListParts','glacier:ListProvisionedCapacity','glacier:ListTagsForVault','glacier:ListVaults','glacier:PurchaseProvisionedCapacity','glacier:RemoveTagsFromVault','glacier:SetDataRetrievalPolicy','glacier:SetVaultAccessPolicy','glacier:SetVaultNotifications','glacier:UploadArchive','glacier:UploadMultipartPart','glue:BatchCreatePartition','glue:BatchDeleteConnection','glue:BatchDeletePartition','glue:BatchDeleteTable','glue:BatchGetPartition','glue:CreateClassifier','glue:CreateConnection','glue:CreateCrawler','glue:CreateDatabase','glue:CreateDevEndpoint','glue:CreateJob','glue:CreatePartition','glue:CreateScript','glue:CreateTable','glue:CreateTrigger','glue:CreateUserDefinedFunction','glue:DeleteClassifier','glue:DeleteConnection','glue:DeleteCrawler','glue:DeleteDatabase','glue:DeleteDevEndpoint','glue:DeleteJob','glue:DeletePartition','glue:DeleteTable','glue:DeleteTrigger','glue:DeleteUserDefinedFunction','glue:GetCatalogImportStatus','glue:GetClassifier','glue:GetClassifiers','glue:GetConnection','glue:GetConnections','glue:GetCrawler','glue:GetCrawlerMetrics','glue:GetCrawlers','glue:GetDatabase','glue:GetDatabases','glue:GetDataflowGraph','glue:GetDevEndpoint','glue:GetDevEndpoints','glue:GetJob','glue:GetJobRun','glue:GetJobRuns','glue:GetJobs','glue:GetMapping','glue:GetPartition','glue:GetPartitions','glue:GetPlan','glue:GetTable','glue:GetTables','glue:GetTableVersions','glue:GetTrigger','glue:GetTriggers','glue:GetUserDefinedFunction','glue:GetUserDefinedFunctions','glue:ImportCatalogToGlue','glue:ResetJobBookmark','glue:StartCrawler','glue:StartCrawlerSchedule','glue:StartJobRun','glue:StartTrigger','glue:StopCrawler','glue:StopCrawlerSchedule','glue:StopTrigger','glue:UpdateClassifier','glue:UpdateConnection','glue:UpdateCrawler','glue:UpdateDatabase','glue:UpdateDevEndpoint','glue:UpdateJob','glue:UpdatePartition','glue:UpdateTable','glue:UpdateTrigger','glue:UpdateUserDefinedFunction','greengrass:AssociateRoleToGroup','greengrass:AssociateServiceRoleToAccount','greengrass:CreateCoreDefinition','greengrass:CreateCoreDefinitionVersion','greengrass:CreateDeployment','greengrass:CreateDeviceDefinition','greengrass:CreateDeviceDefinitionVersion','greengrass:CreateFunctionDefinition','greengrass:CreateFunctionDefinitionVersion','greengrass:CreateGroup','greengrass:CreateGroupCertificateAuthority','greengrass:CreateGroupVersion','greengrass:CreateLoggerDefinition','greengrass:CreateLoggerDefinitionVersion','greengrass:CreateResourceDefinition','greengrass:CreateResourceDefinitionVersion','greengrass:CreateSoftwareUpdateJob','greengrass:CreateSubscriptionDefinition','greengrass:CreateSubscriptionDefinitionVersion','greengrass:DeleteCoreDefinition','greengrass:DeleteDeviceDefinition','greengrass:DeleteFunctionDefinition','greengrass:DeleteGroup','greengrass:DeleteLoggerDefinition','greengrass:DeleteResourceDefinition','greengrass:DeleteSubscriptionDefinition','greengrass:DisassociateRoleFromGroup','greengrass:DisassociateServiceRoleFromAccount','greengrass:GetAssociatedRole','greengrass:GetConnectivityInfo','greengrass:GetCoreDefinition','greengrass:GetCoreDefinitionVersion','greengrass:GetDeploymentStatus','greengrass:GetDeviceDefinition','greengrass:GetDeviceDefinitionVersion','greengrass:GetFunctionDefinition','greengrass:GetFunctionDefinitionVersion','greengrass:GetGroup','greengrass:GetGroupCertificateAuthority','greengrass:GetGroupCertificateConfiguration','greengrass:GetGroupVersion','greengrass:GetLoggerDefinition','greengrass:GetLoggerDefinitionVersion','greengrass:GetResourceDefinition','greengrass:GetResourceDefinitionVersion','greengrass:GetServiceRoleForAccount','greengrass:GetSubscriptionDefinition','greengrass:GetSubscriptionDefinitionVersion','greengrass:ListCoreDefinitions','greengrass:ListCoreDefinitionVersions','greengrass:ListDeployments','greengrass:ListDeviceDefinitions','greengrass:ListDeviceDefinitionVersions','greengrass:ListFunctionDefinitions','greengrass:ListFunctionDefinitionVersions','greengrass:ListGroupCertificateAuthorities','greengrass:ListGroups','greengrass:ListGroupVersions','greengrass:ListLoggerDefinitions','greengrass:ListLoggerDefinitionVersions','greengrass:ListResourceDefinitions','greengrass:ListResourceDefinitionVersions','greengrass:ListSubscriptionDefinitions','greengrass:ListSubscriptionDefinitionVersions','greengrass:ResetDeployments','greengrass:UpdateConnectivityInfo','greengrass:UpdateCoreDefinition','greengrass:UpdateDeviceDefinition','greengrass:UpdateFunctionDefinition','greengrass:UpdateGroup','greengrass:UpdateGroupCertificateConfiguration','greengrass:UpdateLoggerDefinition','greengrass:UpdateResourceDefinition','greengrass:UpdateSubscriptionDefinition','guardduty:AcceptInvitation','guardduty:ArchiveFindings','guardduty:CreateDetector','guardduty:CreateIPSet','guardduty:CreateMembers','guardduty:CreateSampleFindings','guardduty:CreateThreatIntelSet','guardduty:DeclineInvitations','guardduty:DeleteDetector','guardduty:DeleteInvitations','guardduty:DeleteIPSet','guardduty:DeleteMembers','guardduty:DeleteThreatIntelSet','guardduty:DisassociateFromMasterAccount','guardduty:DisassociateMembers','guardduty:GetDetector','guardduty:GetFindings','guardduty:GetFindingsStatistics','guardduty:GetInvitationsCount','guardduty:GetIPSet','guardduty:GetMasterAccount','guardduty:GetMembers','guardduty:GetThreatIntelSet','guardduty:InviteMembers','guardduty:ListDetectors','guardduty:ListFindings','guardduty:ListInvitations','guardduty:ListIPSets','guardduty:ListMembers','guardduty:ListThreatIntelSets','guardduty:StartMonitoringMembers','guardduty:StopMonitoringMembers','guardduty:UnarchiveFindings','guardduty:UpdateDetector','guardduty:UpdateFindingsFeedback','guardduty:UpdateIPSet','guardduty:UpdateThreatIntelSet','health:DescribeAffectedEntities','health:DescribeEntityAggregates','health:DescribeEventAggregates','health:DescribeEventDetails','health:DescribeEvents','health:DescribeEventTypes','iam:AddClientIDToOpenIDConnectProvider','iam:AddRoleToInstanceProfile','iam:AddUserToGroup','iam:AttachGroupPolicy','iam:AttachRolePolicy','iam:AttachUserPolicy','iam:ChangePassword','iam:CreateAccessKey','iam:CreateAccountAlias','iam:CreateGroup','iam:CreateInstanceProfile','iam:CreateLoginProfile','iam:CreateOpenIDConnectProvider','iam:CreatePolicy','iam:CreatePolicyVersion','iam:CreateRole','iam:CreateSAMLProvider','iam:CreateServiceLinkedRole','iam:CreateServiceSpecificCredential','iam:CreateUser','iam:CreateVirtualMFADevice','iam:DeactivateMFADevice','iam:DeleteAccessKey','iam:DeleteAccountAlias','iam:DeleteAccountPasswordPolicy','iam:DeleteGroup','iam:DeleteGroupPolicy','iam:DeleteInstanceProfile','iam:DeleteLoginProfile','iam:DeleteOpenIDConnectProvider','iam:DeletePolicy','iam:DeletePolicyVersion','iam:DeleteRole','iam:DeleteRolePolicy','iam:DeleteSAMLProvider','iam:DeleteServerCertificate','iam:DeleteServiceLinkedRole','iam:DeleteServiceSpecificCredential','iam:DeleteSigningCertificate','iam:DeleteSSHPublicKey','iam:DeleteUser','iam:DeleteUserPolicy','iam:DeleteVirtualMFADevice','iam:DetachGroupPolicy','iam:DetachRolePolicy','iam:DetachUserPolicy','iam:EnableMFADevice','iam:GenerateCredentialReport','iam:GenerateServiceLastAccessedDetails','iam:GetAccessKeyLastUsed','iam:GetAccountAuthorizationDetails','iam:GetAccountPasswordPolicy','iam:GetAccountSummary','iam:GetContextKeysForCustomPolicy','iam:GetContextKeysForPrincipalPolicy','iam:GetCredentialReport','iam:GetGroup','iam:GetGroupPolicy','iam:GetInstanceProfile','iam:GetLoginProfile','iam:GetOpenIDConnectProvider','iam:GetPolicy','iam:GetPolicyVersion','iam:GetRole','iam:GetRolePolicy','iam:GetSAMLProvider','iam:GetServerCertificate','iam:GetServiceLastAccessedDetails','iam:GetServiceLastAccessedDetailsWithEntities','iam:GetServiceLinkedRoleDeletionStatus','iam:GetSSHPublicKey','iam:GetUser','iam:GetUserPolicy','iam:ListAccessKeys','iam:ListAccountAliases','iam:ListAttachedGroupPolicies','iam:ListAttachedRolePolicies','iam:ListAttachedUserPolicies','iam:ListEntitiesForPolicy','iam:ListGroupPolicies','iam:ListGroups','iam:ListGroupsForUser','iam:ListInstanceProfiles','iam:ListInstanceProfilesForRole','iam:ListMFADevices','iam:ListOpenIDConnectProviders','iam:ListPolicies','iam:ListPoliciesGrantingServiceAccess','iam:ListPolicyVersions','iam:ListRolePolicies','iam:ListRoles','iam:ListSAMLProviders','iam:ListServerCertificates','iam:ListServiceSpecificCredentials','iam:ListSigningCertificates','iam:ListSSHPublicKeys','iam:ListUserPolicies','iam:ListUsers','iam:ListVirtualMFADevices','iam:PassRole','iam:PutGroupPolicy','iam:PutRolePolicy','iam:PutUserPolicy','iam:RemoveClientIDFromOpenIDConnectProvider','iam:RemoveRoleFromInstanceProfile','iam:RemoveUserFromGroup','iam:ResetServiceSpecificCredential','iam:ResyncMFADevice','iam:SetDefaultPolicyVersion','iam:SimulateCustomPolicy','iam:SimulatePrincipalPolicy','iam:UpdateAccessKey','iam:UpdateAccountPasswordPolicy','iam:UpdateAssumeRolePolicy','iam:UpdateGroup','iam:UpdateLoginProfile','iam:UpdateOpenIDConnectProviderThumbprint','iam:UpdateRoleDescription','iam:UpdateSAMLProvider','iam:UpdateServerCertificate','iam:UpdateServiceSpecificCredential','iam:UpdateSigningCertificate','iam:UpdateSSHPublicKey','iam:UpdateUser','iam:UploadServerCertificate','iam:UploadSigningCertificate','iam:UploadSSHPublicKey','importexport:CancelJob','importexport:CreateJob','importexport:GetShippingLabel','importexport:GetStatus','importexport:ListJobs','importexport:UpdateJob','inspector:AddAttributesToFindings','inspector:CreateAssessmentTarget','inspector:CreateAssessmentTemplate','inspector:CreateResourceGroup','inspector:DeleteAssessmentRun','inspector:DeleteAssessmentTarget','inspector:DeleteAssessmentTemplate','inspector:DescribeAssessmentRuns','inspector:DescribeAssessmentTargets','inspector:DescribeAssessmentTemplates','inspector:DescribeCrossAccountAccessRole','inspector:DescribeFindings','inspector:DescribeResourceGroups','inspector:DescribeRulesPackages','inspector:GetTelemetryMetadata','inspector:ListAssessmentRunAgents','inspector:ListAssessmentRuns','inspector:ListAssessmentTargets','inspector:ListAssessmentTemplates','inspector:ListEventSubscriptions','inspector:ListFindings','inspector:ListRulesPackages','inspector:ListTagsForResource','inspector:PreviewAgents','inspector:RegisterCrossAccountAccessRole','inspector:RemoveAttributesFromFindings','inspector:SetTagsForResource','inspector:StartAssessmentRun','inspector:StopAssessmentRun','inspector:SubscribeToEvent','inspector:UnsubscribeFromEvent','inspector:UpdateAssessmentTarget','iot:AcceptCertificateTransfer','iot:AssociateTargetsWithJob','iot:AttachPolicy','iot:AttachPrincipalPolicy','iot:AttachThingPrincipal','iot:CancelCertificateTransfer','iot:CancelJob','iot:ClearDefaultAuthorizer','iot:Connect','iot:CreateAuthorizer','iot:CreateCertificateFromCsr','iot:CreateJob','iot:CreateKeysAndCertificate','iot:CreateOTAUpdateJob','iot:CreatePolicy','iot:CreatePolicyVersion','iot:CreateRoleAlias','iot:CreateStream','iot:CreateThing','iot:CreateThingType','iot:CreateTopicRule','iot:DeleteAuthorizer','iot:DeleteCACertificate','iot:DeleteCertificate','iot:DeleteOTAUpdateJob','iot:DeletePolicy','iot:DeletePolicyVersion','iot:DeleteRegistrationCode','iot:DeleteRoleAlias','iot:DeleteStream','iot:DeleteThing','iot:DeleteThingShadow','iot:DeleteThingType','iot:DeleteTopicRule','iot:DeprecateThingType','iot:DescribeAuthorizer','iot:DescribeCACertificate','iot:DescribeCertificate','iot:DescribeDefaultAuthorizer','iot:DescribeEndpoint','iot:DescribeIndex','iot:DescribeJob','iot:DescribeJobExecution','iot:DescribeRoleAlias','iot:DescribeStream','iot:DescribeThing','iot:DescribeThingType','iot:DetachPolicy','iot:DetachPrincipalPolicy','iot:DetachThingPrincipal','iot:DisableTopicRule','iot:EnableTopicRule','iot:GetEffectivePolicies','iot:GetIndexingConfiguration','iot:GetJobDocument','iot:GetLoggingOptions','iot:GetOTAUpdateJob','iot:GetPolicy','iot:GetPolicyVersion','iot:GetRegistrationCode','iot:GetThingShadow','iot:GetTopicRule','iot:ListAttachedPolicies','iot:ListAuthorizers','iot:ListCACertificates','iot:ListCertificates','iot:ListCertificatesByCA','iot:ListIndices','iot:ListJobExecutionsForJob','iot:ListJobExecutionsForThing','iot:ListJobs','iot:ListOTAUpdateJobs','iot:ListOutgoingCertificates','iot:ListPolicies','iot:ListPolicyPrincipals','iot:ListPolicyVersions','iot:ListPrincipalPolicies','iot:ListPrincipalThings','iot:ListRoleAliases','iot:ListStreams','iot:ListTargetsForPolicy','iot:ListThingPrincipals','iot:ListThings','iot:ListThingTypes','iot:ListTopicRules','iot:Publish','iot:Receive','iot:RegisterCACertificate','iot:RegisterCertificate','iot:RejectCertificateTransfer','iot:ReplaceTopicRule','iot:SearchIndex','iot:SetDefaultAuthorizer','iot:SetDefaultPolicyVersion','iot:SetLoggingOptions','iot:Subscribe','iot:TestAuthorization','iot:TestInvokeAuthorizer','iot:TransferCertificate','iot:UpdateAuthorizer','iot:UpdateCACertificate','iot:UpdateCertificate','iot:UpdateIndexingConfiguration','iot:UpdateRoleAlias','iot:UpdateStream','iot:UpdateThing','iot:UpdateThingShadow','iotanalytics:CreateChannel','iotanalytics:CreateDataset','iotanalytics:CreateDatasetContent','iotanalytics:CreateDatastore','iotanalytics:CreatePipeline','iotanalytics:DeleteChannel','iotanalytics:DeleteDataset','iotanalytics:DeleteDatasetContent','iotanalytics:DeleteDatastore','iotanalytics:DeletePipeline','iotanalytics:DescribeChannel','iotanalytics:DescribeDataset','iotanalytics:DescribeDatastore','iotanalytics:DescribePipeline','iotanalytics:GetDatasetContent','iotanalytics:ListChannels','iotanalytics:ListDatasets','iotanalytics:ListDatastores','iotanalytics:ListPipelines','iotanalytics:UpdateDataset','iotanalytics:UpdatePipeline','kinesis:AddTagsToStream','kinesis:CreateStream','kinesis:DecreaseStreamRetentionPeriod','kinesis:DeleteStream','kinesis:DescribeLimits','kinesis:DescribeStream','kinesis:DisableEnhancedMonitoring','kinesis:EnableEnhancedMonitoring','kinesis:GetRecords','kinesis:GetShardIterator','kinesis:IncreaseStreamRetentionPeriod','kinesis:ListStreams','kinesis:ListTagsForStream','kinesis:MergeShards','kinesis:PutRecord','kinesis:PutRecords','kinesis:RemoveTagsFromStream','kinesis:SplitShard','kinesis:UpdateShardCount','kinesisanalytics:AddApplicationInput','kinesisanalytics:AddApplicationOutput','kinesisanalytics:AddApplicationReferenceDataSource','kinesisanalytics:CreateApplication','kinesisanalytics:DeleteApplication','kinesisanalytics:DeleteApplicationOutput','kinesisanalytics:DeleteApplicationReferenceDataSource','kinesisanalytics:DescribeApplication','kinesisanalytics:DiscoverInputSchema','kinesisanalytics:ListApplications','kinesisanalytics:StartApplication','kinesisanalytics:StopApplication','kinesisanalytics:UpdateApplication','kinesisvideo:CreateStream','kinesisvideo:DeleteStream','kinesisvideo:DescribeStream','kinesisvideo:GetDataEndpoint','kinesisvideo:GetMedia','kinesisvideo:GetMediaForFragmentList','kinesisvideo:ListFragments','kinesisvideo:ListStreams','kinesisvideo:ListTagsForStream','kinesisvideo:PutMedia','kinesisvideo:TagStream','kinesisvideo:UntagStream','kinesisvideo:UpdateDataRetention','kinesisvideo:UpdateStream','kms:CancelKeyDeletion','kms:CreateAlias','kms:CreateGrant','kms:CreateKey','kms:Decrypt','kms:DeleteAlias','kms:DeleteImportedKeyMaterial','kms:DescribeKey','kms:DisableKey','kms:DisableKeyRotation','kms:EnableKey','kms:EnableKeyRotation','kms:Encrypt','kms:GenerateDataKey','kms:GenerateDataKeyWithoutPlaintext','kms:GenerateRandom','kms:GetKeyPolicy','kms:GetKeyRotationStatus','kms:GetParametersForImport','kms:ImportKeyMaterial','kms:ListAliases','kms:ListGrants','kms:ListKeyPolicies','kms:ListKeys','kms:ListResourceTags','kms:ListRetirableGrants','kms:PutKeyPolicy','kms:ReEncryptFrom','kms:ReEncryptTo','kms:RetireGrant','kms:RevokeGrant','kms:ScheduleKeyDeletion','kms:TagResource','kms:UntagResource','kms:UpdateAlias','kms:UpdateKeyDescription','lambda:AddPermission','lambda:CreateAlias','lambda:CreateEventSourceMapping','lambda:CreateFunction','lambda:DeleteAlias','lambda:DeleteEventSourceMapping','lambda:DeleteFunction','lambda:DeleteFunctionConcurrency','lambda:EnableReplication','lambda:GetAccountSettings','lambda:GetAlias','lambda:GetEventSourceMapping','lambda:GetFunction','lambda:GetFunctionConfiguration','lambda:GetPolicy','lambda:InvokeAsync','lambda:InvokeFunction','lambda:ListAliases','lambda:ListEventSourceMappings','lambda:ListFunctions','lambda:ListTags','lambda:ListVersionsByFunction','lambda:PublishVersion','lambda:PutFunctionConcurrency','lambda:RemovePermission','lambda:TagResource','lambda:UntagResource','lambda:UpdateAlias','lambda:UpdateEventSourceMapping','lambda:UpdateFunctionCode','lambda:UpdateFunctionConfiguration','lex:CreateBotVersion','lex:CreateIntentVersion','lex:CreateSlotTypeVersion','lex:DeleteBot','lex:DeleteBotAlias','lex:DeleteBotChannelAssociation','lex:DeleteBotVersion','lex:DeleteIntent','lex:DeleteIntentVersion','lex:DeleteSlotType','lex:DeleteSlotTypeVersion','lex:DeleteUtterances','lex:GetBot','lex:GetBotAlias','lex:GetBotAliases','lex:GetBotChannelAssociation','lex:GetBotChannelAssociations','lex:GetBots','lex:GetBotVersions','lex:GetBuiltinIntent','lex:GetBuiltinIntents','lex:GetBuiltinSlotTypes','lex:GetIntent','lex:GetIntents','lex:GetIntentVersions','lex:GetSlotType','lex:GetSlotTypes','lex:GetSlotTypeVersions','lex:GetUtterancesView','lex:PostContent','lex:PostText','lex:PutBot','lex:PutBotAlias','lex:PutIntent','lex:PutSlotType','lightsail:AllocateStaticIp','lightsail:AttachStaticIp','lightsail:CloseInstancePublicPorts','lightsail:CreateDomain','lightsail:CreateDomainEntry','lightsail:CreateInstances','lightsail:CreateInstancesFromSnapshot','lightsail:CreateInstanceSnapshot','lightsail:CreateKeyPair','lightsail:DeleteDomain','lightsail:DeleteDomainEntry','lightsail:DeleteInstance','lightsail:DeleteInstanceSnapshot','lightsail:DeleteKeyPair','lightsail:DetachStaticIp','lightsail:DownloadDefaultKeyPair','lightsail:GetActiveNames','lightsail:GetBlueprints','lightsail:GetBundles','lightsail:GetDomain','lightsail:GetDomains','lightsail:GetInstance','lightsail:GetInstanceAccessDetails','lightsail:GetInstanceMetricData','lightsail:GetInstancePortStates','lightsail:GetInstances','lightsail:GetInstanceSnapshot','lightsail:GetInstanceSnapshots','lightsail:GetInstanceState','lightsail:GetKeyPair','lightsail:GetKeyPairs','lightsail:GetOperation','lightsail:GetOperations','lightsail:GetOperationsForResource','lightsail:GetRegions','lightsail:GetStaticIp','lightsail:GetStaticIps','lightsail:ImportKeyPair','lightsail:IsVpcPeered','lightsail:OpenInstancePublicPorts','lightsail:PeerVpc','lightsail:RebootInstance','lightsail:ReleaseStaticIp','lightsail:StartInstance','lightsail:StopInstance','lightsail:UnpeerVpc','lightsail:UpdateDomainEntry','logs:AssociateKmsKey','logs:CancelExportTask','logs:CreateExportTask','logs:CreateLogGroup','logs:CreateLogStream','logs:DeleteDestination','logs:DeleteLogGroup','logs:DeleteLogStream','logs:DeleteMetricFilter','logs:DeleteResourcePolicy','logs:DeleteRetentionPolicy','logs:DeleteSubscriptionFilter','logs:DescribeDestinations','logs:DescribeExportTasks','logs:DescribeLogGroups','logs:DescribeLogStreams','logs:DescribeMetricFilters','logs:DescribeResourcePolicies','logs:DescribeSubscriptionFilters','logs:DisassociateKmsKey','logs:FilterLogEvents','logs:GetLogEvents','logs:ListTagsLogGroup','logs:PutDestination','logs:PutDestinationPolicy','logs:PutLogEvents','logs:PutMetricFilter','logs:PutResourcePolicy','logs:PutRetentionPolicy','logs:PutSubscriptionFilter','logs:TagLogGroup','logs:TestMetricFilter','logs:UntagLogGroup','machinelearning:AddTags','machinelearning:CreateBatchPrediction','machinelearning:CreateDataSourceFromRDS','machinelearning:CreateDataSourceFromRedshift','machinelearning:CreateDataSourceFromS3','machinelearning:CreateEvaluation','machinelearning:CreateMLModel','machinelearning:CreateRealtimeEndpoint','machinelearning:DeleteBatchPrediction','machinelearning:DeleteDataSource','machinelearning:DeleteEvaluation','machinelearning:DeleteMLModel','machinelearning:DeleteRealtimeEndpoint','machinelearning:DeleteTags','machinelearning:DescribeBatchPredictions','machinelearning:DescribeDataSources','machinelearning:DescribeEvaluations','machinelearning:DescribeMLModels','machinelearning:DescribeTags','machinelearning:GetBatchPrediction','machinelearning:GetDataSource','machinelearning:GetEvaluation','machinelearning:GetMLModel','machinelearning:Predict','machinelearning:UpdateBatchPrediction','machinelearning:UpdateDataSource','machinelearning:UpdateEvaluation','machinelearning:UpdateMLModel','mechanicalturk:ApproveAssignment','mechanicalturk:ApproveRejectedAssignment','mechanicalturk:AssignQualification','mechanicalturk:BlockWorker','mechanicalturk:ChangeHITTypeOfHIT','mechanicalturk:CreateHIT','mechanicalturk:CreateQualificationType','mechanicalturk:DisableHIT','mechanicalturk:DisposeHIT','mechanicalturk:DisposeQualificationType','mechanicalturk:ExtendHIT','mechanicalturk:ForceExpireHIT','mechanicalturk:GetAccountBalance','mechanicalturk:GetAssignment','mechanicalturk:GetAssignmentsForHIT','mechanicalturk:GetBlockedWorkers','mechanicalturk:GetBonusPayments','mechanicalturk:GetFileUploadURL','mechanicalturk:GetHIT','mechanicalturk:GetHITsForQualificationType','mechanicalturk:GetQualificationRequests','mechanicalturk:GetQualificationScore','mechanicalturk:GetQualificationsForQualificationType','mechanicalturk:GetQualificationType','mechanicalturk:GetRequesterStatistic','mechanicalturk:GetRequesterWorkerStatistic','mechanicalturk:GetReviewableHITs','mechanicalturk:GetReviewResultsForHIT','mechanicalturk:GrantBonus','mechanicalturk:GrantQualification','mechanicalturk:NotifyWorkers','mechanicalturk:RegisterHITType','mechanicalturk:RejectAssignment','mechanicalturk:RejectQualificationRequest','mechanicalturk:RevokeQualification','mechanicalturk:SearchHITs','mechanicalturk:SearchQualificationTypes','mechanicalturk:SendTestEventNotification','mechanicalturk:SetHITAsReviewing','mechanicalturk:SetHITTypeNotification','mechanicalturk:UnblockWorker','mechanicalturk:UpdateQualificationScore','mechanicalturk:UpdateQualificationType','mediaconvert:CancelJob','mediaconvert:CreateJob','mediaconvert:CreateJobTemplate','mediaconvert:CreatePreset','mediaconvert:CreateQueue','mediaconvert:DeleteJobTemplate','mediaconvert:DeletePreset','mediaconvert:DeleteQueue','mediaconvert:DescribeEndpoint','mediaconvert:GetJob','mediaconvert:GetJobTemplate','mediaconvert:GetPreset','mediaconvert:GetQueue','mediaconvert:ListJobs','mediaconvert:ListJobTemplates','mediaconvert:ListPresets','mediaconvert:ListQueues','mediaconvert:UpdateJobTemplate','mediaconvert:UpdatePreset','mediaconvert:UpdateQueue','medialive:CreateChannel','medialive:CreateInput','medialive:CreateInputSecurityGroup','medialive:DeleteChannel','medialive:DeleteInput','medialive:DeleteInputSecurityGroup','medialive:DescribeChannel','medialive:DescribeInput','medialive:DescribeInputSecurityGroup','medialive:ListChannels','medialive:ListInputs','medialive:ListInputSecurityGroups','medialive:StartChannel','medialive:StopChannel','mediapackage:CreateChannel','mediapackage:CreateOriginEndpoint','mediapackage:DeleteChannel','mediapackage:DeleteOriginEndpoint','mediapackage:DescribeChannel','mediapackage:DescribeOriginEndpoint','mediapackage:ListChannels','mediapackage:ListOriginEndpoints','mediapackage:UpdateChannel','mediapackage:UpdateOriginEndpoint','mediastore:CreateContainer','mediastore:DeleteContainer','mediastore:DeleteContainerPolicy','mediastore:DeleteObject','mediastore:DescribeContainer','mediastore:DescribeObject','mediastore:GetContainerPolicy','mediastore:GetObject','mediastore:ListContainers','mediastore:ListItems','mediastore:PutContainerPolicy','mediastore:PutObject','mgh:AssociateCreatedArtifact','mgh:AssociateDiscoveredResource','mgh:CreateProgressUpdateStream','mgh:DeleteProgressUpdateStream','mgh:DescribeApplicationState','mgh:DescribeMigrationTask','mgh:DisassociateCreatedArtifact','mgh:DisassociateDiscoveredResource','mgh:ImportMigrationTask','mgh:ListCreatedArtifacts','mgh:ListDiscoveredResources','mgh:ListMigrationTasks','mgh:ListProgressUpdateStreams','mgh:NotifyApplicationState','mgh:NotifyMigrationTaskState','mgh:PutResourceAttributes','mobileanalytics:GetFinancialReports','mobileanalytics:GetReports','mobileanalytics:PutEvents','mobilehub:CreateProject','mobilehub:CreateServiceRole','mobilehub:DeleteProject','mobilehub:DeployToStage','mobilehub:DescribeBundle','mobilehub:ExportBundle','mobilehub:ExportProject','mobilehub:GenerateProjectParameters','mobilehub:GetProject','mobilehub:GetProjectSnapshot','mobilehub:ImportProject','mobilehub:ListAvailableConnectors','mobilehub:ListAvailableFeatures','mobilehub:ListAvailableRegions','mobilehub:ListBundles','mobilehub:ListProjects','mobilehub:SynchronizeProject','mobilehub:UpdateProject','mobilehub:VerifyServiceRole','mobiletargeting:CreateCampaign','mobiletargeting:CreateImportJob','mobiletargeting:CreateSegment','mobiletargeting:DeleteApnsChannel','mobiletargeting:DeleteCampaign','mobiletargeting:DeleteGcmChannel','mobiletargeting:DeleteSegment','mobiletargeting:GetApnsChannel','mobiletargeting:GetApplicationSettings','mobiletargeting:GetCampaign','mobiletargeting:GetCampaignActivities','mobiletargeting:GetCampaigns','mobiletargeting:GetCampaignVersion','mobiletargeting:GetCampaignVersions','mobiletargeting:GetEndpoint','mobiletargeting:GetGcmChannel','mobiletargeting:GetImportJob','mobiletargeting:GetImportJobs','mobiletargeting:GetReports','mobiletargeting:GetSegment','mobiletargeting:GetSegmentImportJobs','mobiletargeting:GetSegments','mobiletargeting:GetSegmentVersion','mobiletargeting:GetSegmentVersions','mobiletargeting:UpdateApnsChannel','mobiletargeting:UpdateApplicationSettings','mobiletargeting:UpdateCampaign','mobiletargeting:UpdateEndpoint','mobiletargeting:UpdateEndpointsBatch','mobiletargeting:UpdateGcmChannel','mobiletargeting:UpdateSegment','mq:CreateBroker','mq:CreateConfiguration','mq:CreateUser','mq:DeleteBroker','mq:DeleteUser','mq:DescribeBroker','mq:DescribeConfiguration','mq:DescribeConfigurationRevision','mq:DescribeUser','mq:ListBrokers','mq:ListConfigurationRevisions','mq:ListConfigurations','mq:ListUsers','mq:RebootBroker','mq:UpdateBroker','mq:UpdateConfiguration','mq:UpdateUser','opsworks:AssignInstance','opsworks:AssignVolume','opsworks:AssociateElasticIp','opsworks:AttachElasticLoadBalancer','opsworks:CloneStack','opsworks:CreateApp','opsworks:CreateDeployment','opsworks:CreateInstance','opsworks:CreateLayer','opsworks:CreateStack','opsworks:CreateUserProfile','opsworks:DeleteApp','opsworks:DeleteInstance','opsworks:DeleteLayer','opsworks:DeleteStack','opsworks:DeleteUserProfile','opsworks:DeregisterEcsCluster','opsworks:DeregisterElasticIp','opsworks:DeregisterInstance','opsworks:DeregisterRdsDbInstance','opsworks:DeregisterVolume','opsworks:DescribeAgentVersions','opsworks:DescribeApps','opsworks:DescribeCommands','opsworks:DescribeDeployments','opsworks:DescribeEcsClusters','opsworks:DescribeElasticIps','opsworks:DescribeElasticLoadBalancers','opsworks:DescribeInstances','opsworks:DescribeLayers','opsworks:DescribeLoadBasedAutoScaling','opsworks:DescribeMyUserProfile','opsworks:DescribePermissions','opsworks:DescribeRaidArrays','opsworks:DescribeRdsDbInstances','opsworks:DescribeServiceErrors','opsworks:DescribeStackProvisioningParameters','opsworks:DescribeStacks','opsworks:DescribeStackSummary','opsworks:DescribeTimeBasedAutoScaling','opsworks:DescribeUserProfiles','opsworks:DescribeVolumes','opsworks:DetachElasticLoadBalancer','opsworks:DisassociateElasticIp','opsworks:GetHostnameSuggestion','opsworks:GrantAccess','opsworks:ListTags','opsworks:RebootInstance','opsworks:RegisterEcsCluster','opsworks:RegisterElasticIp','opsworks:RegisterInstance','opsworks:RegisterRdsDbInstance','opsworks:RegisterVolume','opsworks:SetLoadBasedAutoScaling','opsworks:SetPermission','opsworks:SetTimeBasedAutoScaling','opsworks:StartInstance','opsworks:StartStack','opsworks:StopInstance','opsworks:StopStack','opsworks:TagResource','opsworks:UnassignInstance','opsworks:UnassignVolume','opsworks:UntagResource','opsworks:UpdateApp','opsworks:UpdateElasticIp','opsworks:UpdateInstance','opsworks:UpdateLayer','opsworks:UpdateMyUserProfile','opsworks:UpdateRdsDbInstance','opsworks:UpdateStack','opsworks:UpdateUserProfile','opsworks:UpdateVolume','opsworks-cm:AssociateNode','opsworks-cm:CreateBackup','opsworks-cm:CreateServer','opsworks-cm:DeleteBackup','opsworks-cm:DeleteServer','opsworks-cm:DescribeAccountAttributes','opsworks-cm:DescribeBackups','opsworks-cm:DescribeEvents','opsworks-cm:DescribeNodeAssociationStatus','opsworks-cm:DescribeServers','opsworks-cm:DisassociateNode','opsworks-cm:RestoreServer','opsworks-cm:StartMaintenance','opsworks-cm:UpdateServer','opsworks-cm:UpdateServerEngineAttributes','organizations:AcceptHandshake','organizations:AttachPolicy','organizations:CancelHandshake','organizations:CreateAccount','organizations:CreateOrganization','organizations:CreateOrganizationalUnit','organizations:CreatePolicy','organizations:DeclineHandshake','organizations:DeleteOrganization','organizations:DeleteOrganizationalUnit','organizations:DeletePolicy','organizations:DescribeAccount','organizations:DescribeCreateAccountStatus','organizations:DescribeHandshake','organizations:DescribeOrganization','organizations:DescribeOrganizationalUnit','organizations:DescribePolicy','organizations:DetachPolicy','organizations:DisablePolicyType','organizations:EnableAllFeatures','organizations:EnablePolicyType','organizations:InviteAccountToOrganization','organizations:LeaveOrganization','organizations:ListAccounts','organizations:ListAccountsForParent','organizations:ListChildren','organizations:ListCreateAccountStatus','organizations:ListHandshakesForAccount','organizations:ListHandshakesForOrganization','organizations:ListOrganizationalUnitsForParent','organizations:ListParents','organizations:ListPolicies','organizations:ListPoliciesForTarget','organizations:ListRoots','organizations:ListTargetsForPolicy','organizations:MoveAccount','organizations:RemoveAccountFromOrganization','organizations:UpdateOrganizationalUnit','organizations:UpdatePolicy','polly:DeleteLexicon','polly:DescribeVoices','polly:GetLexicon','polly:ListLexicons','polly:PutLexicon','polly:SynthesizeSpeech','pricing:DescribeServices','pricing:GetAttributeValues','pricing:GetProducts','rds:AddRoleToDBCluster','rds:AddSourceIdentifierToSubscription','rds:AddTagsToResource','rds:ApplyPendingMaintenanceAction','rds:AuthorizeDBSecurityGroupIngress','rds:CopyDBClusterSnapshot','rds:CopyDBParameterGroup','rds:CopyDBSnapshot','rds:CopyOptionGroup','rds:CreateDBCluster','rds:CreateDBClusterParameterGroup','rds:CreateDBClusterSnapshot','rds:CreateDBInstance','rds:CreateDBInstanceReadReplica','rds:CreateDBParameterGroup','rds:CreateDBSecurityGroup','rds:CreateDBSnapshot','rds:CreateDBSubnetGroup','rds:CreateEventSubscription','rds:CreateOptionGroup','rds:DeleteDBCluster','rds:DeleteDBClusterParameterGroup','rds:DeleteDBClusterSnapshot','rds:DeleteDBInstance','rds:DeleteDBParameterGroup','rds:DeleteDBSecurityGroup','rds:DeleteDBSnapshot','rds:DeleteDBSubnetGroup','rds:DeleteEventSubscription','rds:DeleteOptionGroup','rds:DescribeAccountAttributes','rds:DescribeCertificates','rds:DescribeDBClusterParameterGroups','rds:DescribeDBClusterParameters','rds:DescribeDBClusters','rds:DescribeDBClusterSnapshotAttributes','rds:DescribeDBClusterSnapshots','rds:DescribeDBEngineVersions','rds:DescribeDBInstances','rds:DescribeDBLogFiles','rds:DescribeDBParameterGroups','rds:DescribeDBParameters','rds:DescribeDBSecurityGroups','rds:DescribeDBSnapshotAttributes','rds:DescribeDBSnapshots','rds:DescribeDBSubnetGroups','rds:DescribeEngineDefaultClusterParameters','rds:DescribeEngineDefaultParameters','rds:DescribeEventCategories','rds:DescribeEvents','rds:DescribeEventSubscriptions','rds:DescribeOptionGroupOptions','rds:DescribeOptionGroups','rds:DescribeOrderableDBInstanceOptions','rds:DescribePendingMaintenanceActions','rds:DescribeReservedDBInstances','rds:DescribeReservedDBInstancesOfferings','rds:DownloadCompleteDBLogFile','rds:DownloadDBLogFilePortion','rds:FailoverDBCluster','rds:ListTagsForResource','rds:ModifyDBCluster','rds:ModifyDBClusterParameterGroup','rds:ModifyDBClusterSnapshotAttribute','rds:ModifyDBInstance','rds:ModifyDBParameterGroup','rds:ModifyDBSnapshotAttribute','rds:ModifyDBSubnetGroup','rds:ModifyEventSubscription','rds:ModifyOptionGroup','rds:PromoteReadReplica','rds:PurchaseReservedDBInstancesOffering','rds:RebootDBInstance','rds:RemoveSourceIdentifierFromSubscription','rds:RemoveTagsFromResource','rds:ResetDBClusterParameterGroup','rds:ResetDBParameterGroup','rds:RestoreDBClusterFromSnapshot','rds:RestoreDBClusterToPointInTime','rds:RestoreDBInstanceFromDBSnapshot','rds:RestoreDBInstanceToPointInTime','rds:RevokeDBSecurityGroupIngress','rds:StartDBInstance','rds:StopDBInstance','redshift:AuthorizeClusterSecurityGroupIngress','redshift:AuthorizeSnapshotAccess','redshift:CancelQuerySession','redshift:CopyClusterSnapshot','redshift:CreateCluster','redshift:CreateClusterParameterGroup','redshift:CreateClusterSecurityGroup','redshift:CreateClusterSnapshot','redshift:CreateClusterSubnetGroup','redshift:CreateClusterUser','redshift:CreateEventSubscription','redshift:CreateHsmClientCertificate','redshift:CreateHsmConfiguration','redshift:CreateSnapshotCopyGrant','redshift:CreateTags','redshift:DeleteCluster','redshift:DeleteClusterParameterGroup','redshift:DeleteClusterSecurityGroup','redshift:DeleteClusterSnapshot','redshift:DeleteClusterSubnetGroup','redshift:DeleteEventSubscription','redshift:DeleteHsmClientCertificate','redshift:DeleteHsmConfiguration','redshift:DeleteSnapshotCopyGrant','redshift:DeleteTags','redshift:DescribeClusterParameterGroups','redshift:DescribeClusterParameters','redshift:DescribeClusters','redshift:DescribeClusterSecurityGroups','redshift:DescribeClusterSnapshots','redshift:DescribeClusterSubnetGroups','redshift:DescribeClusterVersions','redshift:DescribeDefaultClusterParameters','redshift:DescribeEventCategories','redshift:DescribeEvents','redshift:DescribeEventSubscriptions','redshift:DescribeHsmClientCertificates','redshift:DescribeHsmConfigurations','redshift:DescribeLoggingStatus','redshift:DescribeOrderableClusterOptions','redshift:DescribeReservedNodeOfferings','redshift:DescribeReservedNodes','redshift:DescribeResize','redshift:DescribeSnapshotCopyGrants','redshift:DescribeTableRestoreStatus','redshift:DescribeTags','redshift:DisableLogging','redshift:DisableSnapshotCopy','redshift:EnableLogging','redshift:EnableSnapshotCopy','redshift:GetClusterCredentials','redshift:JoinGroup','redshift:ModifyCluster','redshift:ModifyClusterIamRoles','redshift:ModifyClusterParameterGroup','redshift:ModifyClusterSubnetGroup','redshift:ModifyEventSubscription','redshift:ModifySnapshotCopyRetentionPeriod','redshift:PurchaseReservedNodeOffering','redshift:RebootCluster','redshift:ResetClusterParameterGroup','redshift:RestoreFromClusterSnapshot','redshift:RestoreTableFromClusterSnapshot','redshift:RevokeClusterSecurityGroupIngress','redshift:RevokeSnapshotAccess','redshift:RotateEncryptionKey','redshift:ViewQueriesInConsole','rekognition:CompareFaces','rekognition:CreateCollection','rekognition:CreateStreamProcessor','rekognition:DeleteCollection','rekognition:DeleteFaces','rekognition:DeleteStreamProcessor','rekognition:DescribeStreamProcessor','rekognition:DetectFaces','rekognition:DetectLabels','rekognition:DetectModerationLabels','rekognition:DetectText','rekognition:GetCelebrityInfo','rekognition:GetCelebrityRecognition','rekognition:GetContentModeration','rekognition:GetFaceDetection','rekognition:GetFaceSearch','rekognition:GetLabelDetection','rekognition:GetPersonTracking','rekognition:IndexFaces','rekognition:ListCollections','rekognition:ListFaces','rekognition:ListStreamProcessors','rekognition:RecognizeCelebrities','rekognition:SearchFaces','rekognition:SearchFacesByImage','rekognition:StartCelebrityRecognition','rekognition:StartContentModeration','rekognition:StartFaceDetection','rekognition:StartFaceSearch','rekognition:StartLabelDetection','rekognition:StartPersonTracking','rekognition:StartStreamProcessor','rekognition:StopStreamProcessor','resource-groups:CreateGroup','resource-groups:DeleteGroup','resource-groups:GetGroup','resource-groups:GetGroupQuery','resource-groups:GetTags','resource-groups:ListGroupResources','resource-groups:ListGroups','resource-groups:SearchResources','resource-groups:Tag','resource-groups:Untag','resource-groups:UpdateGroup','resource-groups:UpdateGroupQuery','route53:AssociateVPCWithHostedZone','route53:ChangeResourceRecordSets','route53:ChangeTagsForResource','route53:CreateHealthCheck','route53:CreateHostedZone','route53:CreateReusableDelegationSet','route53:CreateTrafficPolicy','route53:CreateTrafficPolicyInstance','route53:CreateTrafficPolicyVersion','route53:DeleteHealthCheck','route53:DeleteHostedZone','route53:DeleteReusableDelegationSet','route53:DeleteTrafficPolicy','route53:DeleteTrafficPolicyInstance','route53:DisableDomainAutoRenew','route53:DisassociateVPCFromHostedZone','route53:EnableDomainAutoRenew','route53:GetChange','route53:GetCheckerIpRanges','route53:GetGeoLocation','route53:GetHealthCheck','route53:GetHealthCheckCount','route53:GetHealthCheckLastFailureReason','route53:GetHealthCheckStatus','route53:GetHostedZone','route53:GetHostedZoneCount','route53:GetReusableDelegationSet','route53:GetTrafficPolicy','route53:GetTrafficPolicyInstance','route53:GetTrafficPolicyInstanceCount','route53:ListGeoLocations','route53:ListHealthChecks','route53:ListHostedZones','route53:ListHostedZonesByName','route53:ListResourceRecordSets','route53:ListReusableDelegationSets','route53:ListTagsForResource','route53:ListTagsForResources','route53:ListTrafficPolicies','route53:ListTrafficPolicyInstances','route53:ListTrafficPolicyInstancesByHostedZone','route53:ListTrafficPolicyInstancesByPolicy','route53:ListTrafficPolicyVersions','route53:TestDNSAnswer','route53:UpdateHealthCheck','route53:UpdateHostedZoneComment','route53:UpdateTrafficPolicyComment','route53:UpdateTrafficPolicyInstance','route53domains:CheckDomainAvailability','route53domains:DeleteTagsForDomain','route53domains:DisableDomainAutoRenew','route53domains:DisableDomainTransferLock','route53domains:EnableDomainAutoRenew','route53domains:EnableDomainTransferLock','route53domains:GetContactReachabilityStatus','route53domains:GetDomainDetail','route53domains:GetDomainSuggestions','route53domains:GetOperationDetail','route53domains:ListDomains','route53domains:ListOperations','route53domains:ListTagsForDomain','route53domains:RegisterDomain','route53domains:RenewDomain','route53domains:ResendContactReachabilityEmail','route53domains:RetrieveDomainAuthCode','route53domains:TransferDomain','route53domains:UpdateDomainContact','route53domains:UpdateDomainContactPrivacy','route53domains:UpdateDomainNameservers','route53domains:UpdateTagsForDomain','route53domains:ViewBilling','s3:AbortMultipartUpload','s3:CreateBucket','s3:DeleteBucket','s3:DeleteBucketPolicy','s3:DeleteBucketWebsite','s3:DeleteObject','s3:DeleteObjectTagging','s3:DeleteObjectVersion','s3:DeleteObjectVersionTagging','s3:GetAccelerateConfiguration','s3:GetAnalyticsConfiguration','s3:GetBucketAcl','s3:GetBucketCORS','s3:GetBucketLocation','s3:GetBucketLogging','s3:GetBucketNotification','s3:GetBucketPolicy','s3:GetBucketRequestPayment','s3:GetBucketTagging','s3:GetBucketVersioning','s3:GetBucketWebsite','s3:GetInventoryConfiguration','s3:GetIpConfiguration','s3:GetLifecycleConfiguration','s3:GetMetricsConfiguration','s3:GetObject','s3:GetObjectAcl','s3:GetObjectTagging','s3:GetObjectTorrent','s3:GetObjectVersion','s3:GetObjectVersionAcl','s3:GetObjectVersionForReplication','s3:GetObjectVersionTagging','s3:GetObjectVersionTorrent','s3:GetReplicationConfiguration','s3:HeadBucket','s3:ListAllMyBuckets','s3:ListBucket','s3:ListBucketByTags','s3:ListBucketMultipartUploads','s3:ListBucketVersions','s3:ListMultipartUploadParts','s3:ListObjects','s3:ObjectOwnerOverrideToBucketOwner','s3:PutAccelerateConfiguration','s3:PutAnalyticsConfiguration','s3:PutBucketAcl','s3:PutBucketCORS','s3:PutBucketLogging','s3:PutBucketNotification','s3:PutBucketPolicy','s3:PutBucketRequestPayment','s3:PutBucketTagging','s3:PutBucketVersioning','s3:PutBucketWebsite','s3:PutInventoryConfiguration','s3:PutIpConfiguration','s3:PutLifecycleConfiguration','s3:PutMetricsConfiguration','s3:PutObject','s3:PutObjectAcl','s3:PutObjectTagging','s3:PutObjectVersionAcl','s3:PutObjectVersionTagging','s3:PutReplicationConfiguration','s3:ReplicateDelete','s3:ReplicateObject','s3:ReplicateTags','s3:RestoreObject','sagemaker:AddTags','sagemaker:CreateEndpoint','sagemaker:CreateEndpointConfig','sagemaker:CreateModel','sagemaker:CreateNotebookInstance','sagemaker:CreatePresignedNotebookInstanceUrl','sagemaker:CreateTrainingJob','sagemaker:DeleteEndpoint','sagemaker:DeleteEndpointConfig','sagemaker:DeleteModel','sagemaker:DeleteNotebookInstance','sagemaker:DeleteTags','sagemaker:DescribeEndpoint','sagemaker:DescribeEndpointConfig','sagemaker:DescribeModel','sagemaker:DescribeNotebookInstance','sagemaker:DescribeTrainingJob','sagemaker:InvokeEndpoint','sagemaker:ListEndpointConfigs','sagemaker:ListEndpoints','sagemaker:ListModels','sagemaker:ListNotebookInstances','sagemaker:ListTags','sagemaker:ListTrainingJobs','sagemaker:StartNotebookInstance','sagemaker:StopNotebookInstance','sagemaker:StopTrainingJob','sagemaker:UpdateEndpoint','sagemaker:UpdateEndpointWeightsAndCapacities','sagemaker:UpdateNotebookInstance','sdb:BatchDeleteAttributes','sdb:BatchPutAttributes','sdb:CreateDomain','sdb:DeleteAttributes','sdb:DeleteDomain','sdb:DomainMetadata','sdb:GetAttributes','sdb:ListDomains','sdb:PutAttributes','sdb:Select','serverlessrepo:CreateApplication','serverlessrepo:CreateApplicationVersion','serverlessrepo:CreateCloudFormationChangeSet','serverlessrepo:DeleteApplication','serverlessrepo:GetApplication','serverlessrepo:GetApplicationPolicy','serverlessrepo:ListApplications','serverlessrepo:ListApplicationVersions','serverlessrepo:PutApplicationPolicy','serverlessrepo:SearchApplications','serverlessrepo:UpdateApplication','servicecatalog:AcceptPortfolioShare','servicecatalog:AssociatePrincipalWithPortfolio','servicecatalog:AssociateProductWithPortfolio','servicecatalog:CreateConstraint','servicecatalog:CreatePortfolio','servicecatalog:CreatePortfolioShare','servicecatalog:CreateProduct','servicecatalog:CreateProvisioningArtifact','servicecatalog:DeleteConstraint','servicecatalog:DeletePortfolio','servicecatalog:DeletePortfolioShare','servicecatalog:DeleteProduct','servicecatalog:DeleteProvisioningArtifact','servicecatalog:DescribeConstraint','servicecatalog:DescribePortfolio','servicecatalog:DescribeProduct','servicecatalog:DescribeProductAsAdmin','servicecatalog:DescribeProductView','servicecatalog:DescribeProvisioningArtifact','servicecatalog:DescribeProvisioningParameters','servicecatalog:DescribeRecord','servicecatalog:DisassociatePrincipalFromPortfolio','servicecatalog:DisassociateProductFromPortfolio','servicecatalog:ListAcceptedPortfolioShares','servicecatalog:ListConstraintsForPortfolio','servicecatalog:ListLaunchPaths','servicecatalog:ListPortfolioAccess','servicecatalog:ListPortfolios','servicecatalog:ListPortfoliosForProduct','servicecatalog:ListPrincipalsForPortfolio','servicecatalog:ListProvisioningArtifacts','servicecatalog:ListRecordHistory','servicecatalog:ProvisionProduct','servicecatalog:RejectPortfolioShare','servicecatalog:ScanProvisionedProducts','servicecatalog:SearchProducts','servicecatalog:SearchProductsAsAdmin','servicecatalog:TerminateProvisionedProduct','servicecatalog:UpdateConstraint','servicecatalog:UpdatePortfolio','servicecatalog:UpdateProduct','servicecatalog:UpdateProvisionedProduct','servicecatalog:UpdateProvisioningArtifact','servicediscovery:CreatePrivateDnsNamespace','servicediscovery:CreatePublicDnsNamespace','servicediscovery:CreateService','servicediscovery:DeleteNamespace','servicediscovery:DeleteService','servicediscovery:DeregisterInstance','servicediscovery:GetInstance','servicediscovery:GetInstancesHealthStatus','servicediscovery:GetNamespace','servicediscovery:GetOperation','servicediscovery:GetService','servicediscovery:ListInstances','servicediscovery:ListNamespaces','servicediscovery:ListOperations','servicediscovery:ListServices','servicediscovery:RegisterInstance','servicediscovery:UpdateInstanceHeartbeatStatus','servicediscovery:UpdateService','ses:CloneReceiptRuleSet','ses:CreateConfigurationSet','ses:CreateConfigurationSetEventDestination','ses:CreateConfigurationSetTrackingOptions','ses:CreateCustomVerificationEmailTemplate','ses:CreateReceiptFilter','ses:CreateReceiptRule','ses:CreateReceiptRuleSet','ses:CreateTemplate','ses:DeleteConfigurationSet','ses:DeleteConfigurationSetEventDestination','ses:DeleteConfigurationSetTrackingOptions','ses:DeleteCustomVerificationEmailTemplate','ses:DeleteIdentity','ses:DeleteIdentityPolicy','ses:DeleteReceiptFilter'