WTerraform.psm1

New-Alias -Name terraform -Value Invoke-WTerraform
<#
.SYNOPSIS
Get the TerraformVersion saved for current Location
.DESCRIPTION
Convert the crrent Path to ProviderPath and look up the version.
#>

function Get-WTerraformVersion {
    [CmdletBinding()]
    param ()

    begin {
        $currentPath = Convert-Path -Path $PWD
    }

    process {
        $versionMap = Get-WTerraformVersionMap
        return $versionMap."$currentPath"
    }
}
<#
.SYNOPSIS
Load the VersionMap of Folders to Terraform Versions
.DESCRIPTION
Returns Empty if no VersionMap Found
#>

function Get-WTerraformVersionMap {
    [CmdletBinding()]
    param (

    )

    begin {
        $versionMap = @{}
        $cachePath = Join-Path -Path $env:LOCALAPPDATA -ChildPath "WTerraform"
        $versionMapPath = Join-Path -Path $cachePath -ChildPath "versionmap.json"
    }

    process {
        if (Test-Path $versionMapPath) {
            $versionMap = Get-Content -LiteralPath $versionMapPath | ConvertFrom-Json
        }
    }

    end {
        return $versionMap
    }
}
<#
.SYNOPSIS
Wrapper for terraform
.DESCRIPTION
Runs terraform in version specified by Set-WTerraformVersion.
Parameters are just forwarded to terraform
.Example
Invoke-WTerraform -version
Throws error if no Terraform Version was specified earlier. Otherwise runs command 'terraform -version'
#>

function Invoke-WTerraform {
    $version = Get-WTerraformVersion
    if ($version) {
        $path = Join-Path -Path $env:LOCALAPPDATA -ChildPath "WTerraform" | Join-Path -ChildPath $version | Join-Path -ChildPath "terraform.exe"
        if (Test-Path -LiteralPath $path) {
            & $path $args
        } else {
            #TODO: Redownload terraform
            throw "$version is not found"
        }

    } else {
        throw "No Version for $pwd specified. Please Run Set-WTerraformVerstion."
    }
}
<#
.SYNOPSIS
Specify the Terraform Version to use in this folder.
.DESCRIPTION
Checks if specified Version is already present. If not download from Terraform. Also saves the Version for this folder so Invoke-WTerraform will use this Version.
.PARAMETER Version
Version of Terraform to use in this folder
.EXAMPLE
Set-WTerraformVersion -Version 0.14.4
Downloads Terraform Version 0.14.0 if not present and saves the specified version for later use with Invoke-WTerraform
#>

function Set-WTerraformVersion {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [String]$Version
    )

    begin {
        $baseUri = "https://releases.hashicorp.com/terraform"
        $cachePath = Join-Path -Path $env:LOCALAPPDATA -ChildPath "WTerraform"
        $versionMapPath = Join-Path -Path $cachePath -ChildPath "versionmap.json"
        $currentPath = Convert-Path $pwd.Path
        if (-not (Test-Path -LiteralPath $cachePath)) {
            New-Item -Path $cachePath -ItemType Directory
        }
        $terraformFullVersion = "terraform_$($Version)_windows_amd64"
    }

    process {
        $cacheVersionRootPath = Join-Path -Path $cachePath -ChildPath "$terraformFullVersion"
        $cacheVersionTerraformPath = Join-Path -Path $cacheVersionRootPath -ChildPath "terraform.exe"
        $cacheVersionZipPath = Join-Path -Path $cachePath -ChildPath "$terraformFullVersion.zip"
        if (Test-Path -LiteralPath $cacheVersionTerraformPath) {
            Write-Verbose "Terraform $terraformFullVersion already present"
        } else {
            Invoke-WebRequest -Uri "$baseUri/$Version/$terraformFullVersion.zip" -OutFile $cacheVersionZipPath
            Expand-Archive -Path $cacheVersionZipPath -DestinationPath $cacheVersionRootPath
            Remove-Item -Path $cacheVersionZipPath
        }

        $versionMap = Get-WTerraformVersionMap
        $oldVersion = Get-WTerraformversion
        $versionChange = $false
        if ($oldVersion -eq $terraformFullVersion) {
            Write-Verbose "Terraform Version for $currentPath is already $oldVersion"
        } elseif ($oldVersion -and $oldVersion -ne $terraformFullVersion) {
            Write-Warning "Set Terraform Version from $oldVersion to $terraformFullVersion for $currentPath"
            $versionMap."$currentPath" = $terraformFullVersion
            $versionChange = $true
        } else {
            Write-Verbose "Set Terraform Version to $terraformFullVersion for $currentPath"
            Add-Member -InputObject $versionMap -MemberType NoteProperty -Name $currentPath -Value $terraformFullVersion
            $versionChange = $true
        }

        if ($true -eq $versionChange) {
            Set-Content -Value ($versionMap | ConvertTo-Json) -LiteralPath $versionMapPath
        }
    }
}