Invoke-Terraform.psm1


Function Copy-TerraformBinary {
    param(
        [parameter(Mandatory)]
        [string]$TFVersion,
        [string]$ZipPath
    )

    $installPath = (Get-TerraformConfiguration).TFPath
    if (-not (Test-Path $installPath -PathType Container)) {
        if (-not (New-Item -Path $installPath -ItemType 'directory')) {
            throw "Failed to create $($installPath) preference directory"
        }
    }

    $binary = 'terraform'
    if ($isWindows) {
        $binary += '.exe'
    }

    $binaryVersion = 'terraform_{0}' -f $TFVersion
    if ($IsWindows) {
        $binaryVersion += '.exe'
    }

    if ($ZipPath) {
        $tmpPath = [System.IO.Path]::GetTempPath()
        [string] $guid = [System.Guid]::NewGuid()

        $tmpfolder = (Join-Path $tmpPath $guid)

        Expand-Archive -Path $zipPath -DestinationPath $tmpFolder

        $sourcePath = (Join-Path $tmpFolder $binary)
        $destPath = (Join-Path $installPath $binaryVersion)
    } else {
        $sourcePath = (Join-Path $installPath $binaryVersion)
        $destPath = (Join-Path $installPath $binary)
    }
    Copy-Item -Path $sourcePath -Destination $destPath -Force

    # TODO: Is Powershelly way?
    if (-not $IsWindows) {
        & chmod +x $destPath
    }
}
function Get-TerraformLatestRelease {
    $headers = @{
        Accept = 'application/vnd.github.v3+json'
    }

    $response = Invoke-RestMethod 'https://api.github.com/repos/hashicorp/terraform/releases/latest' -Method 'GET' -Headers $headers
    $latest = $response.name.substring(1)
    return $latest
}
Function Get-TerraformPath {
    param(
        [parameter(Mandatory)]
        [string]$TFVersion
    )

    if ($isWindows) {
        $fileExt = '.exe'
    }
    return Join-Path (Get-TerraformConfiguration).TFPath "terraform_$($TFVersion)$($fileExt)"
}
function Get-TerraformPlatform {

    if ($IsWindows) {
        return 'windows'
    }

    if ($IsLinux) {
        return 'linux'
    }

    if ($IsMacOS) {
        return 'darwin'
    }
    throw 'Unknown platform.'
}
Function Get-TerraformVersion {
    param(
        [parameter(Mandatory)]
        [string]$Path
    )

    $terraformVersionFile = Join-Path -Path $Path -ChildPath .terraform-version
    if (Test-Path -Path $terraformVersionFile -PathType Leaf) {
        return $terraformVersionFile
    }

    $Parent = Split-Path $Path
    if ($Parent -eq $Home) {
        return $null
    }
    if ($Parent) {
        return Get-TerraformVersion $Parent
    }

    # Shouldn't get here
    return $null
}
Function Get-TerraformZip {
    param(
        [parameter(Mandatory)]
        [string]$TFVersion,
        [switch]$SkipChecksum = $False
    )

    $platform = Get-TerraformPlatform
    $shaKeyId = ((Get-TerraformConfiguration).HashiCorpPGPKeyId).Substring(10)

    $archiveName = 'terraform_{0}_{1}_amd64.zip' -f $TFVersion, $platform
    $zipUrl = '{0}/{1}/terraform_{1}_{2}_amd64.zip' -f (Get-TerraformConfiguration).ReleaseUrl, $TFVersion, $platform
    $shaUrl = '{0}/{1}/terraform_{1}_SHA256SUMS' -f (Get-TerraformConfiguration).ReleaseUrl, $TFVersion
    $shaSigUrl = '{0}/{1}/terraform_{1}_SHA256SUMS.{2}.sig' -f (Get-TerraformConfiguration).ReleaseUrl, $TFVersion, $shaKeyId

    $tmpPath = [System.IO.Path]::GetTempPath()
    [string] $guid = [System.Guid]::NewGuid()

    $zipPath = (Join-Path $tmpPath "$($guid).zip")
    $shaPath = (Join-Path $tmpPath "$($guid)_SHA256SUMS")
    $shaSigPath = (Join-Path $tmpPath "$($guid)_SHA256SUMS.sig")

    try {
        Invoke-WebRequest -Uri $zipUrl -OutFile $zipPath
    } catch {
        Write-Error "Unable to request $($zipUrl)"
        throw $_
    }

    try {
        Invoke-WebRequest -Uri $shaUrl -OutFile $shaPath
    } catch {
        throw "Unable to request $($shaUrl)"
    }

    try {
        Invoke-WebRequest -Uri $shaSigUrl -OutFile $shaSigPath
    } catch {
        throw "Unable to request $($shaSigUrl)"
    }

    if ( -not (Test-TerraformArchiveChecksum -SkipChecksum:$SkipChecksum -ArchiveName $archiveName -ZipPath $zipPath -SHAPath $shaPath -SHASigPath $shaSigPath) ) {
        throw 'Terraform Archive failed Checksum test.'
    }
    return $zipPath
}
Function Install-TerraformBinary {
    param(
        [parameter(Mandatory)]
        [string]$TFVersion,
        [switch]$SkipChecksum = $False,
        [switch]$SkipCodeSignature = $False
    )

    $zipPath = Get-TerraformZip -TFVersion $TFVersion -SkipChecksum:$SkipChecksum

    try {
        Copy-TerraformBinary -TFVersion $TFVersion -ZipPath $zipPath
    } catch {
        Write-Error "Unable to copy binary from $zipPath."
        throw $_
    }

    if (-not (Test-TerraformPath -TFVersion $TFVersion)) {
        throw "Failed to install Terraform $($TFversion) binary."
    }

    if ( -not (Test-TerraformCodeSignature -TFVersion $TFVersion -SkipCodeSignature:$SkipCodeSignature)) {
        Uninstall-Terraform -TFVersion $TFVersion
        throw "Terraform $($TFversion) fail to pass Code Signature test. Uninstalling."
    }
}
function Test-TerraformArchiveChecksum {
    param (
        [parameter(Mandatory)]
        [string]$ArchiveName,
        [parameter(Mandatory)]
        [string]$ZipPath,
        [parameter(Mandatory)]
        [string]$SHAPath,
        [parameter(Mandatory)]
        [string]$SHASigPath,
        [switch]$SkipChecksum = $False

    )

    if ($SkipChecksum -or (Get-TerraformConfiguration).SkipChecksum) {
        Write-Verbose 'Skipping Terraform Archive Checksum test.'
        return $true
    }

    gpg --list-keys (Get-TerraformConfiguration).HashiCorpPGPKeyId # 2>&1 | Out-Null
    if ($LASTEXITCODE -ne 0) {
        gpg --quiet --keyserver (Get-TerraformConfiguration).PGPKeyServer --recv (Get-TerraformConfiguration).HashiCorpPGPKeyId
        if ($LASTEXITCODE -ne 0) {
            throw 'Unable to retrieve HashiCorp key'
        }
    } else {
        # Refresh incase of future revoke user will recevie warning
        gpg --quiet --keyserver (Get-TerraformConfiguration).PGPKeyServer --recv (Get-TerraformConfiguration).HashiCorpPGPKeyId
    }

    gpg --verify $SHASigPath $SHAPath
    if ($LASTEXITCODE -ne 0) {
        throw "Unable to verify signature on $($SHAPath)"
    }
    if (-not ((Get-TerraformConfiguration).SquelchChecksumWarning) -and ($output | Select-String 'WARNING: This key is not certified' -Quiet)) {
        Write-Warning @'
The HashiCorp key has been installed but not certified. Run either of the following

    - Confirm-TerraformHashiCorpKey
    - Set-TerraformSquelchChecksumWarning $true
'@

    }

    $SHASum = (Get-FileHash $ZipPath).Hash
    $HashiCorpSHASum = (Get-Content $shaPath | Select-String $ArchiveName).ToString().Split()[0]
    if ($SHASum -ne $HashiCorpSHASum ) {
        throw "Unable to verify SHASUM with $($SHAPath)"
    }

    Write-Verbose "Terraform archive $($zipPath) passed checksum test"
    return $true
}
Function Test-TerraformCodeSignature {
    param(
        [parameter(Mandatory)]
        [string]$TFVersion,
        [switch]$SkipCodeSignature
    )
    if ($SkipCodeSignature -or (Get-TerraformConfiguration).SkipCodeSignature) {
        Write-Verbose 'Skipping Code Signature test'
        return $true
    }
    if ($IsWindows) {
        # HashiCorp started signing with version 0.12.24
        # TODO return true and throw a Warning
        $tfThumbprint = (Get-AuthenticodeSignature -FilePath (Get-TerraformPath -TFVersion $TFVersion)).SignerCertificate.Thumbprint
        return $tfthumbprint -eq (Get-TerraformConfiguration).HashiCorpWindowsThumbprint
    }
    if ($IsMacOs) {
        # $tfThumbprint = codesign --verify -d --verbose=2 (Get-TerraformPath -TFVersion $TFVersion) | Select-String TeamIdentifier).ToString().Split('=')[1]
        # return $tfthumbprint -eq (Get-TerraformConfiguration).HashiCorpTeamIdentifier
        codesign --verify -d --verbose=2 (Get-TerraformPath -TFVersion $TFVersion)
        return $LASTEXITCODE -eq 0
    }
    if ($IsLinux) {
        Write-Verbose 'CodeSignature check at runtime is not supported on Linux.'
        return $true
    }
    Write-Error 'Unable to test terraform CodeSignature. Unknown platform.'
    throw $_
}
Function Test-TerraformPath {
    param(
        [parameter(Mandatory)]
        [string]$TFVersion
    )
    Write-Verbose "Testing path for Terraform version $($TFVersion) "
    return Test-Path (Get-TerraformPath -TFVersion $TFVersion) -PathType leaf
}
<#
    .SYNOPSIS
        Helper function to sign the Hashi Corp PHP key.
    .DESCRIPTION
        Helper function to sign the Hashi Corp PHP key.
    .EXAMPLE
        Confirm-TerraformHashicorpKey

        Runs gpg to sign a HasiCorp PGP key.
    .INPUTS
        None. You cannot pipe objects to Confirm-TerraformHashicorpKey.
    .OUTPUTS
        None. Confirm-TerraformHashicorpKey returns nothing.
    .LINK
        Online version: https://github.com/pearcec/Invoke-Terraform
