param( [string]$TemplatePath = 'D:\project\deployment\alertmanager\alertmanager.yml', [string]$OutputPath, [string]$EnvFilePath = '' ) $ErrorActionPreference = 'Stop' if ([string]::IsNullOrWhiteSpace($OutputPath)) { throw 'OutputPath is required' } if (-not (Test-Path $TemplatePath)) { throw "template not found: $TemplatePath" } if (-not [string]::IsNullOrWhiteSpace($EnvFilePath)) { if (-not (Test-Path $EnvFilePath)) { throw "env file not found: $EnvFilePath" } Get-Content $EnvFilePath -Encoding UTF8 | ForEach-Object { $line = $_.Trim() if ($line -eq '' -or $line.StartsWith('#')) { return } $parts = $line -split '=', 2 if ($parts.Count -ne 2) { throw "invalid env line: $line" } [Environment]::SetEnvironmentVariable($parts[0].Trim(), $parts[1].Trim(), 'Process') } } $content = Get-Content $TemplatePath -Raw -Encoding UTF8 $matches = [regex]::Matches($content, '\$\{(?[A-Z0-9_]+)\}') $variables = @($matches | ForEach-Object { $_.Groups['name'].Value } | Sort-Object -Unique) $missing = @() foreach ($name in $variables) { $value = [Environment]::GetEnvironmentVariable($name, 'Process') if ([string]::IsNullOrWhiteSpace($value)) { $missing += $name continue } $escapedToken = [regex]::Escape('${' + $name + '}') $escapedValue = $value -replace '\\', '\\' $content = [regex]::Replace($content, $escapedToken, [System.Text.RegularExpressions.MatchEvaluator]{ param($m) $value }) } if ($missing.Count -gt 0) { throw "missing required alertmanager environment variables: $($missing -join ', ')" } if ($content -match '\$\{[A-Z0-9_]+\}') { throw 'rendered alertmanager config still contains unresolved placeholders' } $outputDir = Split-Path $OutputPath -Parent if (-not [string]::IsNullOrWhiteSpace($outputDir)) { New-Item -ItemType Directory -Force $outputDir | Out-Null } Set-Content -Path $OutputPath -Value $content -Encoding UTF8 Get-Content $OutputPath