Centralized Backup of Various Resources with AWS Backup
awsAWS Backup is a managed service that allows you to centrally backup resources like S3, RDS, DynamoDB, and more specified by resource IDs or tags. You can strengthen governance by applying policies to accounts under your Organization, and prepare for disaster recovery by copying to vaults in other regions or accounts.
AWS Organizaionsで複数のアカウントを一元管理する - sambaiz-net
Pricing is based on storage capacity for both backup and restore operations. However, for S3, the backup cost is $0.06/GB while the storage cost in the Tokyo region is $0.025/GB, which makes AWS Backup quite expensive. For larger scale deployments, it may be better to implement custom backup solutions rather than using AWS Backup. From a data recovery perspective, versioning can be a viable option if you can handle bucket deletion. In fact, versioning must be enabled for S3 buckets to be eligible for AWS Backup.
Enable S3 versioning to retrieve accidentally overwritten or deleted objects - sambaiz-net
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as backup from 'aws-cdk-lib/aws-backup';
import * as iam from 'aws-cdk-lib/aws-iam';
export class AwsBackupTestStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// VPC for RDS
const vpc = new ec2.Vpc(this, 'BackupTestVpc', {
maxAzs: 2,
natGateways: 0,
subnetConfiguration: [
{
name: 'Public',
subnetType: ec2.SubnetType.PUBLIC,
cidrMask: 24,
},
],
});
// RDS Instance (PostgreSQL)
const dbInstance = new rds.DatabaseInstance(this, 'BackupTestDatabase', {
engine: rds.DatabaseInstanceEngine.postgres({
version: rds.PostgresEngineVersion.VER_16_6,
}),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC,
},
publiclyAccessible: true,
multiAz: false,
allocatedStorage: 20,
maxAllocatedStorage: 100,
databaseName: 'testdb',
credentials: rds.Credentials.fromGeneratedSecret('dbadmin'),
backupRetention: cdk.Duration.days(7), // Enable RDS automatic backups for PITR (AWS Backup handles long-term retention)
removalPolicy: cdk.RemovalPolicy.DESTROY,
deletionProtection: false,
});
// Allow PostgreSQL access from anywhere (test environment only)
dbInstance.connections.allowFromAnyIpv4(ec2.Port.tcp(5432));
// S3 Bucket
const bucket = new s3.Bucket(this, 'BackupTestBucket', {
versioned: true, // Required for AWS Backup
encryption: s3.BucketEncryption.S3_MANAGED,
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});
// Tag resources for AWS Backup selection
cdk.Tags.of(dbInstance).add('Backup', 'daily');
cdk.Tags.of(bucket).add('Backup', 'daily');
// Backup Vault
const backupVault = new backup.BackupVault(this, 'BackupVault', {
backupVaultName: 'AwsBackupTestVault',
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
// Backup Plan
const backupPlan = new backup.BackupPlan(this, 'BackupPlan', {
backupPlanName: 'DailyBackupPlan',
backupVault,
backupPlanRules: [
new backup.BackupPlanRule({
ruleName: 'HourlyBackup',
scheduleExpression: cdk.aws_events.Schedule.cron({
minute: '0', // Every hour
}),
deleteAfter: cdk.Duration.days(7),
startWindow: cdk.Duration.hours(1),
completionWindow: cdk.Duration.hours(2),
}),
],
});
// Backup Selection (tag-based)
const backupRole = 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'),
iam.ManagedPolicy.fromAwsManagedPolicyName('AWSBackupServiceRolePolicyForS3Backup'),
iam.ManagedPolicy.fromAwsManagedPolicyName('AWSBackupServiceRolePolicyForS3Restore'),
],
});
backupPlan.addSelection('DailyBackupSelection', {
resources: [
backup.BackupResource.fromTag('Backup', 'daily'),
],
role: backupRole,
allowRestores: true,
});
}
}
Recovery points are created at specified intervals with a minimum of 60 minutes, and you can select them to restore to a new instance.