今回は、AWS Backup サービスによる EC2、EBS、RDSなどの自動バックアップと通知をAWS CDKで実装する方法をまとめました。
はじめに
今回は、AWS Backupサービスを使用して、EC2インスタンスやEBS、RDSなどのリソースの自動バックアップとバックアップ結果通知の仕組みをAWS CDKでコード化していきます。タグベースでバックアップ対象を柔軟に制御し、日次・週次・月次の異なるスケジュールでバックアップを実行します。
今回作成するリソース
– SNSトピック: バックアップ実行結果の通知
– IAMロール: AWS Backup実行専用ロール
– Backup Vault: バックアップデータの安全な保存場所
– Backup Plan: 日次の自動バックアップスケジュール
– Backup Selection: タグベースでのバックアップ対象リソース選択
アーキテクチャ概要
AWS CDK ソースコード
SNS設定
const emailAddresses = [ // SNS通知先メーリングリスト 'xxxxxx@example.com', 'xxxxxxx@example.com' ]; const backupNotificationTopic = new sns.Topic(this, 'BackupNotificationTopic', { // バックアップ監視用のトピック topicName: 'backup-notification-topic', // トピック名 displayName: 'AWS Backup Notification Topic' // 表示名 }); emailAddresses.forEach(email => { // バックアップ監視用のサブスクリプション backupNotificationTopic.addSubscription( new subscriptions.EmailSubscription(email) ); });
ポイント:
- 複数の管理者アドレスに通知可能
- バックアップジョブの完了・失敗を即座に通知するためのSNS
IAMロール設定
const backupRole = new iam.Role(this, 'BackupRole', { roleName: 'backup-role', // バックアップロール名 assumedBy: new iam.ServicePrincipal('backup.amazonaws.com'), // AWS Backupサービスが引き受け managedPolicies: [ // マネージドポリシー iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSBackupServiceRolePolicyForBackup'), // バックアップ用マネージドポリシー iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSBackupServiceRolePolicyForRestores'), // リストア用マネージドポリシー ] });
ポイント:
- AWS Backupサービス専用のロール
- バックアップとリストア両方の権限を付与
Backup Vault設定
const backupVault = new backup.BackupVault(this, 'BackupVault', { // バックアップボールトの作成 backupVaultName: 'backup-vault', // バックアップボールト名 notificationTopic: backupNotificationTopic, // バックアップ監視用SNSトピック notificationEvents: [ // 通知イベント backup.BackupVaultEvents.BACKUP_JOB_COMPLETED, // バックアップジョブ完了 ], removalPolicy: cdk.RemovalPolicy.DESTROY // スタック削除時にボールトを削除 });
ポイント:
- バックアップデータの暗号化保存
- SNS通知と連携
- バックアップジョブ完了時の自動通知
リリース完了後RemovalPolicy.RETAIN
に変更推奨
Backup Plan設定(日次)
const dailyBackupPlan = new backup.BackupPlan(this, 'DailyBackupPlan', { backupPlanName: 'daily-backup-plan', // バックアッププラン名 backupPlanRules: [ // バックアップルール作成 new backup.BackupPlanRule({ ruleName: 'daily-backup-rule', // バックアップルール名 backupVault: backupVault, // バックアップボールトを指定 scheduleExpressionTimezone: TimeZone.ASIA_TOKYO, // 実行スケジュールのタイムゾーンを指定:JST scheduleExpression: events.Schedule.cron({ // 実行スケジュール(毎日2:00 JST) hour: '2', minute: '00', day: '*', month: '*', year: '*' }), startWindow: cdk.Duration.hours(1), // 次の時間以内に開始:1時間 completionWindow: cdk.Duration.hours(2), // 次の時間以内に完了:2時間 deleteAfter: cdk.Duration.days(1) // 保持期間:1日 }) ] });
ポイント:
- タイムゾーン: すべて
Asia/Tokyo
(JST)で統一 - スケジュール:
- 日次: 毎日 2:00 JST
- 実行時間: 1時間以内開始、2時間以内完了
- 保持期間: 要件に応じて調整可能(コードは1日設定)
Backup Selection設定(日次)
const dailyBackupResource = new backup.CfnBackupSelection(this, 'DailyBackupResource', { backupPlanId: dailyBackupPlan.backupPlanId, // バックアッププランを指定 backupSelection: { iamRoleArn: backupRole.roleArn, // IAMロールを指定 selectionName: 'daily-backup-resource', // リソース割り当て名 resources: ['arn:aws:ec2:*:*:instance/*'], // 特定のリソースタイプを含める:EC2のすべてのインスタンス conditions: { // タグを使用して選択を絞り込む StringEquals: [{ // 次と等しい ConditionKey: 'aws:ResourceTag/BackupScheduleDaily', // キー ConditionValue: 'True' // 値 }] } } });
ポイント:
- タグベース選択: 柔軟なリソース管理
- 必要なタグ:
- 日次:
BackupScheduleDaily: True
- 日次:
- 対象リソース: EC2インスタンス
動作フロー
- スケジュール開始: 設定されたCronスケジュールに従ってバックアップ開始
- タグチェック: 対象リソースのタグを確認し、バックアップ対象を特定
- バックアップ実行: AWS Backupサービスがバックアップを自動実行
- 結果通知: SNSトピック経由でメール通知
- ライフサイクル管理: 保持期間満了後の自動削除
今回実装したコンストラクトファイルまとめ
import * as cdk from 'aws-cdk-lib';
import { TimeZone } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as backup from 'aws-cdk-lib/aws-backup';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as events from 'aws-cdk-lib/aws-events';
import * as sns from 'aws-cdk-lib/aws-sns';
import * as subscriptions from 'aws-cdk-lib/aws-sns-subscriptions';
export interface BackupConstructProps {
// 必要に応じて追加のプロパティを定義
}
export class BackupConstruct extends Construct {
constructor(scope: Construct, id: string, props?: BackupConstructProps) {
super(scope, id);
//===========================================
// バックアップ監視用SNSトピック作成
//===========================================
const emailAddresses = [ // SNS通知先メーリングリスト
'xxxxxx@example.com',
'xxxxxxx@example.com'
];
const backupNotificationTopic = new sns.Topic(this, 'BackupNotificationTopic', { // バックアップ監視用のトピック
topicName: 'backup-notification-topic', // トピック名
displayName: 'AWS Backup Notification Topic' // 表示名
});
emailAddresses.forEach(email => { // バックアップ監視用のサブスクリプション
backupNotificationTopic.addSubscription(
new subscriptions.EmailSubscription(email)
);
});
//===========================================
// バックアップ用IAMロール作成
//===========================================
const backupRole = new iam.Role(this, 'BackupRole', {
roleName: 'backup-role', // バックアップロール名
assumedBy: new iam.ServicePrincipal('backup.amazonaws.com'), // AWS Backupサービスが引き受け
managedPolicies: [ // マネージドポリシー
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSBackupServiceRolePolicyForBackup'), // バックアップ用マネージドポリシー
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSBackupServiceRolePolicyForRestores'), // リストア用マネージドポリシー
]
});
//===========================================
// AWS Backup作成
//===========================================
// バックアップボールトの作成
const backupVault = new backup.BackupVault(this, 'BackupVault', { // バックアップボールトの作成
backupVaultName: 'backup-vault', // バックアップボールト名
notificationTopic: backupNotificationTopic, // バックアップ監視用SNSトピック
notificationEvents: [ // 通知イベント
backup.BackupVaultEvents.BACKUP_JOB_COMPLETED, // バックアップジョブ完了
],
removalPolicy: cdk.RemovalPolicy.DESTROY // スタック削除時にボールトを削除
});
// 要件に合わせてバックアッププランを選択する
// 日次バックアッププランの作成
const dailyBackupPlan = new backup.BackupPlan(this, 'DailyBackupPlan', {
backupPlanName: 'daily-backup-plan', // バックアッププラン名
backupPlanRules: [ // バックアップルール作成
new backup.BackupPlanRule({
ruleName: 'daily-backup-rule', // バックアップルール名
backupVault: backupVault, // バックアップボールトを指定
scheduleExpressionTimezone: TimeZone.ASIA_TOKYO, // 実行スケジュールのタイムゾーンを指定:JST
scheduleExpression: events.Schedule.cron({ // 実行スケジュール(毎日2:00 JST)
hour: '2',
minute: '00',
day: '*',
month: '*',
year: '*'
}),
startWindow: cdk.Duration.hours(1), // 次の時間以内に開始:1時間
completionWindow: cdk.Duration.hours(2), // 次の時間以内に完了:2時間
deleteAfter: cdk.Duration.days(1) // 保持期間:1日
})
]
});
// 日次バックアップのリソース割り当て
const dailyBackupResource = new backup.CfnBackupSelection(this, 'DailyBackupResource', {
backupPlanId: dailyBackupPlan.backupPlanId, // バックアッププランを指定
backupSelection: {
iamRoleArn: backupRole.roleArn, // IAMロールを指定
selectionName: 'daily-backup-resource', // リソース割り当て名
resources: ['arn:aws:ec2:*:*:instance/*'], // 特定のリソースタイプを含める:EC2のすべてのインスタンス
conditions: { // タグを使用して選択を絞り込む
StringEquals: [{ // 次と等しい
ConditionKey: 'aws:ResourceTag/BackupScheduleDaily', // キー
ConditionValue: 'True' // 値
}]
}
}
});
}
}
});
まとめ
今回は、AWS Backupサービスを使用した包括的なバックアップソリューションをAWS CDKで実装しました。
IaCとして管理することで、環境間での一貫したバックアップポリシーの展開や、設定変更の履歴管理も可能になります。 コンプライアンス要件に応じた保持期間の調整や、運用時間に合わせたスケジュール変更も容易に行えます。
皆さんのお役に立てば幸いです。