VPSで運用しているMySQLサーバをS3へバックアップ

#本稿の目的
VPSで運用しているMySQLサーバのバックアップをAWSのS3上に保存し、ローカルに保存してきたバックアップが消える恐怖から逃れること。毎日バックアップをセキュアにS3へ転送できるようにする。

MySQLのバックアップはmysqldumpを利用して取得する

#バックアップ用のバケットを作成
MySQLのバックアップを保存するS3バケットを作成する。 リージョンはTokyo(ap-northeast-1)を指定する。

* バケット名 : 
 - wk-backup-vps
* MySQLバックアップを保存するS3のプレフィクス 
 - /mysql

#IAM Userの作成
AWS上でホストしているインスタンスであればIAM RoleでS3へのアクセスを設定できるが、今回は外部のサーバ(VPS)であるため、IAM Userを作成し、Access KeyとSecret Access Keyを発行する。

今回は<strong>wkbackup</strong>というユーザ名でIAM Userを作成する。

IAM User発行時のAccess KeyとSecret Access Keyは後で使用するので保存する。 

#バケットポリシーの作成
mysqldumpで取得したバックアップをS3に転送する際に、極力アクセスは制限したいため、バックアップ転送元のIPアドレスからのみアクセスできるようにバケットポリシーを設定する。

* Principal
 - 作成したIAM UserのARNを指定
* Action
 - 取得< Get >、保存< Put >を指定
* Resource
 - 先ほど作成したバケットのARN
* IpAddress
 - S3へリクエストするホストのIPアドレスを指定

```backet-policy.json
{
	"Version": "2012-10-17",
	"Id": "S3BackupVpsPolicy",
	"Statement": [
		{
			"Sid": "S3BackupIPAllow",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::***************:user/wkbackup"
			},
			"Action": [
				"s3:GetObject",
				"s3:PutObject"
			],
			"Resource": "arn:aws:s3:::wk-backup-vps/*",
			"Condition": {
				"IpAddress": {
					"aws:SourceIp": "***.***.***.***/32"
				}
			}
		}
	]
}
```

#IAM Policyの作成
下記のIAM Policyを設定する。 先ほど作成したS3バケットにのみアクセス可能なポリシーを作成し、IAM Userにアタッチする。 

```allow-s3-access-for-backup.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1469886005000",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::wk-backup-vps",
                "arn:aws:s3:::wk-backup-vps/*"
            ]
        }
    ]
}
```

#MySQLサーバからS3へのアクセスの設定
MySQLサーバでAWS CLIを使用して、S3へバックアップを転送するキーの設定を行う。 設定はprofileを使用して、環境を指定してcliを実行できるようにする。 

##AWS CLIのインストール
AWS CLIはPythonとPipがいるので、インストールする。
※Redhat系の場合のインストール

```bash
$sudo yum -y install python python-devel python-setuptools
```
Pipのインストール

```bash
$sudo easy_install pip
```
AWS CLIのインストール

```bash
$sudo pip install awscli
```

##アクセスキー関連の設定
さきほどIAM Userを作成した際に取得したaccess keyとsecret access keyをセットアップする。

```~/.aws/credentials 
[s3backup]
aws_access_key_id = ***************
aws_secret_access_key = **********************
```

```~/.aws/config
[profile s3backup]
output = json
region = ap-northeast-1
```

##AWS CLIの設定確認
アクセスキーの設定ができているか確認する。下記コマンドを叩いて、Enterを何回か押下して、内容確認する。

```bash
$aws configure --profile s3backup
```

S3へアクセスできるか確認する。問題なければプロンプトには何も表示されないはず。

```bash
$aws s3 ls s3://wk-backup-vps/ --profile s3backup
```
#MySQLのバックアップの設定
バックアップを保存するディレクトリを作成する。

```bash
$mkdir /backup/mysql/
```
バックアップ(sqlファイル)を取得するには下記のmysqldumpを使用する。 -pの後にパスワードを入力する。 実際にdumpをとるときのユーザは、dump用の権限を作成したユーザを作成した方がよいかもしれない。 

```bash
$mysqldump -u root -p************* -x --all-databases > /backup/mysql/mysql-backup.sql
```
#MySQLサーバ→S3 cron化
上記のmysqldumpとs3へのcpをシェルスクリプトにまとめて、cronで毎日実行する

```mysql_backup_s3.sh 
#!/bin/bash
mysqldump -u root -p************* -x --all-databases > /backup/mysql/mysql-backup.sql
aws s3 cp /backup/mysql/mysql-backup.sql s3://wk-backup-vps/mysql/ --profile s3backup
```
実行権限を付与して、cron.dailyに登録する。

```bash
$chmod +x mysql_backup_s3.sh
$mv mysql_backup_s3.sh /etc/cron.daily
```
S3へ保存されているか確認する。無事データがあればOK。
cron.dailyが待てない人はmysql_backup_s3.shを実行してください。

```bash
$aws s3 ls s3://wk-backup-vps/mysql/ --profile s3backup
```