Skip to content

Instantly share code, notes, and snippets.

@rleap-m
Created December 5, 2025 16:07
Show Gist options
  • Select an option

  • Save rleap-m/9caa1fee121a3349f26d0f5a770aec5e to your computer and use it in GitHub Desktop.

Select an option

Save rleap-m/9caa1fee121a3349f26d0f5a770aec5e to your computer and use it in GitHub Desktop.
Utility script to create a Terraform working directory from a repository
<#
.SYNOPSIS
Utility script to create a Terraform working directory from a repository
.EXAMPLE
Copy-QaInfra.ps1 -VariablePath ./mke_412_rc1 -DestinationPath ./mke_412_ga -Verbose
#>
[CmdletBinding()]
param (
# Path to the items to copy
[ValidateScript({Test-Path $_ -PathType Container})]
[Parameter(mandatory=$false)]
[string]
$RepoPath = '/mnt/c/Users/rleap/Documents/gitrepo/qa-infra',
# Files to includes in the operation (qualifies the Path parameter)
[Parameter(mandatory=$false)]
[string[]]
$FileTypeToInclude = @('*.tf','*.json','*.yaml','*.tpl','*.tmpl','*.tftpl','*.sh','*.ps1','*.psm1','*.psd1','*.py','*.js','*.md','*.toml','*.cfg','*.example'),
# Add any bare filenames (no extension) you want copied
[Parameter(mandatory=$false)]
[string[]]
$BareNamesToInclude = @('Makefile','MAKEFILE'),
# Directories to exclude from the operation (qualifies the Path parameter)
[Parameter(mandatory=$false)]
[string[]]
$DirToExclude = @('.git','.terraform','ssh_keys','img','images'),
# Path to Terraform variable definition files specific to the configuration
[ValidateScript({Test-Path $_ -PathType Container})]
[Parameter(mandatory=$true)]
[string]
$VariablePath,
# Path to the working directory
[Parameter(mandatory=$true)]
[string]
$DestinationPath
)
function Copy-ViaRsync {
[CmdletBinding(SupportsShouldProcess = $true)]
param(
[Parameter(Mandatory)]
[string]$Path,
[Parameter(Mandatory)]
[string]$Destination,
[string[]]$Include = @(),
[string[]]$Exclude = @(),
[switch]$Recurse, # kept for compatibility
[switch]$Force # kept for compatibility
)
if (-not (Test-Path -LiteralPath $Destination -PathType Container)) {
$null = New-Item -ItemType Directory -Path $Destination -Force
}
$rsync = '/usr/bin/rsync'
if (-not (Test-Path -LiteralPath $rsync)) { $rsync = 'rsync' }
$src = ($Path.TrimEnd('/')) + '/'
$dst = ($Destination.TrimEnd('/')) + '/'
# Use a non-reserved name instead of $args
[string[]]$rsyncArgs = @('-a','-m') # archive + prune empty dirs
if ($VerbosePreference -eq 'Continue') {
$rsyncArgs += @('-v','--itemize-changes','--info=NAME')
}
$rsyncArgs += '--include=*/'
foreach ($p in $Include) { if ($p) { $rsyncArgs += "--include=$p" } }
foreach ($d in $Exclude) { if ($d) { $rsyncArgs += "--exclude=/$d/**" } }
$rsyncArgs += '--exclude=*'
$rsyncArgs += @($src, $dst)
if ($PSCmdlet.ShouldProcess("$src -> $dst", "rsync $($rsyncArgs -join ' ')")) {
& $rsync @rsyncArgs
if ($LASTEXITCODE -ne 0) { throw "rsync exited with code $LASTEXITCODE" }
}
}
if (-not(Test-Path -Path $DestinationPath -PathType Container)) {
$null = New-Item -Path $DestinationPath -ItemType Directory -ErrorAction Stop
}
$includes = @($FileTypeToInclude + $BareNamesToInclude)
Copy-ViaRsync -Path $RepoPath -Destination $DestinationPath -Include $includes -Exclude $DirToExclude -Recurse -Force
Copy-Item -Path (Join-Path -Path $VariablePath -ChildPath '*.tfvars') -Destination $DestinationPath -PassThru
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment