Add working provisioning and configuration for MS SQL data warehouse
This commit is contained in:
67
configuration/ansible_mssql/roles/db_restore/tasks/main.yml
Normal file
67
configuration/ansible_mssql/roles/db_restore/tasks/main.yml
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
- name: Find sqlcmd.exe
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$sqlcmd = Get-ChildItem 'C:\Program Files\Microsoft SQL Server' -Filter 'sqlcmd.exe' `
|
||||
-Recurse -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -notlike '*\x86\*' } |
|
||||
Sort-Object LastWriteTime -Descending |
|
||||
Select-Object -First 1 -ExpandProperty FullName
|
||||
if (-not $sqlcmd) { throw 'sqlcmd.exe not found' }
|
||||
$Ansible.Result = $sqlcmd
|
||||
$Ansible.Changed = $false
|
||||
register: sqlcmd_path
|
||||
|
||||
- name: Download database backups
|
||||
ansible.windows.win_get_url:
|
||||
url: "{{ item.url }}"
|
||||
dest: "{{ db_backup_dir }}\\{{ item.filename }}"
|
||||
loop: "{{ db_backups }}"
|
||||
|
||||
- name: Restore databases
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$sqlcmd = '{{ sqlcmd_path.result }}'
|
||||
$bakFile = '{{ db_backup_dir }}\{{ item.filename }}'
|
||||
$dbName = '{{ item.name }}'
|
||||
|
||||
# Idempotent: skip if database already exists
|
||||
$exists = (& $sqlcmd -S . -E -h -1 `
|
||||
-Q "SET NOCOUNT ON; SELECT name FROM sys.databases WHERE name = N'$dbName'" |
|
||||
Out-String).Trim()
|
||||
if ($exists -eq $dbName) {
|
||||
Write-Output "$dbName already exists — skipping restore."
|
||||
$Ansible.Changed = $false
|
||||
return
|
||||
}
|
||||
|
||||
# Get logical file list from the backup
|
||||
$raw = & $sqlcmd -S . -E -s "|" -W `
|
||||
-Q "RESTORE FILELISTONLY FROM DISK = N'$bakFile'"
|
||||
|
||||
$files = $raw | Select-Object -Skip 2 | Where-Object { $_ -match '\|' } | ForEach-Object {
|
||||
$cols = $_ -split '\|'
|
||||
[PSCustomObject]@{
|
||||
LogicalName = $cols[0].Trim()
|
||||
PhysicalName = $cols[1].Trim()
|
||||
FileType = $cols[2].Trim() # D = data, L = log
|
||||
}
|
||||
}
|
||||
|
||||
# Build MOVE clauses — keep original filename, redirect to correct partition
|
||||
$moves = $files | ForEach-Object {
|
||||
$dir = if ($_.FileType -eq 'L') { '{{ db_log_dir }}' } else { '{{ db_data_dir }}' }
|
||||
$file = [System.IO.Path]::GetFileName($_.PhysicalName)
|
||||
"MOVE N'$($_.LogicalName)' TO N'$dir\$file'"
|
||||
}
|
||||
|
||||
$sql = "RESTORE DATABASE [$dbName] FROM DISK = N'$bakFile' WITH $($moves -join ', '), REPLACE, STATS = 10"
|
||||
Write-Output "Restoring $dbName ..."
|
||||
& $sqlcmd -S . -E -Q $sql -t 3600
|
||||
if ($LASTEXITCODE -ne 0) { throw "RESTORE failed with exit code $LASTEXITCODE" }
|
||||
loop: "{{ db_backups }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
timeout: 7200
|
||||
Reference in New Issue
Block a user