#>

Function Confirm-TerraformHashicorpKey {
    & gpg --sign-key (Get-TerraformConfiguration).HashiCorpPGPKeyId
}
function Get-TerraformConfiguration {
    Import-Configuration
}
<#
    .SYNOPSIS
        Get stable path for terraform binary (ie. terraform.exe or terraform)
    .DESCRIPTION
        Get stable path for terraform binary (ie. terraform.exe or terraform)
    .EXAMPLE
        Get-TerraformStableBinary

        Returns stable path for terraform binary
    .INPUTS
        None. You cannot pipe objects to Set-TerraformStableBinary.
    .OUTPUTS
        Returns a path.
    .LINK
        Set-TerraformStableBinary
    .LINK
        Online version: https://github.com/pearcec/Invoke-Terraform
#>

function Get-TerraformStableBinary {

    $installPath = (Get-TerraformConfiguration).TFPath
    $binary = 'terraform'
    if ($isWindows) {
        $binary += '.exe'
    }
    $binPath = Join-Path -Path $installPath -ChildPath $binary

    if (Test-Path $binPath -PathType leaf ) {
        return $binPath
    }
    Write-Error @"
Terraform static binary not set. Run either:
    - Set-TerraformStableBinary
or:
    - Set-TerraformAutoStableBinary `$true
    - Set-TerraformVersion -TFVersion:[TFversion]
or:
    - Set-TerraformAutoStableBinary `$true
    - Install-Terraform
"@

    throw ''
}
<#
    .SYNOPSIS
        Install a version of terraform.
    .DESCRIPTION
        Install a version of terraform.
    .PARAMETER TFVersion
        The version of terraform to install.
    .PARAMETER SkipChecksum
        Skip release archive checksum verification.
    .PARAMETER SkipCodeSignature
        Skip code signature verifcation.
    .EXAMPLE
        Install-Terraform -TFVersion 0.14.7

        Installs terraform version 0.14.7
    .INPUTS
        None. You cannot pipe objects to Install-Terraform.
    .OUTPUTS
        None. Install-Terraform returns nothing.
    .LINK
        Uninstall-Terraform
    .LINK
        Online version: https://github.com/pearcec/Invoke-Terraform
