Skip to content

Commit

Permalink
Feature/improvements (#3)
Browse files Browse the repository at this point in the history
Correctly set $? to reflect false when validation has failed.
Added new Cmdlet to chain terraform validate and confirm-tfvars.
  • Loading branch information
jamesw4 authored Nov 20, 2023
1 parent 1bc3263 commit 784afbb
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 17 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -44,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.
Expand All @@ -55,3 +64,9 @@ The output mirrors native terraform output, any errors are passed directly from
### <u>Failure Example</u>

![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
8 changes: 4 additions & 4 deletions src/Confirm-TFVars/Confirm-TFVars.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
RootModule = 'Confirm-TFVars.psm1'

# Version number of this module.
ModuleVersion = '0.0.3'
ModuleVersion = '0.0.4'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand All @@ -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 = ''
Expand Down Expand Up @@ -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 = @()
Expand All @@ -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 = ''
Expand Down
60 changes: 49 additions & 11 deletions src/Confirm-TFVars/Confirm-TFVars.psm1
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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"
Expand All @@ -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
Expand All @@ -65,18 +100,21 @@ 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++
}
}

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
Expand Down

0 comments on commit 784afbb

Please sign in to comment.