🔧 Add bootstrap script for Azure state management
This commit is contained in:
78
scripts/bootstrap-az-state.ps1
Normal file
78
scripts/bootstrap-az-state.ps1
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
Param(
|
||||||
|
[string]$Location = "westeurope",
|
||||||
|
[string]$ResourceGroup = "rg-tofu-state",
|
||||||
|
[string]$StorageAccountName = "",
|
||||||
|
[string]$ContainerName = "tfstate",
|
||||||
|
[string]$StateKey = "terraform.tfstate",
|
||||||
|
[switch]$UseAzureAdAuth = $true
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
function Ensure-AzLogin {
|
||||||
|
try { az account show | Out-Null }
|
||||||
|
catch { az login | Out-Null }
|
||||||
|
}
|
||||||
|
|
||||||
|
Ensure-AzLogin
|
||||||
|
|
||||||
|
# Resource Group (idempotent)
|
||||||
|
az group create --name $ResourceGroup --location $Location | Out-Null
|
||||||
|
|
||||||
|
# Storage Account name must be globally unique, 3-24 chars, lowercase letters/numbers
|
||||||
|
if ([string]::IsNullOrWhiteSpace($StorageAccountName)) {
|
||||||
|
$rand = Get-Random -Minimum 100000 -Maximum 999999
|
||||||
|
$StorageAccountName = ("tofu" + $rand + "state").ToLower()
|
||||||
|
if ($StorageAccountName.Length -gt 24) { $StorageAccountName = $StorageAccountName.Substring(0, 24) }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create SA if missing
|
||||||
|
$saExists = $true
|
||||||
|
try { az storage account show -g $ResourceGroup -n $StorageAccountName | Out-Null }
|
||||||
|
catch { $saExists = $false }
|
||||||
|
|
||||||
|
if (-not $saExists) {
|
||||||
|
az storage account create `
|
||||||
|
-g $ResourceGroup -n $StorageAccountName -l $Location `
|
||||||
|
--sku Standard_LRS --kind StorageV2 `
|
||||||
|
--https-only true --min-tls-version TLS1_2 `
|
||||||
|
--allow-blob-public-access false | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enable blob versioning + soft delete (nice safety net for state)
|
||||||
|
az storage account blob-service-properties update `
|
||||||
|
-g $ResourceGroup -n $StorageAccountName `
|
||||||
|
--enable-versioning true `
|
||||||
|
--enable-delete-retention true --delete-retention-days 14 | Out-Null
|
||||||
|
|
||||||
|
# Create container (try Entra "login" auth first; fallback to account key if needed)
|
||||||
|
$containerCreated = $false
|
||||||
|
try {
|
||||||
|
az storage container create `
|
||||||
|
--name $ContainerName --account-name $StorageAccountName `
|
||||||
|
--auth-mode login | Out-Null
|
||||||
|
$containerCreated = $true
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
$key = az storage account keys list -g $ResourceGroup -n $StorageAccountName --query "[0].value" -o tsv
|
||||||
|
az storage container create `
|
||||||
|
--name $ContainerName --account-name $StorageAccountName `
|
||||||
|
--account-key $key | Out-Null
|
||||||
|
$containerCreated = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Write backend.hcl (NO secrets if you keep AzureAD auth + CLI)
|
||||||
|
$backend = @()
|
||||||
|
$backend += "resource_group_name = `"$ResourceGroup`""
|
||||||
|
$backend += "storage_account_name = `"$StorageAccountName`""
|
||||||
|
$backend += "container_name = `"$ContainerName`""
|
||||||
|
$backend += "key = `"$StateKey`""
|
||||||
|
if ($UseAzureAdAuth) { $backend += "use_azuread_auth = true" } # uses Entra ID :contentReference[oaicite:2]{index=2}
|
||||||
|
Set-Content -Path (Join-Path (Get-Location) "backend.hcl") -Value ($backend -join "`n") -Encoding UTF8
|
||||||
|
|
||||||
|
Write-Host "State backend ready:"
|
||||||
|
Write-Host " RG: $ResourceGroup"
|
||||||
|
Write-Host " SA: $StorageAccountName"
|
||||||
|
Write-Host " Container: $ContainerName"
|
||||||
|
Write-Host " Key: $StateKey"
|
||||||
|
Write-Host "Wrote backend.hcl"
|
||||||
Reference in New Issue
Block a user