Amazon S3へのデータバックアップと世代管理設定

「重要なデータはクラウドバックアップ！」的なことが当たり前になりつつあるご時世ですが、バックアップデータのバージョン管理（世代管理）やライフサイクル設定の記事は意外と少ないです。今回はクラウドバックアップしているデータを復旧させるときにどの時点まで戻せるか（RPO）を考慮して、Amazon S3 へデータバックアップを行う場合の設定をお試ししたいと思います。

# 今回のゴール
毎日定時にサーバ内のデータをAmazon S3へバックアップし、５世代前まで保存する環境を構築する。（古い世代のデータは古い順に自動的に削除していく）

# 完成イメージ
![Qiita_S3＿概要図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/16aeaaf3-72b5-d0c1-99f5-f0d9e3b00670.png)

# 前提条件
 - 定期的にAmazon S3へデータバックアップできるサーバもしくはNAS がある　※今回はEC2を使います
 - バックアップ先として利用するのはAmazon S3（Standard）

# 設定概要
[1] Amazon S3 のバケットの作成および世代管理、ライフサイクルの設定
[2] EC2 にS3へのアクセス権を持つIAMロールのアタッチ
[3] サーバ側のタスクスケジューラーにバックアップジョブの設定

# やってみた
まず[1]の設定ですが以下のように設定します。
該当のバケットを選択し、「プロパティ」をクリックする

①設定したいバケットのバージョニングを有効にする
![S3_バックアップ有効化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/d9bf7c9f-1db7-f228-2c36-4900cd70be77.png)
「編集する」をクリックし、「有効にする」へ変更
![バックアップ編集.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/10d5a24f-be9d-b363-4a73-cef7c285bb87.png)


②設定したいバケットで以下のライフサイクルルールを設定する
![ライフサイクル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/dc4938a1-c5b1-50f3-c390-7777de894d65.png)
![ライフサイクル２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/952f89ba-0575-da5a-a721-e0e5a6ec3cfd.png)

バケット内の特定のフォルダにルールを適用させたい場合は「１つ以上のフィルターを～」の方を選択してください。

- アクションで「オブジェクトの現行バージョニングの有効期限が切れる」を設定し、オブジェクト作成後の日数を"1" に設定

- アクションで「オブジェクトが以前のバージョンを完全に削除する」を設定し、オブジェクトが以前のバージョンになってからの日数を”5”に設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/314a1ec5-a227-9a26-ec57-ca46ed7b5010.png)


上記の設定により、アップロード後1日で、有効期限切れというフラグが立ち、5日後に有効期限切れのデータを削除するというライフサイクルを設定することができます。
これでS3バケット側の設定は完了です。

続いて[2]の設定を行います。
EC2へのIAMロールのアタッチは以前別の記事で書きましたのでご参考までに。
[Amazon EC2(Amazon linux)から直接S3へのファイルコピー](https://qiita.com/u-bayashi/items/89718b1f567a93486e4a)

最後にAWS CLI　のコマンドでS3バケットへデータをバックアップするバッチをサーバのタスクスケジューラーに登録して、自動更新してくれるようにします。
今回はEC2のCドライブ直下に「Xフォルダ」を作成し、その中のデータをS3へアップロードする設定にしたいと思います。
　※タスクスケジューラー設定前に事前にXフォルダの作成とデータの格納は手動で行っておいてください。

バッチファイルの中身は以下のような感じです。

    # Cドライブ直下のXフォルダに移動
    pushd C:\X
    # Xフォルダの中身をフォルダごとS3バケットに同期
    aws s3 sync . s3://{S3バケット名}/ --delete

コマンド構文は
aws s3 sync {同期元} {同期先}/ {オプション}という形です。
ちなみに"--delete" は同期元にないデータは同期先から削除するオプションです。

このバッチファイルをこんな感じでサーバのタスクスケジューラーに登録して、毎日定時で動作するようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/ff5b3a63-c6ac-e34d-8802-d769e82dcd3d.png)
サーバ側ではフォルダの中はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/7cbbfe17-71da-a869-1a49-5ee8aff5ce0b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/0d42e5ae-2f05-a2d1-ee22-448d089b0f10.png)

上手くコマンドが動作して、同期できるとS3側だと以下のように見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/1cd3f2c5-9d73-dcc2-968b-6e0787b8f5d1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/b97673dc-2de5-03f6-203e-3d1868a102da.png)


指定した日数が経過するとこんな感じで削除マーカがついて、古いデータが消されたようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/b8c4d881-44e7-fa6e-4c61-75d4ae6dc14c.png)


# 注意点
##### バケットへのデータを差分バックアップにしていると一定時間更新されていないファイルはS3バケットから削除される？
これはライフサイクルの「オブジェクトの現行バージョニングの有効期限が切れる」という設定が影響しています。初回にバックアップデータとしてアップロードされてからそれ以降の更新がないデータの場合、１世代目がアップロードされてから指定した期間で現行バージョンの有効期限が切れて、**<font color="Red">指定期間後に「以前のバージョンを削除する」設定</font>**により、削除するという動きになるようです。
更新するフォルダとしないフォルダがある場合はライフサイクル適応のオプションでプレフィックス（フォルダパス）を指定してやりましょう。
差分バックアップではなく、更新しないデータもそのまま上書きされるのであれば、全部のデータがごっそり更新されていくので問題ないと思われます。
##### aws cli でフォルダごとバックアップときはcp ではなく、sync を利用する
cpは特定のファイルをコピーする場合で、フォルダ（ディレクトリ構造）はコピーできません。代わりにsyncを利用すればフォルダごとコピー可能です。※--recursiveオプションを使う方法もあるようですが上手くいきませんでした...
##### 時間設定について
○○日後などのタイムスケジュールを登録する際にその時間はUTCなのか、日本時間なのかをよく確認しておきましょう。日本時間の0:00に動作すると思っていたら9:00(日本時間はUTC+9時間)に動作するようになっていたということにならないように...

# おわりに
需要がありそうな機能なのに、検索してもあまり設定内容紹介の記事が出てこないので、書いてみました。
AWSのBusinessSupportに問い合わせて「それでいいと思う」的な回答はもらいましたが間違っていたら、あしからずm(_ _)m そしてご指摘頂けると幸いです。