kakakakakku blog

Weekly Tech Blog: Keep on Learning!

AWS Backup で Amazon EC2 インスタンスをバックアップする構成を Terraform で構築する

AWS Backup で Amazon EC2 インスタンスをバックアップする構成を Terraform で構築する検証をしたので簡単にまとめておこうと思う💡 設定によっても異なるけど今回は大きく以下のリソースを使って構築した.

AWS Backup の設定としては以下のように仮置きしている👌

  • リソースタイプは EC2 に限定する
  • バックアップ対象にする Amazon EC2 インスタンスにはタグ Backup: true を追加しておく
  • 日本時間 6:00 に実行する(UTC だと 21:00
  • 7日後に有効期限切れとする

ちなみに AWS Backup で開始時間を設定するときに Asia/Tokyo (UTC+09:00) などタイムゾーンを設定する新機能が 8/29 にリリースされてるけど,現時点では Terraform ではまだサポートされてなく,UTC 前提で schedule を設定する必要がある.近いうちに ScheduleExpressionTimezone をサポートできるようになるはず🕐 期待〜 \( 'ω')/

aws.amazon.com

Terraform コード

リソースタイプを EC2 に限定するために aws_backup_selectionresourcesarn:aws:ec2:*:*:instance/* と設定している📝

data "aws_caller_identity" "current" {}

locals {
  account_id = data.aws_caller_identity.current.account_id
}

resource "aws_backup_vault" "sandbox" {
  name = "sandbox"
}

resource "aws_backup_plan" "sandbox" {
  name = "sandbox"

  rule {
    rule_name         = "daily-7days-retention"
    target_vault_name = aws_backup_vault.sandbox.name
    schedule          = "cron(0 21 * * ? *)"

    lifecycle {
      delete_after = 7
    }
  }
}

resource "aws_backup_selection" "ec2" {
  name         = "ec2-backup-resources"
  plan_id      = aws_backup_plan.sandbox.id
  iam_role_arn = aws_iam_role.aws_backup.arn
  resources    = ["arn:aws:ec2:*:*:instance/*"]

  condition {
    string_equals {
      key   = "aws:ResourceTag/Backup"
      value = "true"
    }
  }
}

resource "aws_iam_role" "aws_backup" {
  name               = "aws-backup-role"
  assume_role_policy = data.aws_iam_policy_document.assume_aws_backup.json

  inline_policy {
    name   = "iam-pass-role"
    policy = data.aws_iam_policy_document.iam_pass_role.json
  }
}

resource "aws_iam_role_policy_attachment" "aws_backup_for_backup" {
  role       = aws_iam_role.aws_backup.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup"
}

resource "aws_iam_role_policy_attachment" "aws_backup_for_restores" {
  role       = aws_iam_role.aws_backup.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores"
}

data "aws_iam_policy_document" "iam_pass_role" {
  version = "2012-10-17"
  statement {
    actions = [
      "iam:PassRole"
    ]
    resources = [
      "arn:aws:iam::${local.account_id}:role/xxxxx"
    ]
  }
}

data "aws_iam_policy_document" "assume_aws_backup" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["backup.amazonaws.com"]
    }
  }
}

あと今回リストア用に管理ポリシー AWSBackupServiceRolePolicyForRestores を追加しているけど,実際にリストアをするときに Amazon EC2 インスタンスに IAM Role を引き渡すためには iam:PassRole の権限も必要になるとドキュメントに書いてある.よって,今回はインラインポリシーを使って特定の IAM Role に対する iam:PassRole を許可してある✌️

docs.aws.amazon.com

結果

期待通りに構築できた❗️

実際に1週間ほど運用してみて期待通りに動いてくれた〜 \( 'ω')/