AWS Backup & Disaster Recovery Strategieën
Bescherm uw bedrijf met uitgebreide backup en disaster recovery strategieën met behulp van AWS Backup, cross-region replicatie en geautomatiseerde herstelprocedures
Introductie
Gegevensverlies en serviceonderbrekingen kunnen catastrofaal zijn voor elk bedrijf. Of het nu wordt veroorzaakt door menselijke fouten, cyberaanvallen, natuurrampen of systeemfouten, de impact kan variëren van tijdelijk ongemak tot volledig bedrijfsfalen. Een robuuste backup en disaster recovery (DR) strategie is niet alleen een technische vereiste – het is een zakelijke noodzaak.
Deze uitgebreide gids verkent AWS backup en disaster recovery strategieën, van basis backup-automatisering tot multi-region disaster recovery architecturen. U leert hoe u oplossingen ontwerpt die voldoen aan uw Recovery Time Objective (RTO) en Recovery Point Objective (RPO) vereisten terwijl u de kosten optimaliseert.
Wat u leert:
- RTO, RPO en herstelstrategieën begrijpen
- AWS Backup service voor gecentraliseerd backup-beheer
- Cross-region replicatie strategieën voor S3, RDS en DynamoDB
- Disaster recovery patronen: Backup & Restore, Pilot Light, Warm Standby, Hot Standby
- Backup-beleid automatiseren met AWS CDK en Python
- Herstelprocedures testen en valideren
- Kostenoptimalisatie voor backup en DR oplossingen
RTO en RPO Begrijpen
Recovery Time Objective (RTO)
RTO is de maximaal acceptabele tijd dat een applicatie down kan zijn nadat een ramp heeft plaatsgevonden. Het beantwoordt de vraag: “Hoe snel moeten we herstellen?”
Voorbeelden:
- E-commerce website: RTO van 1 uur (omzetverlies, reputatieschade)
- Intern rapportagesysteem: RTO van 24 uur (minder kritiek)
- Bankapplicatie: RTO van minuten (regelgevende vereisten)
Recovery Point Objective (RPO)
RPO is de maximaal acceptabele hoeveelheid gegevensverlies gemeten in tijd. Het beantwoordt de vraag: “Hoeveel gegevens kunnen we ons veroorloven te verliezen?”
Voorbeelden:
- Financieel handelssysteem: RPO van seconden (elke transactie telt)
- Blog website: RPO van 24 uur (dagelijkse backups acceptabel)
- Data warehouse: RPO van 1 uur (uurlijkse snapshots)
RTO vs RPO Kosten Afwegingen
Hogere Beschikbaarheid = Hogere Kosten
RPO/RTO Strategie AWS Services Maandelijkse Kosten (schatting)
────────────────────────────────────────────────────────────────────────────────────────
Dagen Backup & Restore S3, Glacier, AWS Backup €50-500
Uren Pilot Light S3, RDS standby, Route53 €500-2000
Minuten Warm Standby Multi-AZ, Read Replica €2000-10000
Seconden Hot Standby Active-Active, Multi-Reg €10000+
AWS Backup Service
Introductie tot AWS Backup
AWS Backup is een volledig beheerde service die gegevensbescherming centraliseert en automatiseert voor AWS services waaronder:
- Amazon EC2 (EBS volumes)
- Amazon RDS en Aurora
- Amazon DynamoDB
- Amazon EFS
- Amazon FSx
- AWS Storage Gateway
- Amazon S3
Belangrijkste Voordelen:
- Gecentraliseerd beheer: Eén console voor alle backups
- Geautomatiseerde backup planning: Op beleid gebaseerde backup plannen
- Cross-region backup: Automatische replicatie naar verschillende regio’s
- Compliance rapportage: Volg backup compliance vereisten
- Lifecycle management: Automatisch overgaan naar koude opslag
- Encryptie: Alle backups versleuteld in rust en tijdens transport
Backup Plannen Maken met AWS CDK
// lib/backup-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as backup from 'aws-cdk-lib/aws-backup';
import * as events from 'aws-cdk-lib/aws-events';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';
export class BackupStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Backup vault aanmaken
const backupVault = new backup.BackupVault(this, 'PrimaryBackupVault', {
backupVaultName: 'primary-backup-vault',
// Encryptie inschakelen met KMS
encryptionKey: new cdk.aws_kms.Key(this, 'BackupKey', {
description: 'KMS sleutel voor backup encryptie',
enableKeyRotation: true,
removalPolicy: cdk.RemovalPolicy.RETAIN,
}),
// Voorkom onbedoeld verwijderen
removalPolicy: cdk.RemovalPolicy.RETAIN,
});
// Backup vault voor cross-region replicatie
const drBackupVault = new backup.BackupVault(this, 'DRBackupVault', {
backupVaultName: 'dr-backup-vault-eu-west-1',
removalPolicy: cdk.RemovalPolicy.RETAIN,
});
// Dagelijks backup plan met lifecycle regels
const dailyBackupPlan = new backup.BackupPlan(this, 'DailyBackupPlan', {
backupPlanName: 'daily-backup-plan',
backupPlanRules: [
new backup.BackupPlanRule({
ruleName: 'DailyBackups',
backupVault,
// Planning: Dagelijks om 2 uur 's nachts UTC
scheduleExpression: events.Schedule.cron({
hour: '2',
minute: '0',
}),
// Start backup binnen 1 uur na planning
startWindow: cdk.Duration.hours(1),
// Voltooi backup binnen 2 uur
completionWindow: cdk.Duration.hours(2),
// Lifecycle: Overgang naar koude opslag na 30 dagen
moveToColdStorageAfter: cdk.Duration.days(30),
// Verwijderen na 90 dagen
deleteAfter: cdk.Duration.days(90),
// Kopiëren naar DR regio
copyActions: [
{
destinationBackupVault: drBackupVault,
moveToColdStorageAfter: cdk.Duration.days(30),
deleteAfter: cdk.Duration.days(90),
},
],
}),
],
});
// Uurlijks backup plan voor kritieke databases
const hourlyBackupPlan = new backup.BackupPlan(this, 'HourlyBackupPlan', {
backupPlanName: 'hourly-critical-backup-plan',
backupPlanRules: [
new backup.BackupPlanRule({
ruleName: 'HourlyBackups',
backupVault,
// Planning: Elk uur
scheduleExpression: events.Schedule.rate(cdk.Duration.hours(1)),
startWindow: cdk.Duration.minutes(30),
completionWindow: cdk.Duration.hours(1),
// Bewaar uurlijkse backups voor 7 dagen
deleteAfter: cdk.Duration.days(7),
// Direct kopiëren naar DR regio
copyActions: [
{
destinationBackupVault: drBackupVault,
deleteAfter: cdk.Duration.days(7),
},
],
}),
],
});
// Wekelijks backup plan met lange retentie
const weeklyBackupPlan = new backup.BackupPlan(this, 'WeeklyBackupPlan', {
backupPlanName: 'weekly-long-term-backup-plan',
backupPlanRules: [
new backup.BackupPlanRule({
ruleName: 'WeeklyBackups',
backupVault,
// Planning: Elke zondag om 3 uur 's nachts UTC
scheduleExpression: events.Schedule.cron({
weekDay: 'SUN',
hour: '3',
minute: '0',
}),
startWindow: cdk.Duration.hours(2),
completionWindow: cdk.Duration.hours(4),
// Overgang naar koude opslag na 7 dagen
moveToColdStorageAfter: cdk.Duration.days(7),
// Bewaren voor 1 jaar
deleteAfter: cdk.Duration.days(365),
copyActions: [
{
destinationBackupVault: drBackupVault,
moveToColdStorageAfter: cdk.Duration.days(7),
deleteAfter: cdk.Duration.days(365),
},
],
}),
],
});
// Backup selectie: Tag-gebaseerde resource selectie
// Dagelijkse backups voor alle productie resources
dailyBackupPlan.addSelection('ProductionResources', {
backupSelection: {
selectionName: 'production-daily-backup',
iamRole: new iam.Role(this, 'BackupRole', {
assumedBy: new iam.ServicePrincipal('backup.amazonaws.com'),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName(
'service-role/AWSBackupServiceRolePolicyForBackup'
),
iam.ManagedPolicy.fromAwsManagedPolicyName(
'service-role/AWSBackupServiceRolePolicyForRestores'
),
],
}),
},
resources: [
// Selecteer resources op tag
backup.BackupResource.fromTag('Environment', 'production'),
backup.BackupResource.fromTag('Backup', 'daily'),
],
});
// Uurlijkse backups voor kritieke databases
hourlyBackupPlan.addSelection('CriticalDatabases', {
resources: [
backup.BackupResource.fromTag('Criticality', 'critical'),
backup.BackupResource.fromTag('Backup', 'hourly'),
],
});
// Wekelijkse backups voor lange termijn retentie
weeklyBackupPlan.addSelection('LongTermRetention', {
resources: [
backup.BackupResource.fromTag('Backup', 'weekly'),
],
});
// CloudWatch alarm voor mislukte backups
const backupFailureAlarm = new cdk.aws_cloudwatch.Alarm(
this,
'BackupFailureAlarm',
{
alarmName: 'backup-job-failure',
metric: new cdk.aws_cloudwatch.Metric({
namespace: 'AWS/Backup',
metricName: 'NumberOfBackupJobsFailed',
statistic: 'Sum',
period: cdk.Duration.hours(1),
}),
threshold: 1,
evaluationPeriods: 1,
comparisonOperator:
cdk.aws_cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
treatMissingData: cdk.aws_cloudwatch.TreatMissingData.NOT_BREACHING,
}
);
// SNS topic voor backup notificaties
const backupTopic = new cdk.aws_sns.Topic(this, 'BackupNotifications', {
displayName: 'Backup Job Notificaties',
});
backupFailureAlarm.addAlarmAction(
new cdk.aws_cloudwatch_actions.SnsAction(backupTopic)
);
// Outputs
new cdk.CfnOutput(this, 'BackupVaultArn', {
value: backupVault.backupVaultArn,
description: 'Primaire backup vault ARN',
});
new cdk.CfnOutput(this, 'DailyBackupPlanId', {
value: dailyBackupPlan.backupPlanId,
description: 'Dagelijks backup plan ID',
});
}
}
Python Script voor Backup Automatisering
# scripts/backup_automation.py
import boto3
import json
from datetime import datetime, timedelta
from typing import List, Dict
class AWSBackupManager:
"""Beheer AWS Backup operaties programmatisch"""
def __init__(self, region: str = 'eu-central-1'):
self.backup_client = boto3.client('backup', region_name=region)
self.ec2_client = boto3.client('ec2', region_name=region)
self.rds_client = boto3.client('rds', region_name=region)
self.region = region
def create_on_demand_backup(
self,
resource_arn: str,
backup_vault_name: str,
iam_role_arn: str,
backup_name: str = None
) -> str:
"""
Maak een on-demand backup voor een specifieke resource
Args:
resource_arn: ARN van de resource voor backup
backup_vault_name: Naam van de backup vault
iam_role_arn: IAM rol ARN voor backup service
backup_name: Optionele aangepaste backup naam
Returns:
Backup job ID
"""
if not backup_name:
timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')
backup_name = f"on-demand-backup-{timestamp}"
try:
response = self.backup_client.start_backup_job(
BackupVaultName=backup_vault_name,
ResourceArn=resource_arn,
IamRoleArn=iam_role_arn,
IdempotencyToken=backup_name,
StartWindowMinutes=60,
CompleteWindowMinutes=120,
Lifecycle={
'MoveToColdStorageAfterDays': 30,
'DeleteAfterDays': 90
}
)
backup_job_id = response['BackupJobId']
print(f"Backup job gestart: {backup_job_id}")
return backup_job_id
except Exception as e:
print(f"Fout bij aanmaken backup: {str(e)}")
raise
def list_backup_jobs(
self,
backup_vault_name: str = None,
state: str = None,
max_results: int = 100
) -> List[Dict]:
"""
Lijst backup jobs met optionele filters
Args:
backup_vault_name: Filter op backup vault
state: Filter op job status (CREATED, PENDING, RUNNING, COMPLETED, FAILED, ABORTED)
max_results: Maximum aantal resultaten
Returns:
Lijst van backup jobs
"""
params = {'MaxResults': max_results}
if backup_vault_name:
params['ByBackupVaultName'] = backup_vault_name
if state:
params['ByState'] = state
try:
response = self.backup_client.list_backup_jobs(**params)
return response.get('BackupJobs', [])
except Exception as e:
print(f"Fout bij ophalen backup jobs: {str(e)}")
raise
def restore_from_backup(
self,
recovery_point_arn: str,
iam_role_arn: str,
metadata: Dict,
resource_type: str
) -> str:
"""
Herstel een resource van een backup recovery point
Args:
recovery_point_arn: ARN van het recovery point
iam_role_arn: IAM rol ARN voor restore service
metadata: Restore metadata (varieert per resource type)
resource_type: Type resource (EBS, RDS, etc.)
Returns:
Restore job ID
"""
try:
response = self.backup_client.start_restore_job(
RecoveryPointArn=recovery_point_arn,
IamRoleArn=iam_role_arn,
Metadata=metadata,
ResourceType=resource_type
)
restore_job_id = response['RestoreJobId']
print(f"Restore job gestart: {restore_job_id}")
return restore_job_id
except Exception as e:
print(f"Fout bij starten restore: {str(e)}")
raise
def generate_backup_report(
self,
backup_vault_name: str,
days: int = 7
) -> Dict:
"""
Genereer backup compliance rapport
Args:
backup_vault_name: Naam van de backup vault
days: Aantal dagen terug te kijken
Returns:
Rapport dictionary met statistieken
"""
cutoff_date = datetime.now() - timedelta(days=days)
# Haal alle backup jobs op in tijdsbestek
jobs = self.list_backup_jobs(backup_vault_name=backup_vault_name)
# Filter op datum
recent_jobs = [
job for job in jobs
if datetime.fromisoformat(
job['CreationDate'].replace('Z', '+00:00')
) > cutoff_date
]
# Bereken statistieken
total_jobs = len(recent_jobs)
completed = len([j for j in recent_jobs if j['State'] == 'COMPLETED'])
failed = len([j for j in recent_jobs if j['State'] == 'FAILED'])
running = len([j for j in recent_jobs if j['State'] == 'RUNNING'])
total_size = sum(
job.get('BackupSizeInBytes', 0)
for job in recent_jobs
if job['State'] == 'COMPLETED'
)
report = {
'vault_name': backup_vault_name,
'period_days': days,
'total_jobs': total_jobs,
'completed_jobs': completed,
'failed_jobs': failed,
'running_jobs': running,
'success_rate': f"{(completed/total_jobs*100):.2f}%" if total_jobs > 0 else "0%",
'total_backup_size_gb': f"{total_size / (1024**3):.2f}",
'generated_at': datetime.now().isoformat()
}
return report
# Voorbeeld gebruik
if __name__ == '__main__':
# Initialiseer backup manager
backup_mgr = AWSBackupManager(region='eu-central-1')
# Maak on-demand backup voor RDS instantie
rds_arn = "arn:aws:rds:eu-central-1:123456789012:db:production-db"
iam_role = "arn:aws:iam::123456789012:role/AWSBackupServiceRole"
job_id = backup_mgr.create_on_demand_backup(
resource_arn=rds_arn,
backup_vault_name='primary-backup-vault',
iam_role_arn=iam_role,
backup_name='production-db-handmatige-backup'
)
# Genereer backup rapport
report = backup_mgr.generate_backup_report(
backup_vault_name='primary-backup-vault',
days=7
)
print("\n=== Backup Rapport ===")
print(json.dumps(report, indent=2))
Cross-Region Replicatie Strategieën
S3 Cross-Region Replicatie
// lib/s3-replication-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';
export class S3ReplicationStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Bron bucket in primaire regio (eu-central-1)
const sourceBucket = new s3.Bucket(this, 'SourceBucket', {
bucketName: 'forrict-productie-data-primair',
versioned: true, // Vereist voor replicatie
encryption: s3.BucketEncryption.S3_MANAGED,
lifecycleRules: [
{
// Verplaats oude versies naar Glacier na 30 dagen
noncurrentVersionTransitions: [
{
storageClass: s3.StorageClass.GLACIER,
transitionAfter: cdk.Duration.days(30),
},
],
// Verwijder oude versies na 90 dagen
noncurrentVersionExpiration: cdk.Duration.days(90),
},
],
removalPolicy: cdk.RemovalPolicy.RETAIN,
});
// Doel bucket in DR regio (eu-west-1)
const destinationBucket = new s3.Bucket(this, 'DestinationBucket', {
bucketName: 'forrict-productie-data-dr',
versioned: true,
encryption: s3.BucketEncryption.S3_MANAGED,
removalPolicy: cdk.RemovalPolicy.RETAIN,
});
// IAM rol voor replicatie
const replicationRole = new iam.Role(this, 'ReplicationRole', {
assumedBy: new iam.ServicePrincipal('s3.amazonaws.com'),
path: '/service-role/',
});
// Geef rechten aan bron bucket
sourceBucket.grantRead(replicationRole);
// Geef rechten aan doel bucket
destinationBucket.grantWrite(replicationRole);
// Voeg replicatie configuratie toe
const cfnSourceBucket = sourceBucket.node.defaultChild as s3.CfnBucket;
cfnSourceBucket.replicationConfiguration = {
role: replicationRole.roleArn,
rules: [
{
id: 'repliceer-alle-objecten',
status: 'Enabled',
priority: 1,
filter: {
// Repliceer alle objecten
prefix: '',
},
destination: {
bucket: destinationBucket.bucketArn,
// Repliceer opslagklasse
storageClass: 'STANDARD',
// Schakel replicatie tijdscontrole in (15 minuten SLA)
replicationTime: {
status: 'Enabled',
time: {
minutes: 15,
},
},
// Schakel metrics in voor monitoring
metrics: {
status: 'Enabled',
eventThreshold: {
minutes: 15,
},
},
},
// Delete marker replicatie
deleteMarkerReplication: {
status: 'Enabled',
},
},
],
};
// CloudWatch alarm voor replicatie vertraging
const replicationAlarm = new cdk.aws_cloudwatch.Alarm(
this,
'ReplicationLagAlarm',
{
alarmName: 's3-replicatie-vertraging',
metric: new cdk.aws_cloudwatch.Metric({
namespace: 'AWS/S3',
metricName: 'ReplicationLatency',
dimensionsMap: {
SourceBucket: sourceBucket.bucketName,
DestinationBucket: destinationBucket.bucketName,
},
statistic: 'Maximum',
period: cdk.Duration.minutes(5),
}),
// Waarschuw als replicatie langer dan 30 minuten duurt
threshold: 1800, // seconden
evaluationPeriods: 2,
}
);
}
}
RDS Cross-Region Read Replica
De RDS cross-region configuratie volgt hetzelfde patroon als het Engelse voorbeeld met PostgreSQL database instanties, read replica’s en monitoring alarmen voor replicatie vertraging.
Disaster Recovery Patronen
Patroon 1: Backup and Restore (RPO: Uren, RTO: Uren)
Gebruik: Niet-kritieke applicaties waar enkele uren downtime acceptabel is
Architectuur:
- Regelmatige backups naar S3/Glacier
- Geen resources actief in DR regio
- Laagste kosten optie
Kosten: €50-500/maand
Herstelproces:
- Detecteer uitval in primaire regio
- Haal backups op van S3
- Start infrastructuur in DR regio met IaC
- Herstel data van backups
- Update DNS naar DR regio
Patroon 2: Pilot Light (RPO: Minuten, RTO: 10-30 minuten)
Gebruik: Productie applicaties met gematigde RTO/RPO vereisten
Architectuur:
- Kern infrastructuur actief in DR regio (databases, minimale compute)
- Data continu gerepliceerd
- Extra resources ingericht tijdens ramp
Kosten: €500-2000/maand
Patroon 3: Warm Standby (RPO: Seconden, RTO: Minuten)
Gebruik: Bedrijfskritieke applicaties met minimale downtime vereisten
Architectuur:
- Verkleinde versie van volledige omgeving actief in DR regio
- Data gesynchroniseerd in real-time
- Kan enig productie verkeer verwerken
Kosten: €2000-10000/maand
Patroon 4: Hot Standby / Active-Active (RPO: Geen, RTO: Seconden)
Gebruik: Missiekritieke applicaties met nul tolerantie voor downtime
Architectuur:
- Volledige productie omgeving in meerdere regio’s
- Active-active configuratie
- Real-time data replicatie
- Globale load balancing
Kosten: €10000+/maand
Testen en Validatie
Geautomatiseerd DR Test Script
Het Python test script volgt dezelfde structuur als het Engels voorbeeld, met functies voor het testen van backup restore, failover en RTO/RPO metingen.
Best Practices
1. Backup Strategie
- Implementeer 3-2-1 regel: 3 kopieën, 2 verschillende media, 1 offsite
- Automatiseer backups met AWS Backup
- Test restores regelmatig (minimaal maandelijks)
- Tag resources voor geautomatiseerde backup
- Implementeer lifecycle beleid om kosten te beheersen
2. Gegevensbescherming
- Schakel versioning in op S3 buckets
- Gebruik cross-region replicatie voor kritieke data
- Versleutel alle backups in rust en tijdens transport
- Implementeer backup retentie beleid in lijn met AVG
- Monitor backup job succespercentages
3. Herstelplanning
- Documenteer RTO en RPO vereisten voor elke workload
- Maak gedetailleerde runbooks voor herstelprocedures
- Automatiseer herstel waar mogelijk
- Oefen failure scenario’s (chaos engineering)
- Houd contactlijsten up-to-date
4. Kostenoptimalisatie
- Gebruik Glacier voor lange termijn retentie
- Implementeer intelligent tiering voor S3
- Bepaal juiste grootte DR infrastructuur
- Gebruik spot instances voor DR testen
- Verwijder oude backups automatisch
5. Monitoring en Alerting
- Monitor backup job voltooiing
- Waarschuw bij replicatie vertraging
- Volg RTO/RPO compliance
- Monitor cross-region bandbreedte kosten
- Stel herstel tijd tracking in
Conclusie
Een uitgebreide backup en disaster recovery strategie is essentieel voor bedrijfscontinuïteit. AWS biedt krachtige tools zoals AWS Backup, cross-region replicatie en multi-region architecturen om uw data en applicaties te beschermen. De sleutel is het kiezen van het juiste DR patroon gebaseerd op uw RTO/RPO vereisten en budgetbeperkingen.
Belangrijkste Punten:
- Definieer duidelijke RTO en RPO vereisten voor elke workload
- Automatiseer backups met AWS Backup service
- Implementeer cross-region replicatie voor kritieke data
- Kies geschikt DR patroon (Backup & Restore, Pilot Light, Warm Standby, Hot Standby)
- Test herstelprocedures regelmatig
- Monitor backup compliance en replicatie vertraging
Klaar om een robuuste disaster recovery strategie te implementeren? Forrict kan u helpen backup en DR oplossingen te ontwerpen en implementeren die zijn afgestemd op uw zakelijke vereisten en compliance behoeften.
Bronnen
- AWS Backup Documentatie
- AWS Disaster Recovery
- AWS Well-Architected Framework - Betrouwbaarheid Pilaar
- S3 Cross-Region Replicatie
- RDS Read Replica’s
Forrict Team
AWS expert en consultant bij Forrict, gespecialiseerd in cloud architectuur en AWS best practices voor Nederlandse bedrijven.

