WTerraform.psm1
$Script:Path = Join-Path -Path $env:LOCALAPPDATA -ChildPath "WTerraform" 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 Downloads the specified Terraform Version if not present .DESCRIPTION Downloads and extracts release from hashicorp. #> function Install-WTerraform { [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateScript( { $_ -match "^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$" })] [String]$Version, [Parameter(Mandatory)] [ValidateSet("windows")] [String]$OS, [Parameter(Mandatory)] [ValidateSet("amd64", "386")] [String]$Architecture ) begin { $baseUri = "https://releases.hashicorp.com/terraform" $OS = $OS.ToLower() $Architecture = $Architecture.ToLower() if (-not (Test-Path -Path $Script:Path)) { New-Item -Path $script:Path -ItemType Directory } } process { $terraformFullVersion = "terraform_$($Version)_$($OS)_$($Architecture)" $versionPath = Join-Path -Path $Script:Path -ChildPath $terraformFullVersion $exePath = Join-Path -Path $versionPath -ChildPath "terraform.exe" if (Test-Path -LiteralPath $exePath) { Write-Verbose "$terraformFullVersion already present in $exePath" } else { $zipPath = Join-Path -Path $Script:Path -ChildPath "$terraformFullVersion.zip" Invoke-WebRequest -Uri "$baseUri/$Version/$terraformFullVersion.zip" -OutFile $zipPath Expand-Archive -Path $zipPath -DestinationPath $versionPath } } end { Remove-Item -Path (Join-Path -Path $Script:Path -ChildPath "*.zip") } } <# .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-WTerraformVersion." } } <# .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 .PARAMETER Global Set the Version globally (in userPath) instead of local 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, [switch]$Global ) 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 { Install-WTerraform -Version $Version -OS "windows" -Architecture "amd64" if ($Global.IsPresent) { $regex = $cachePath $regex = [regex]::Escape($regex) $regex = $regex + "\\(terraform_\d+\.\d+\.\d+_\w+_\w+);?" $versionPath = $cachePath | Join-Path -ChildPath $terraformFullVersion $path = [System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User) if ($path -match $regex) { Write-Warning "Set Terraform Version from $($matches[1]) to $terraformFullVersion globally" $path = $path -replace $regex, "" } $path = $path + ";" + $versionPath [System.Environment]::SetEnvironmentVariable("Path", $path, [System.EnvironmentVariableTarget]::User) } else { $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 } } } } |