Copias de seguridad S3 AWS - MunchiA/Tartuski GitHub Wiki

Copias de seguridad a S3

[!WARNING] Antes de continuar, asegúrate de tener un entorno dondes subir los ficheros Ejemplo: Terraform AWS para evitar errores posteriores.

Una vez creados, tendremos que fijarnos en las credenciales. Nosotros utilizamos entornos de laboratorio, por lo que las credenciales van cambiando frecuentemente.

Necesitaremos:

[!IMPORTANT]

aws_access_key_id=*******
aws_secret_access_key=*******
aws_session_token=*******
Region=us-east-1

Primero veremos cómo subir el servidor de datos al S3.
En nuestro caso, no queremos tener que iniciar sesión y subirlo manualmente, así que usaremos un script que sube directamente al bucket con la fecha y hora actuales.

Como utilizamos entornos de laboratorio, emplearemos Terraform para poder crear y destruir recursos fácilmente y evitar gastos innecesarios. image

El script que utilizaremos pide los datos que anteriormente mencionamos, por lo que aunque cambies de entorno, si el bucket se llama igual, no tendrás problemas.


Script de copia y subida a S3 (PowerShell)

$perfilesPath = "C:\datos-tartuski\Perfiles-Moviles"

# Verificar que existe el directorio base
if (!(Test-Path $perfilesPath)) {
    Write-Host "La ruta $perfilesPath no existe." -ForegroundColor Red
    exit 1
}

Write-Host "Verificando permisos en carpetas de perfiles..." -ForegroundColor Cyan

# Recorre todas las carpetas de perfil
Get-ChildItem -Path $perfilesPath -Directory | ForEach-Object {
    $carpeta = $_.FullName
    try {
        $acl = Get-Acl -Path $carpeta

        $adminTienePermiso = $false
        foreach ($entry in $acl.Access) {
            if ($entry.IdentityReference -match "Administradores" -and `
                ($entry.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::FullControl)) {
                $adminTienePermiso = $true
                break
            }
        }

        if (-not $adminTienePermiso) {
            Write-Host "Asignando permisos a: $carpeta"
            takeown /f "$carpeta" /r /d s | Out-Null
            icacls "$carpeta" /grant Administradores:F /t | Out-Null
        } else {
            Write-Host "Permisos ya presentes en: $carpeta"
        }
    }
    catch {
        Write-Warning "No se pudo acceder a $carpeta, intentando forzar permisos..."
        takeown /f "$carpeta" /r /d s | Out-Null
        icacls "$carpeta" /grant Administradores:F /t | Out-Null
    }
}

Write-Host ""
Write-Host "Comprimiendo carpeta C:\datos-tartuski..." -ForegroundColor Cyan

# Fecha y nombre del archivo de backup
$fechaHora = Get-Date -Format "yyyyMMdd-HHmmss"
$archivoBackup = "backup-datos-tartuski-$fechaHora.zip"
$rutaBackup = "C:\backups\$archivoBackup"

# Crear directorio local si no existe
if (!(Test-Path "C:\backups")) {
    New-Item -ItemType Directory -Path "C:\backups" | Out-Null
}

# Comprimir con .NET (mejor que Compress-Archive)
Add-Type -AssemblyName System.IO.Compression.FileSystem
try {
    [System.IO.Compression.ZipFile]::CreateFromDirectory("C:\datos-tartuski", $rutaBackup)
}
catch {
    Write-Host "Error al comprimir los archivos: $_" -ForegroundColor Red
    exit 1
}

# Eliminar credenciales anteriores
$awsCredentialsPath = "$env:USERPROFILE\.aws\credentials"
if (Test-Path $awsCredentialsPath) {
    try {
        Remove-Item $awsCredentialsPath -Force
    }
    catch {
        Write-Warning "No se pudo eliminar el archivo de credenciales existente."
    }
}

# Solicitar credenciales
Write-Host ""
Write-Host "Ingresa tus credenciales temporales de AWS" -ForegroundColor Yellow
$accessKey = Read-Host "Access Key"
$secretKey = Read-Host "Secret Key"
$sessionToken = Read-Host "Session Token (Token MFA o de sesión temporal)"

# Escribir archivo de credenciales sin BOM
$credentialContent = @"
[default]
aws_access_key_id = $accessKey
aws_secret_access_key = $secretKey
aws_session_token = $sessionToken
"@
$awsDir = "$env:USERPROFILE\.aws"
if (!(Test-Path $awsDir)) {
    New-Item -ItemType Directory -Path $awsDir | Out-Null
}
[System.IO.File]::WriteAllText($awsCredentialsPath, $credentialContent, (New-Object System.Text.UTF8Encoding($false)))

# Nombre del bucket
$bucketName = "NOMBRE DE TU BUCKET"
$remotePrefix = "backups/$fechaHora"
$remotePath = "$remotePrefix/$archivoBackup"

# Verificar que AWS CLI está disponible antes de continuar
if (-not (Get-Command "aws" -ErrorAction SilentlyContinue)) {
    Write-Host "AWS CLI no está instalada o no está en PATH." -ForegroundColor Red
    exit 1
}

# Subida a S3
Write-Host ""
Write-Host "Subiendo archivo a S3..." -ForegroundColor Cyan
aws s3 cp $rutaBackup "s3://$bucketName/$remotePath"

if ($LASTEXITCODE -eq 0) {
    Write-Host "Backup subido exitosamente a: s3://$bucketName/$remotePath" -ForegroundColor Green
} else {
    Write-Host "Error al subir el backup a S3." -ForegroundColor Red
}

[!TIP] Por si queréis automatizarlo aún más:
Aquí tenéis una tarea programada en PowerShell que ejecuta el script diariamente a las 7 de la mañana.

$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `\"C:\subir_backup.ps1`\""
$Trigger = New-ScheduledTaskTrigger -Daily -At 7:00AM
Register-ScheduledTask -TaskName "SubirBackupDiario" -Action $Action -Trigger $Trigger -Description "Sube el backup diariamente a las 7 AM" -User "SYSTEM" -RunLevel Highest