#>

Function Install-Terraform {
    param(
        [string]$TFVersion,
        [switch]$SkipChecksum = $False,
        [switch]$SkipCodeSignature = $False
    )

    if (-not $TFVersion) {
        $TFVersion = Get-TerraformLatestRelease
    }

    if (Test-TerraformPath -TFVersion $TFVersion) {
        Write-Verbose "Terraform $($TFversion) already installed."
        return
    }
    Write-Verbose "Installing terraform version $($TFVersion)"
    Install-TerraformBinary -TFVersion $TFVersion -SkipChecksum:$SkipChecksum -SkipCodeSignature:$SkipCodeSignature
}


Function Invoke-Terraform {
    <#
    .SYNOPSIS
        Run terraform version based on user preference.
    .DESCRIPTION
        Run terraform version based on user preference.
        Additional parameters are passed to the terraform binary.
    .PARAMETER TFVersion
        Override preferred version of terraform to run.
    .PARAMETER SkipCodeSignature
        Skip code signature verifcation.
    .EXAMPLE
        Invoke-Terraform -TFVersion 0.14.7

        Runs terraform version 0.14.7
    .EXAMPLE
        Invoke-Terraform

        Runs terraform version based on user preference or default preference.
    .INPUTS
        None. You cannot pipe objects to Invoke-Terraform.
    .OUTPUTS
        None. Invoke-Terraform returns nothing.
    .LINK
        Install-Terraform
    .LINK
        Online version: https://github.com/pearcec/Invoke-Terraform
    #>

    param(
        [string]$TFVersion,
        [switch]$SkipCodeSignature = $False
    )

    # HACK:
    #
    # Due to positional parameters the first unnamed parameter
    # is passed to $TFVersion. This catches non version parameters
    # intended to pass to the terraform run.
    if (-not ($TFVersion -match '^0\.\d\d?\.\d\d?$')) {
        # Build $TFargs and null $TFVersion for default preference
        $TFargs = @($TFVersion) + $args
        $TFVersion = $null
    } else {
        $TFArgs = $args
    }

    $terraformVersionFile = Get-TerraformVersion -Path (Get-Item .).FullName
    if ($terraformVersionFile -and (-not $TFVersion)) {
        $TFVersion = Get-Content $terraformVersionFile
        # TODO regex validate the version
        Write-Verbose "Found .terraform-version $TFVersion"
    }

    # If Version still isn't set
    if (-not $TFVersion) {
        $TFVersion = (Get-TerraformConfiguration).TFVersion
    }

    if (-not (Test-TerraformPath -TFVersion $TFVersion)) {
        Write-Warning "Terraform version $($TFVersion) not found."

        if ((Get-TerraformConfiguration).AutoDownload) {
            Write-Verbose "Auto downloading terraform version $($TFVersion)"
            Install-Terraform -TFVersion $TFVersion
        } else {
            Write-Error @"
Terraform version $($TFVersion) not installed. Run either:
    - Install-Terraform -TFVersion $($TFVersion)
or:
    - Set-TerraformAutoDownload `$true
"@

            throw ''
        }
    }

    if (-not (Test-TerraformCodeSignature -TFVersion $TFVersion -SkipCodeSignature:$SkipCodeSignature)) {
        throw 'Unable to confirm Code Signature of terraform binary'
    }

    & (Get-TerraformPath -TFVersion $TFVersion) $TFargs
}

Set-Alias -Name terraform -Value Invoke-Terraform
<#
    .SYNOPSIS
        Set auto download configuration.
    .DESCRIPTION
        Set auto download configuration.
    .PARAMETER AutoDownload
        Either true or false.
    .EXAMPLE
        Set-TerraformAutoDownload $true

        Sets auto download configuration to true
    .INPUTS
        None. You cannot pipe objects to Set-TerraformAutoDownload.
    .OUTPUTS
        None. Set-TerraformAutoDownload returns nothing.
    .LINK
        Get-TerraformConfiguration
    .LINK
        Online version: https://github.com/pearcec/Invoke-Terraform
#>

function Set-TerraformAutoDownload {
    [cmdletbinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    param(
        [parameter(Mandatory)]
        [boolean]$AutoDownload
    )
    begin {
        Write-Debug -Message 'Beginning'
        $configurationPath = Get-ConfigurationPath
    }

    process {
        if ($PSCmdlet.ShouldProcess($configurationPath, "Setting AutoDownload configuration to $($AutoDownload)")) {
            Write-Verbose "Setting AutoDownload configuration to $($AutoDownload)"
            Set-TerraformConfiguration @{ AutoDownload = $AutoDownload } -Confirm:$False
        }
    }
    end {
        Write-Debug -Message 'Ending'
    }
}
<#
    .SYNOPSIS
        Set auto switch binary configuration.
    .DESCRIPTION
        Set auto switch binary configuration.
    .PARAMETER AutoStableBinary
        Either true or false.
    .EXAMPLE
        Set-TerraformAutoStableBinary $true

        Sets auto switch binary configuration to true
    .INPUTS
        None. You cannot pipe objects to Set-TerraformAutoStableBinary.
    .OUTPUTS
        None. Set-TerraformAutoStableBinary returns nothing.
    .LINK
        Get-TerraformConfiguration
    .LINK
        Online version: https://github.com/pearcec/Invoke-Terraform
#>

function Set-TerraformAutoStableBinary {
    [cmdletbinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    param(
        [parameter(Mandatory)]
        [boolean]$AutoStableBinary
    )
    begin {
        Write-Debug -Message 'Beginning'
        $configurationPath = Get-ConfigurationPath
    }

    process {
        if ($PSCmdlet.ShouldProcess($configurationPath, "Setting AutoStableBinary configuration to $($AutoStableBinary)")) {
            Write-Verbose "Setting AutoStableBinary configuration to $($AutoStableBinary)"
            Set-TerraformConfiguration @{ AutoStableBinary = $AutoStableBinary } -Confirm:$False
        }
    }
    end {
        Write-Debug -Message 'Ending'
    }
}
function Set-TerraformConfiguration {
    [cmdletbinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    param(
        [parameter(Mandatory)]
        [hashtable]$Configuration
    )
    begin {
        Write-Debug -Message 'Beginning'
        $configurationPath = Get-ConfigurationPath
    }
    process {
        # Merge existing configuration with updates
        $existingConfiguration = Import-Configuration
        $existingConfiguration.keys | Where-Object {
            $_ -notin $Configuration.keys
        } | ForEach-Object {
            $Configuration.Add($_, $existingConfiguration.Item($_) )
        }

        # Drop keys not defined by default configuration
        $remove = $Configuration.keys | Where-Object {
            $_ -notin $existingConfiguration.keys
        }
        $remove | ForEach-Object {
            $Configuration.Remove($_)
        }

        if ($PSCmdlet.ShouldProcess($configurationPath, "Setting Configuration configuration to $($Configuration | ConvertTo-Json -Depth 5)")) {
            Write-Verbose "Setting configuration to $($Configuration | ConvertTo-Json -Depth 5)"
            $Configuration | Export-Configuration
        }
    }

    end {
        Write-Debug -Message 'Ending'
    }
}
<#
    .SYNOPSIS
        Set squelch checksum warning configuration.
    .DESCRIPTION
        Set squelch checksum warning configuration.
    .PARAMETER SquelchChecksumWarning
        Either true or false.
    .EXAMPLE
        Set-TerraformSquelchChecksumWarning $true

        Set squelch checksum warning configuration to true
    .INPUTS
        None. You cannot pipe objects to Set-TerraformSquelchChecksumWarning.
    .OUTPUTS
        None. Set-TerraformSquelchChecksumWarningreturns nothing.
    .LINK
        Get-TerraformConfiguration
    .LINK
        Online version: https://github.com/pearcec/Invoke-Terraform
#>

function Set-TerraformSquelchChecksumWarning {
    [cmdletbinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    param(
        [parameter(Mandatory)]
        [boolean]$SquelchChecksumWarning
    )
    begin {
        Write-Debug -Message 'Beginning'
        $configurationPath = Get-ConfigurationPath
    }

    process {
        if ($PSCmdlet.ShouldProcess($configurationPath, "Setting SquelchChecksumWarning configuration to $($SquelchChecksumWarning)")) {
            Write-Verbose "Setting SquelchChecksumWarning configuration to $($SquelchChecksumWarning)"
            Set-TerraformConfiguration @{ SquelchChecksumWarning = $SquelchChecksumWarning } -Confirm:$False
        }
    }

    end {
        Write-Debug -Message 'Ending'
    }
}
<#
    .SYNOPSIS
        Set version for stable terraform binary (ie. terraform.exe or terraform)
    .DESCRIPTION
        Set version for stable terraform binary (ie. terraform.exe or terraform)
    .PARAMETER TFVersion
        The preferred version.
    .PARAMETER SkipChecksum
        Skip release archive checksum verification.
    .PARAMETER SkipCodeSignature
        Skip code signature verifcation.
    .EXAMPLE
        Set-TerraformStableBinary

        Sets the latest terraform version to the static name terraform.exe or terraform
    .EXAMPLE
        Set-TerraformStableBinary -TFVersion 0.14.7

        Sets terraform version 0.14.7 to the static name terraform.exe or terraform
    .INPUTS
        None. You cannot pipe objects to Set-TerraformStableBinary.
    .OUTPUTS
        None. Set-TerraformStableBinary returns nothing.
    .LINK
        Get-TerraformStableBinary
    .LINK
        Online version: https://github.com/pearcec/Invoke-Terraform
#>

function Set-TerraformStableBinary {
    [cmdletbinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    param(
        [string]$TFVersion,
        [switch]$SkipChecksum = $False,
        [switch]$SkipCodeSignature = $False
    )

    begin {
        Write-Debug -Message 'Beginning'
        if (-not $TFVersion) {
            $TFVersion = Get-TerraformLatestRelease
        }
    }

    process {
        if ($PSCmdlet.ShouldProcess($configurationPath, "Setting static terraform binary to TFVesion $($TFVersion)")) {
            if (-not (Test-TerraformPath -TFVersion $TFVersion)) {
                Write-Verbose "Installing terraform version $($TFVersion)"
                Install-TerraformBinary -TFVersion $TFVersion -SkipChecksum:$SkipChecksum -SkipCodeSignature:$SkipCodeSignature
            }
            Copy-TerraformBinary -TFVersion $TFVersion
        }
    }

    end {
        Write-Debug -Message 'Ending'
    }
}
<#
    .SYNOPSIS
        Set configuration version for terraform.
    .DESCRIPTION
        Set configuration version for terraform.
    .PARAMETER TFVersion
        The preferred version.
    .EXAMPLE
        Set-TerraformVersion -TFVersion 0.14.7

        Sets configuration version for terraform to 0.14.7
    .INPUTS
        None. You cannot pipe objects to Set-TerraformVersion.
    .OUTPUTS
        None. Set-TerraformVersion returns nothing.
    .LINK
        Get-TerraformConfiguration
    .LINK
        Online version: https://github.com/pearcec/Invoke-Terraform
#>

Function Set-TerraformVersion {
    [cmdletbinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    param(
        [parameter(Mandatory)]
        [string]$TFVersion
    )
    begin {
        Write-Debug -Message 'Beginning'
        $configurationPath = Get-ConfigurationPath
        $AutoStableBinary = (Get-TerraformConfiguration).AutoStableBinary
    }

    process {
        if ($PSCmdlet.ShouldProcess($configurationPath, "Setting TFVesion configuration version to $($TFVersion)")) {
            Write-Verbose "Setting TFVersion configuration version to $($TFVersion)"
            Set-TerraformConfiguration @{ TFVersion = $TfVersion } -Confirm:$False
        }
        if ($AutoStableBinary) {
            Set-TerraformStableBinary -TFVersion $TFVersion -Confirm:$ConfirmPreference
        }
    }

    end {
        Write-Debug -Message 'Ending'
    }
}

Set-Alias -Name Switch-Terraform -Value Set-TerraformVersion
<#
    .SYNOPSIS
        Uninstall a version of terraform.
    .DESCRIPTION
        Unnstall a version of terraform.
    .PARAMETER TFVersion
        The version of terraform to uninstall.
    .EXAMPLE
        Uninstall-Terraform -TFVersion 0.14.7

        Uninstalls terraform version 0.14.7
    .INPUTS
        None. You cannot pipe objects to Uninstall-Terraform.
    .OUTPUTS
        None. Uninstall-Terraform returns nothing.
    .LINK
        Install-Terraform
    .LINK
        Online version: https://github.com/pearcec/Invoke-Terraform
#>

Function Uninstall-Terraform {
    param(
        [parameter(Mandatory)]
        [string]$TFVersion
    )

    if (Test-TerraformPath -TFVersion $TFVersion) {
        Write-Verbose "Uninstalling terraform version $($TFVersion)"
        Remove-Item (Get-TerraformPath -TFVersion $TFVersion) -Force
    } else {
        Write-Warning "Unable to uninstall terraform. Version ($TFVersion) not found."
    }
}
$PSDefaultParameterValues = @{
    'Invoke-WebRequest:Verbose' = $false
    'Invoke-WebRequest:Debug'   = $false
}

$ProgressPreference = 'SilentlyContinue'