From 14978be7b68a6bce26f07cf49c76b1d897971725 Mon Sep 17 00:00:00 2001 From: James Williams Date: Mon, 20 Nov 2023 14:50:50 +0000 Subject: [PATCH 1/4] . --- README.md | 12 +++++- src/Confirm-TFVars/Confirm-TFVars.psd1 | 6 +-- src/Confirm-TFVars/Confirm-TFVars.psm1 | 60 +++++++++++++++++++++----- 3 files changed, 62 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 573d245..37ec3b3 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # Confirm-TFVars -![PublishStatus](https://github.com/jamesw4/Confirm-TFVars/actions/workflows/publish.yml/badge.svg) - A cross platform PowerShell module to validate tfvars files based on variable definition and validation rules. +| GitHub Actions | PSGallery | Latest Version | +|:---------------------------------------------------:|:-------------------------------------------------------:|:-------------------------------:| +| [![PublishStatus][publish-badge]][publish-pipeline] | [![PowerShell Gallery][psgallery-badge]][psgallery-url] | ![GitHubTag][version-tag-badge] + ## Why? Working with terraform on a daily basis, for most of the projects I work on terraform plan and apply are ran via CICD pipeline, and access to the state backend restricted. My typical workflow is to run `terraform validate` to confirm syntax before committing any code. It's always bugged me there is no out of the box dedicated solution to also validate content of tfvars files against the variable definitions and validation rules. This can result in committing code and waiting for a CICD pipeline to throw an error before you know anything is wrong. @@ -55,3 +57,9 @@ The output mirrors native terraform output, any errors are passed directly from ### Failure Example ![Failure Example Image](Screenshots/Failure.png) + +[publish-badge]: https://img.shields.io/github/actions/workflow/status/jamesw4/confirm-tfvars/publish.yml?logo=github&label=Publish +[publish-pipeline]: https://github.com/jamesw4/Confirm-TFVars/actions/workflows/publish.yml +[psgallery-badge]: https://img.shields.io/powershellgallery/dt/Confirm-TFVars?label=Downloads&logo=powershell&color=0a7bbc +[psgallery-url]: https://www.powershellgallery.com/packages/Confirm-TFVars +[version-tag-badge]: https://img.shields.io/github/v/tag/jamesw4/Confirm-TFVars?label=Version&logo=task diff --git a/src/Confirm-TFVars/Confirm-TFVars.psd1 b/src/Confirm-TFVars/Confirm-TFVars.psd1 index e9f4445..1e78fb3 100644 --- a/src/Confirm-TFVars/Confirm-TFVars.psd1 +++ b/src/Confirm-TFVars/Confirm-TFVars.psd1 @@ -15,7 +15,7 @@ ModuleVersion = '0.0.3' # Supported PSEditions - # CompatiblePSEditions = @() + # = @() # ID used to uniquely identify this module GUID = '464d215b-5187-4504-b146-d6246c8debfb' @@ -30,7 +30,7 @@ Copyright = '(c) James.Williams. All rights reserved.' # Description of the functionality provided by this module - Description = 'Uses terraform console to validate tfvars files against variable definition.' + Description = 'A cross platform PowerShell module to validate tfvars files based on variable definition and validation rules.e definition and validation rules.' # Minimum version of the PowerShell engine required by this module # PowerShellVersion = '' @@ -95,7 +95,7 @@ PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. - Tags = @('Terraform', 'TFVars') + Tags = @('Terraform', 'TFVars', 'Windows', 'Linux', 'PSEdition_Desktop', 'PSEdition_Core') # A URL to the license for this module. # LicenseUri = '' diff --git a/src/Confirm-TFVars/Confirm-TFVars.psm1 b/src/Confirm-TFVars/Confirm-TFVars.psm1 index c318e71..a925b62 100644 --- a/src/Confirm-TFVars/Confirm-TFVars.psm1 +++ b/src/Confirm-TFVars/Confirm-TFVars.psm1 @@ -1,3 +1,41 @@ +function Confirm-TF { + <# + .SYNOPSIS + Runs 'terraform validate' and 'confirm-tfvars' in sequence. + .DESCRIPTION + Runs 'terraform validate' and 'confirm-tfvars' in sequence. + .LINK + https://github.com/jamesw4/confirm-tfvars + .INPUTS + None + .OUTPUTS + None + #> + + [cmdletbinding()] + param() + + If (-not(Get-Command("terraform") -ErrorAction SilentlyContinue)) { + $PSCmdlet.ThrowTerminatingError((New-Object System.Management.Automation.ErrorRecord "Terraform CLI is required, but could not be found.", "", ([System.Management.Automation.ErrorCategory]::NotSpecified), "")) + } + + $errorCount = 0 + + terraform validate + if ($? -eq $false) { + $errorCount++ + } + + Confirm-TFVars + if ($? -eq $false) { + $errorCount++ + } + + If ($errorCount -gt 0) { + $PSCmdlet.ThrowTerminatingError((New-Object System.Management.Automation.ErrorRecord "Overall validation failed.", "", ([System.Management.Automation.ErrorCategory]::NotSpecified), "")) + } +} + function Confirm-TFVars { <# .SYNOPSIS @@ -25,6 +63,7 @@ function Confirm-TFVars { Attempts validation using vars.tf as the defintion and validates dev.tfvars in current directory. #> + [cmdletbinding()] param ( [string]$VarFile = "*.tfvars", [string]$VariableDefinitionFile = "variables.tf" @@ -35,23 +74,19 @@ function Confirm-TFVars { $tfvars = Get-ChildItem $VarFile -ErrorAction SilentlyContinue If (-not(Get-Command("terraform") -ErrorAction SilentlyContinue)) { - Write-Error "Terraform CLI is required, but could not be found." - return + $PSCmdlet.ThrowTerminatingError((New-Object System.Management.Automation.ErrorRecord "Terraform CLI is required, but could not be found.", "", ([System.Management.Automation.ErrorCategory]::NotSpecified), "")) } If ($(Get-ChildItem *.tf).count -eq 0) { - Write-Error "No terraform files found in current directory, rerun from a directory containing terraform configuration." - return + $PSCmdlet.ThrowTerminatingError((New-Object System.Management.Automation.ErrorRecord "No terraform files found in current directory, rerun from a directory containing terraform configuration.", "", ([System.Management.Automation.ErrorCategory]::NotSpecified), "")) } If (-not(Test-Path $VariableDefinitionFile)) { - Write-Error "Variable definition file ""$VariableDefinitionFile"" could not be found." - return + $PSCmdlet.ThrowTerminatingError((New-Object System.Management.Automation.ErrorRecord "Variable definition file ""$VariableDefinitionFile"" could not be found.", "", ([System.Management.Automation.ErrorCategory]::NotSpecified), "")) } If ($($tfvars).count -eq 0) { - Write-Error "No vars files found matching name ""$varfile""." - return + $PSCmdlet.ThrowTerminatingError((New-Object System.Management.Automation.ErrorRecord "No vars files found matching name ""$varfile"".", "", ([System.Management.Automation.ErrorCategory]::NotSpecified), "")) } # Copy variable defintion to a temp folder so we can target it in isolation @@ -65,11 +100,11 @@ function Confirm-TFVars { # Loop through the tfvars and validate foreach ($tfvar in $tfvars) { - $result = "exit" | terraform -chdir="$Folder" console --var-file=$tfvar 2>&1 - If ($null -ne $result) { + $result = """exit""" | terraform -chdir="$Folder" console --var-file=$tfvar 2>&1 + $resultErrors = $result | Where-Object { $($_.GetType()).name -eq "ErrorRecord" } + If ($null -ne $resultErrors) { $filename = $tfvar.name Write-Error "Validation of $filename failed." - $result | Where-Object { $($_.GetType()).name -eq "ErrorRecord" } $errorCount++ } } @@ -77,6 +112,9 @@ function Confirm-TFVars { If ($errorCount -eq 0) { Write-Host "Success!" -ForegroundColor Green -NoNewline; Write-Host " The variables are valid." } + else { + $PSCmdlet.ThrowTerminatingError((New-Object System.Management.Automation.ErrorRecord "One or more variable validation errors occured.", "", ([System.Management.Automation.ErrorCategory]::NotSpecified), "")) + } # Tidy up Remove-Item $Folder -Recurse From 0131cd59d0b465973aabc4fe348d8506064a2085 Mon Sep 17 00:00:00 2001 From: James Williams Date: Mon, 20 Nov 2023 14:51:54 +0000 Subject: [PATCH 2/4] . --- src/Confirm-TFVars/Confirm-TFVars.psd1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Confirm-TFVars/Confirm-TFVars.psd1 b/src/Confirm-TFVars/Confirm-TFVars.psd1 index 1e78fb3..e90ed58 100644 --- a/src/Confirm-TFVars/Confirm-TFVars.psd1 +++ b/src/Confirm-TFVars/Confirm-TFVars.psd1 @@ -12,7 +12,7 @@ RootModule = 'Confirm-TFVars.psm1' # Version number of this module. - ModuleVersion = '0.0.3' + ModuleVersion = '0.0.4' # Supported PSEditions # = @() @@ -69,7 +69,7 @@ # NestedModules = @() # 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-TFVars' + FunctionsToExport = 'Confirm-TFVars', 'Confirm-TF' # Cmdlets 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 cmdlets to export. CmdletsToExport = @() From 867666cdcd45904dc3a4f45ab12ccf3a92ab8498 Mon Sep 17 00:00:00 2001 From: James Williams Date: Mon, 20 Nov 2023 14:52:49 +0000 Subject: [PATCH 3/4] . --- src/Confirm-TFVars/Confirm-TFVars.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Confirm-TFVars/Confirm-TFVars.psd1 b/src/Confirm-TFVars/Confirm-TFVars.psd1 index e90ed58..7e79ad8 100644 --- a/src/Confirm-TFVars/Confirm-TFVars.psd1 +++ b/src/Confirm-TFVars/Confirm-TFVars.psd1 @@ -15,7 +15,7 @@ ModuleVersion = '0.0.4' # Supported PSEditions - # = @() + # CompatiblePSEditions = @() # ID used to uniquely identify this module GUID = '464d215b-5187-4504-b146-d6246c8debfb' From 352208547724e5013337f31b9cd475ea8dc786d0 Mon Sep 17 00:00:00 2001 From: James Williams Date: Mon, 20 Nov 2023 14:57:53 +0000 Subject: [PATCH 4/4] . --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 37ec3b3..7cd494a 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,13 @@ Full native PowerShell help is available in the module via `Get-Help`. Get-Help Confirm-TFVars -Full ``` +The following two Cmdlets are included in the module: + +| Cmdlet | Description | +|----------------------------------------|-------------------------------------------------------------------------------------------------------| +| Confirm-TFVars | The main functionality used to validate tfvars files. +| Confirm-TF | Runs `terraform validate` and `confirm-tfvars` in sequence and confirms overall validation of the two. + ## What to expect The output mirrors native terraform output, any errors are passed directly from terraform to the console.