様々なリソースをAWS上で運用していると、RDSだけでなくEC2も定期的にバックアップを取得したくなる時があります。
そんな時にお手軽に設定できる方法を説明させて頂きます。
バックアップ取得について
以前はAWS LambdaやAWS Command Line Interfaceを利用して取得する必要がありましたが、今はCloudWatch Eventsから簡単に設定出来ます。
- まずはAWS Management ConsoleでCloudWatchダッシュボードを選択し、イベントのルールで必要な事柄を設定していきます。
- ルールの作成をします。まずはスケジュールとターゲットを設定します。
スケジュールに入れる時刻はUTCなので注意が必要です。
ターゲットの項目で[EC2 CreateSnapshot API呼び出し]を選択し、取得したいボリュームIDを入れます。
今回は例として毎朝6時(日本時間)に特定のEBSのスナップショットを取得するように設定しました。 - ルールの詳細を設定します。
CloudWatch Evensからリソースを操作するために、IAMロールが必要になります。
ここでは下記のようなRoleを使用しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:Describe*", "ec2:RebootInstances", "ec2:StopInstances", "ec2:TerminateInstances", "ec2:CreateSnapshot" ], "Resource": "*" } ] } |
以上で自動スナップショット作成が完了です。
注意点として現状ではCloudWatchEventsではSnapshotにTagをつけることができません。
バックアップの削除
さて、次はスナップショット削除の自動化についてです。
取得したスナップショットを特定の世代数で管理しましょう。
古いスナップショットの削除については、残念ながらCloudWatch Eventsでは実施出来ません。
そのため、別の方法が必要なので今回はAWS Lambda(Python3.6)を利用してみました。
- 管理したい世代数をkeep_backupsに設定します。
- ‘対象ボリュームのID’ を設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import boto3 client = boto3.client('ec2') del_tergets = [] keep_backups = 2 def del_snapshot(event, context): get_snapshots_descriptions() delete_snapshot() def get_snapshots_descriptions(): snapshots = client.describe_snapshots( Filters=[ { 'Name': 'volume-id', 'Values': ['vol-031a3841312b84bb0'] } ] ) for snapshot in snapshots['Snapshots']: if 'Tags' not in snapshot.keys(): del_tergets.append(snapshot) del_tergets.sort(key=lambda x: x['StartTime']) def delete_snapshot(): while keep_backups < len(del_tergets): client.delete_snapshot(SnapshotId=del_tergets[0]['SnapshotId']) del_tergets.pop(0) |
上記の注意点として、ボリュームIDとTagが存在していないスナップショットを削除の対象にしています。
もし手動で取得したスナップショットがある場合は、Tag付けが必要になります。
作成した関数のトリガーを設定します。
トリガータブを選択し、下記のように設定してします。
今回はスナップショット取得1時間後に削除処理が実施されるようにスケジュールしました。
以上で設定は完了です。
まとめ
CloudWatchEventsからもスナップショットの削除したいな、取得したスナップショットにTagが付けれたらな等の希望もありますが、それでも十分便利な機能ではあるので助かりますね。