Skip to content

Commit

Permalink
Provide a binary without a version reference in the filename #13 (#15) (
Browse files Browse the repository at this point in the history
#16)

* Provide a binary without a version reference in the filename #13 (#15)

* Fixes #13
- Provide a binary without a version reference in the filename
- Set TFVersion on Copy-TerraformBinary (was pulling from Global scope and working somehow.)
- Modified Copy-TerraformBinary to support copying existing versioned installations to static installation.
- Refactor private function Copy-TerraformBinary to optionally use a ZipPath other defaults to stable path
- Renamed Get-TerraformZip to use Get-TerraformBinary in public namespace
- Add switch for automatically switch stable path with Set-TerraformVersion is invokved
- Tests

* Add CHANGELOG.md for issue #13
  • Loading branch information
pearcec authored Apr 25, 2021
1 parent 22982bc commit e093e1e
Show file tree
Hide file tree
Showing 23 changed files with 854 additions and 45 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed

- `Invoke-Terraform` recursively searches up for `.terraform-version` stopping at root ([#12](https://github.com/pearcec/Invoke-Terraform/issues/12))
- Provide a binary without a version reference in the filename ([#13](https://github.com/pearcec/Invoke-Terraform/issues/13))

## [0.4.0]

Expand Down
3 changes: 2 additions & 1 deletion Invoke-Terraform/Configuration.psd1
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
@{
TFPath = Join-Path -Path $PSScriptRoot -ChildPath '..' -AdditionalChildPath 'bin'
TFVersion = '0.14.7'
TFVersion = '0.15.0'
ReleaseUrl = 'https://releases.hashicorp.com/terraform'
AutoDownload = $false
AutoStableBinary = $false

HashiCorpPGPThumbprint = '91A6E7F85D05C65630BEF18951852D87348FFC4C'
HashiCorpPGPKeyId = '0x51852D87348FFC4C'
Expand Down
3 changes: 3 additions & 0 deletions Invoke-Terraform/Invoke-Terraform.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,13 @@
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @(
'Confirm-TerraformHashicorpKey'
'Get-TerraformStableBinary'
'Get-TerraformConfiguration'
'Install-Terraform'
'Invoke-Terraform'
'Set-TerraformAutoDownload'
'Set-TerraformAutoStableBinary'
'Set-TerraformStableBinary'
'Set-TerraformConfiguration'
'Set-TerraformSquelchChecksumWarning'
'Set-TerraformVersion'
Expand Down
22 changes: 15 additions & 7 deletions Invoke-Terraform/Private/Copy-TerraformBinary.ps1
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
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"
Expand All @@ -16,19 +16,27 @@ Function Copy-TerraformBinary {
if ($isWindows) {
$binary += '.exe'
}

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

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

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

Expand-Archive -Path $zipPath -DestinationPath $tmpFolder
Copy-Item -Path $tmpfolder/$binary -Destination $destPath -Force
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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Function Get-TerraformBinary {
Function Get-TerraformZip {
param(
[parameter(Mandatory)]
[string]$TFVersion,
Expand Down
4 changes: 2 additions & 2 deletions Invoke-Terraform/Private/Install-TerraformBinary.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ Function Install-TerraformBinary {
[switch]$SkipCodeSignature = $False
)

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

try {
Copy-TerraformBinary -ZipPath $zipPath
Copy-TerraformBinary -TFVersion $TFVersion -ZipPath $zipPath
} catch {
Write-Error "Unable to copy binary from $zipPath."
throw $_
Expand Down
42 changes: 42 additions & 0 deletions Invoke-Terraform/Public/Get-TerraformStableBinary.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<#
.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 ''
}
4 changes: 2 additions & 2 deletions Invoke-Terraform/Public/Invoke-Terraform.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ Function Invoke-Terraform {
Install-Terraform -TFVersion $TFVersion
} else {
Write-Error @"
Terraform version $($TFVersion) not installed. Run either
Terraform version $($TFVersion) not installed. Run either:
- Install-Terraform -TFVersion $($TFVersion)
or:
- Set-TerraformAutoDownload `$true
"@
throw ''
Expand Down
41 changes: 41 additions & 0 deletions Invoke-Terraform/Public/Set-TerraformAutoStableBinary.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<#
.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'
}
}
57 changes: 57 additions & 0 deletions Invoke-Terraform/Public/Set-TerraformStableBinary.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<#
.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'
}
}
4 changes: 4 additions & 0 deletions Invoke-Terraform/Public/Set-TerraformVersion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ Function Set-TerraformVersion {
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 {
Expand Down
88 changes: 59 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

A PowerShell module to run terraform.

| GitHub Actions | PSGallery | License |
|----------------|-----------|---------|
[![GitHub Actions Status][github-actions-badge]][github-actions-build] | [![PowerShell Gallery][psgallery-badge]][psgallery] | [![License][license-badge]][license]
| GitHub Actions | PSGallery | License |
| ---------------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------ |
| [![GitHub Actions Status][github-actions-badge]][github-actions-build] | [![PowerShell Gallery][psgallery-badge]][psgallery] | [![License][license-badge]][license] |

## Overview

Expand All @@ -31,25 +31,32 @@ terraform -TFVersion 0.14.8 -version
```

## Commands
| Command | Description |
|---------|-------------|
Confirm-TerraformHashicorpKey | Confirm the HashiCorp Security Key in gpg.
Get-TerraformPreference | List user preferences.
Install-Terraform | Install a version of terraform.
Invoke-Terraform | Run terraform.
Set-TerraformPreference | Set Invoke-Terraform user preferences.
Switch-Terraform | Change default version of terraform to invoke.
Uninstall-Terraform | Uninstall a version of terraform.
terraform | Invoke-Terraform alias.
| Command | Description |
| ----------------------------------- | ------------------------------------------------------------------------------------------ |
| Confirm-TerraformHashicorpKey | Confirm the HashiCorp Security Key in gpg. |
| Get-TerraformConfiguration | Get Invoke-Terraform configurations. |
| Get-TerraformStableBinary | Get the path for the current static installation of terraform binary. |
| Install-Terraform | Install a version of terraform. |
| Invoke-Terraform | Run terraform. |
| Set-TerraformAutoDownload | Set Invoke-Terraform to automatically download terraform if needed. |
| Set-TerraformAutoStableBinary | Set Set-TerraformVersion to automatically switch static installation of terraform binary. |
| Set-TerraformConfiguration | Set Invoke-Terraform configurations. |
| Set-TerraformStableBinary | Set version of static installation of terraform binary. |
| Set-TerraformSquelchChecksumWarning | Squelch checksum warnings. |
| Set-TerraformVersion | Change default version of terraform to invoke. |
| Switch-Terraform | Set-TerraformVersion alias. |
| Uninstall-Terraform | Uninstall a version of terraform. |
| terraform | Invoke-Terraform alias. |

## User Preferences

| Name | Description |
|------|-------------|
Path | Installation location for terraform binaries. Defaults to $HOME\bin.
TFVersion | Preferred version of terraform.
ReleaseUrl | Defaults to https://releases.hashicorp.com/terraform
AutoDownload | Automatically download terraform when invoking if the binary is not installed. Defaults to false.
| Name | Description |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Path | Installation location for terraform binaries. Defaults to $HOME\bin. |
| TFVersion | Preferred version of terraform. |
| ReleaseUrl | Defaults to https://releases.hashicorp.com/terraform |
| AutoDownload | Automatically download terraform when invoking if the binary is not installed. Defaults to false. |
| AutoStableBinary | Automatically switch the static binary to the TFVersion called with Set-TerraformVersion (ie Switch-Terraform). Defaults to false. |

## Verification

Expand All @@ -58,21 +65,44 @@ HashiCorp provides a few methods of [verification](https://www.hashicorp.com/sec
The default behavior is to always run code signature verification every time terraform is run when supported and checksums when binaries are installed. By default HashiCorp PGP Key is import from keyserver.ubuntu.com. The following additional preferences may be used to validate the signatures provide by this module, and adjust the settings according to your
security tolerance:

| Name | Description |
|------|-------------|
HashiCorpPGPThumbprint | 91A6E7F85D05C65630BEF18951852D87348FFC4C
HashiCorpPGPKeyId | 0x51852D87348FFC4C
HashiCorpTeamIdentifier | D38WU7D763
HashiCorpWindowsThumbprint | 35AB9FC834D217E9E7B1778FB1B97AF7C73792F2
PGPKeyServer | keyserver.ubuntu.com
SquelchChecksumWarning | Turn off warning from gpg when HashiCorp imported key has not be signed. Defaults to false.
SkipChecksum | Turn off release archive checksum verification via gpg. Defaults to false.
SkipCodeSignature | Turn off code signature verification. Defaults to false.
| Name | Description |
| -------------------------- | ------------------------------------------------------------------------------------------- |
| HashiCorpPGPThumbprint | 91A6E7F85D05C65630BEF18951852D87348FFC4C |
| HashiCorpPGPKeyId | 0x51852D87348FFC4C |
| HashiCorpTeamIdentifier | D38WU7D763 |
| HashiCorpWindowsThumbprint | 35AB9FC834D217E9E7B1778FB1B97AF7C73792F2 |
| PGPKeyServer | keyserver.ubuntu.com |
| SquelchChecksumWarning | Turn off warning from gpg when HashiCorp imported key has not be signed. Defaults to false. |
| SkipChecksum | Turn off release archive checksum verification via gpg. Defaults to false. |
| SkipCodeSignature | Turn off code signature verification. Defaults to false. |

## Other behavior

By default *Invoke-Terraform* searches the current working directory for the file `.terraform-version`. This file contains the preferred version of terraform. Store this file with your terraform project to seamlessly invoke the required version of terraform.

## Best Practice

### $ENV:Path, $PATH

It is recommended the `terraform` binary be removed from `$ENV:Path`. Even though the powershell alias overrides what is available in the `Path`, unexpected usage could occur if this module was not loaded. This eliminates the chance of running an unplanned version.

### VSCode

If terraform is removed from your path as recommended, the [vscode-terraform](https://github.com/hashicorp/vscode-terraform) extension breaks. The `Set-TerraformStableBinary` has been added to provide a stable path name. Run `Get-TerraformStableBinary` to retrieve the path. Use the following example for vscode settings:

```json
"terraform.languageServer": {
"external": true,
"pathToBinary": "",
"args": [
"serve",
"-tf-exec=C:/users/pearcec/Documents/PowerShell/Modules/Invoke-Terraform/bin/terraform.exe",
],
"maxNumberOfProblems": 100,
"trace.server": "off"
}
```

[github-actions-badge]: https://github.com/pearcec/Invoke-Terraform/workflows/CI/badge.svg
[github-actions-build]: https://github.com/pearcec/Invoke-Terraform/actions
[psgallery-badge]: https://img.shields.io/powershellgallery/dt/invoke-terraform.svg
Expand Down
Loading

0 comments on commit e093e1e

Please sign in to comment.