最新 追記

雑記帳


2015-03-31 (Tue) [長年日記]

[AWS] Amazon RDSの自動バックアップによるスナップショットを保護するツールを作った

Amazon RDSは、自動バックアップ機能があって大変便利である。自動バックアップは、ポイントインタイムリカバリ用のデータの他に、定期的にスナップショットも作成する。

そのため、RDSのスナップショットには属性があり、自動バックアップによるスナップショットと、ユーザによって取得されたスナップショットの区別ができるようになっている。それぞれ、'automated'と'manual'という属性値となる。

RDSの自動スナップショットは、RDSインスタンスとライフタイムが同じであり、インスタンスを削除すると、'automated'スナップショットも消えてしまう。RDSは、インスタンスを削除する際に、ファイナルスナップショットなるものを作成できるのだが、あくまで最終的な状態のみが残せるだけで、ポイントインタイムリカバリのように、過去のデータから戻すことは出来ない。

それを緩和する方法として、スナップショットをコピーして取っておく、ということができる。自動スナップショットをコピーすることで、'manual'スナップショットを作ることができる。'manual'スナップショットは、RDSインスタンスのライフタイムとは切り離されるため、インスタンスが消えてもスナップショットは残る。

前置きが長くなった。この「自動スナップショットからマニュアルスナップショットを自動的に作成する」ためのスクリプトを作成した。

'automated'スナップショットは、Backup Windowの中で作成される。タスクスケジューラを使って、Backup Windowの後にこのスクリプトを実行すれば、常に最新のコピーを作成することができる。

導入

Rubygemsのパッケージなので、gemコマンドでインストールできる。

 $ gem install preserve-rds-snapshot

AWS認証情報(credentials)

AWSの認証情報は、AWS CLIと同様に使用することができる。thor-awsを使っているので、詳細はそちらを参照のこと。EC2上で実行するのであれば、IAM Roleが利用できる。手元の環境で実行するのであれば、--profileがおすすめ。

初期化

まずは、対象となるRDSインスタンスを初期化する。

 $ preserve-rds-snapshot init --region ap-northeast-1 --generations 5 --instance my-rds

--instanceオプションでインスタンスを指定しなかった場合は、指定したリージョンの全てのRDSインスタンスが対象となる。その他のサブコマンドも全て同様。

--generationsオプションは、スナップショットを残す世代数となる。'automated'スナップショットと違い、'manual'スナップショットは自動的に削除されないため、新しくコピーを作成した際に、指定した世代数を超えた分のスナップショットを削除するようになっている。指定しなかった場合は10となる。

初期化処理は、RDSインスタンスに'preserve-rds-snapshot'タグを付与する。値には指定した世代数が入る。

実行

スナップショットをコピーする。

 $ preserve-rds-snapshot preserve --region ap-northeast-1 --instance my-rds

preserveサブコマンドは、'preserve-rds-snapshot'タグが付与されているインスタンスの、'automated'スナップショットのうち、最新のスナップショットをコピーする。コピーする際には、インスタンスと同様に'preserve-rds-snapshot'タグを付与する。

コピー後、'preserve-rds-snapshot'タグが付与されたスナップショットのうち、指定の世代数を超えた分のスナップショットを、snapshot create timeの古いものから削除する。

'automated'スナップショットは、Backup Windowに合わせて毎日作成されるので、このスクリプトも、それに合わせて毎日実行される想定となっている。

その他

最新のスナップショット以外を対象にしたい場合は、copyサブコマンドを使って、対象となるスナップショットを指定すれば良い。

あるスナップショットを、自動削除の対象外にしたい場合は、'preserve-rds-snapshot'タグを削除すれば良い。

タグを生成する際に、AWSアカウント番号を使用する(対象のARNが必要となる)。そのため、EC2のセキュリティグループからAWSアカウント番号を取得している。EC2のDescribeSecurityGroups APIを実行する権限が必要となる(参考)。もし権限が付与できない場合は、--aws-account-numberオプションを付与すること。