AWS Backupを用いてAuroraクロスリージョンコピーしてみる(Terraform)

### 何をやるか

AWS Backupを利用して、RDSやEC2などのバックアップを自動的に取得させます。

リソースによってクロスリージョン対応しており、東京→大阪で保存してみます。

### やること

Auroraのバックアップをクロスリージョンで取得します。

今回はTerraformで用意します。

![AWSBackup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/7491b7a3-fc9d-5459-be5c-5c94e70bbddc.png)

### やってみて知れたこと

・AWSアカウントで各リージョンの設定を有効化しないと、Backup設定しても使用できなかった

→設定、及びバックアップ状況の確認は、コピー元のリージョンで行う
→バックアップリソース自体はコピー先の「保護されたリソース」に存在する

### Terraform側ベースの構成要素

```yaml
バックアッププラン
- バックアップルール設定
  - ルール名
  - バックアップボールト設定
  - 頻度
  - バックアップウィンドウ
    - default
    - custom
      - 開始時間(UTC)
      - 開始時間
      - 完了時間
  - コールドストレージへの移行
  - 保持期間
  - コピー先リージョン
  - 送信先バックアップボールド
    - コールドストレージへの移行
    - 保持期間
  - 復旧ポイントタグ(リカバリポイントに追加)
- リソースの割り当て
  - リソース割り当て名
  - IAM ロール
  - タグ
```

### 各Terraform要素

```yaml
Resource: aws_backup_global_settings
→クロスアカウントの機能有効化

Resource: aws_backup_region_settings
→各リージョンでの機能有効化

Resource: aws_backup_selection
→IAM Role, プラン, 対象リソース選択（ここがメインな感じ）

Resource: aws_backup_plan
→バックアッププラン。ボールト、スケジュール等を選択

Resource: aws_backup_vault
→ボールト設定、KMS指定

Resource: aws_backup_vault_policy
→ボールト設定に使用するポリシー

Resource: aws_backup_vault_notifications
→バックアップボールトイベント通知を、SNSトピックに設定
```

### サンプルコード

要件：Auroraを毎日AM2時(JST)でバックアップ取得し、1週間保存
今回は東京リージョンにサービス（Aurora）がある場合とします。

```jsx
# バックアップ元リージョンで、AWS Backupを有効にする（大事）
resource "aws_backup_region_settings" "backup-enable" {
  resource_type_opt_in_preference = {
    "Aurora"          = true
  }
}

# バックアップボールト
# Default KMS Setting
resource "aws_backup_vault" "standard-vault" {
  name        = "standard_backup_vault"
}

# ボールトポリシー（バックアップ実行する側）の権限
resource "aws_backup_vault_policy" "standard-vault-policy" {
  backup_vault_name = aws_backup_vault.standard-vault.name
  policy = <<POLICY
{
  "Version": "2012-10-17",
  "Id": "default",
  "Statement": [
    {
      "Sid": "default",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
		"backup:DescribeBackupVault",
		"backup:DeleteBackupVault",
		"backup:PutBackupVaultAccessPolicy",
		"backup:DeleteBackupVaultAccessPolicy",
		"backup:GetBackupVaultAccessPolicy",
		"backup:StartBackupJob",
		"backup:GetBackupVaultNotifications",
		"backup:PutBackupVaultNotifications"
      ],
      "Resource": "${aws_backup_vault.standard-vault.arn}"
    }
  ]
}
POLICY
}

# バックアッププラン
resource "aws_backup_plan" "aurora-backup" {
  name = "aurora_backup_plan"

  rule {
    rule_name         = "aurora_backup_plan_rule"
    target_vault_name = aws_backup_vault.standard-vault.name
    schedule          = "cron(0 18 * * ? *)"
    lifecycle {
      delete_after = 7
    }
  }
}

# バックアップで使用するポリシー定義（assumerole）
# assumerole policy(roleの権限を誰/どのAWSサービスに渡せるようにするか)
data "aws_iam_policy_document" "backup-assumerole" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type = "Service"
      identifiers = ["backup.amazonaws.com"]
    }
  }
}

# assumeroleを適用するrole実体
resource "aws_iam_role" "aurora-backup" {
  name = "aurora-backup"
  assume_role_policy = data.aws_iam_policy_document.backup-assumerole.json
}

# 必要な権限を定義（AWSで用意してある権限テンプレート:ServiceRoleを今回は使用）
resource "aws_iam_role_policy_attachment" "aurora-backup" {
  role = aws_iam_role.aurora-backup.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup"
}

# Resource: aws_backup_selection（ここメイン）
# 以上を用いて、バックアップを設定
resource "aws_backup_selection" "aurora-daily-cross-backupplan" {
  iam_role_arn = aws_iam_role.aurora-backup.arn
  name = "aurora-daily-cross-backup-selection"
  plan_id = aws_backup_plan.aurora-backup.id
  resources = [
    aws_rds_cluster.aurora-cluster-name.arn
  ]
}
```

以下、クロスリージョンバックアップの設定
（今回は大阪に一週間保存）

```yaml
# クロスリージョンの場合は、backup planに以下を追加
# この部分は、resource "aws_backup_plan"内に入れ込む。
copy_action {
      destination_vault_arn = "arn:aws:backup:ap-northeast-3:${var.acountid}:backup-vault:Default"
      lifecycle {
          delete_after       = 7
        }
    }
```


以上となります。
リージョンを跨いだバックアップができるのはとても助かります。。