DEV Community

Paulo Ponciano
Paulo Ponciano

Posted on • Originally published at Medium

AWS Backup plan com terraform

Construir um plano de backup através da console de gerenciamento AWS é uma tarefa simples, mas que pode consumir um tempo relevante no projeto se o objetivo é implementar vários ambientes ou até mesmo para um simples laboratório.

Dessa forma, podemos automatizar ao máximo essa tarefa e ter a tranquilidade de que o proposto será implementado via código sem variações.

Image description

Código terraform aqui.

Pré-requisitos

  • Terraform instalado

  • AWS CLI instalado

  • Credenciais da conta alvo configuradas localmente

O que esperar

Backup dos recursos que possuam ResourceTag/Backup com valor ‘yes’ e sejam do tipo Volume EC2 (EBS), RDS ou EFS.

  • Horário: 5AM (UTC)/2AM (UTC-3)

  • Retenção: 7 dias (diário), 14 dias (semanal), 90 dias (mensal)

  • Diário: execução diária

  • Semanal: execução todo domingo

  • Mensal: execução todo dia 1 do mês

Variáveis

Basicamente é tudo que precisa informar em todo processo:

variable "AWS_REGION" {
  default = "us-east-1"
}

variable "customer_env" {
  default = "ENV_NAME"
}
Enter fullscreen mode Exit fullscreen mode

Construção

  • Chave KMS para vault de backup:
resource "aws_kms_key" "backup_kms_key" {
  description             = join("-", [var.customer_env, "KMS-Key-Backup", var.AWS_REGION])
  deletion_window_in_days = 10
}
Enter fullscreen mode Exit fullscreen mode
  • Vault de backup criptografado:
resource "aws_backup_vault" "backup_vault" {
  name        = join("-", [var.customer_env, "backup-vault", var.AWS_REGION])
  kms_key_arn = aws_kms_key.backup_kms_key.arn
}
Enter fullscreen mode Exit fullscreen mode
  • Role para backup (utilizando policy AWS):
data "aws_iam_policy_document" "backup_policy_document" {
  statement {
    actions = ["sts:AssumeRole"]
    effect  = "Allow"
    principals {
      type        = "Service"
      identifiers = ["backup.amazonaws.com"]
    }
  }

  version = "2012-10-17"
}

data "aws_iam_policy" "backup_iam_policy" {
  name = "AWSBackupServiceRolePolicyForBackup"
}

resource "aws_iam_role" "backup_role" {
  name               = join("-", [var.customer_env, "backup-role", var.AWS_REGION])
  assume_role_policy = data.aws_iam_policy_document.backup_policy_document.json
}

resource "aws_iam_role_policy_attachment" "backup_policy_attach" {
  policy_arn = data.aws_iam_policy.backup_iam_policy.arn
  role       = aws_iam_role.backup_role.name
}

Enter fullscreen mode Exit fullscreen mode
  • Plano de backup com regras: daily, weekly, monthly:
resource "aws_backup_plan" "main-backup-plan" {
  name = join("-", [var.customer_env, "backup-plan", var.AWS_REGION])

  # REGRA DE BACKUP DIÁRIO
  rule {
    completion_window = 300
    rule_name         = "DailyBackups"
    schedule          = "cron(0 5 ? * * *)"
    start_window      = 120
    target_vault_name = join("-", [var.customer_env, "backup-vault", var.AWS_REGION])

    lifecycle {
      cold_storage_after = 0
      delete_after       = 7
    }
  }

  # REGRA DE BACKUP SEMANAL
  rule {
    completion_window = 300
    rule_name         = "WeeklyBackups"
    schedule          = "cron(0 5 ? * 1 *)"
    start_window      = 120
    target_vault_name = join("-", [var.customer_env, "backup-vault", var.AWS_REGION])

    lifecycle {
      cold_storage_after = 0
      delete_after       = 14
    }
  }

  # REGRA DE BACKUP MENSAL
  rule {
    completion_window = 300
    rule_name         = "MonthlyBackups"
    schedule          = "cron(0 5 1 * ? *)"
    start_window      = 120
    target_vault_name = join("-", [var.customer_env, "backup-vault", var.AWS_REGION])

    lifecycle {
      cold_storage_after = 0
      delete_after       = 90
    }
  }

  depends_on = [
    aws_backup_vault.backup_vault
  ]
}
Enter fullscreen mode Exit fullscreen mode
  • Gatilho de backup e filtro de recursos:
# GATILHO DE BACKUP
resource "aws_backup_selection" "backup-selection" {
  iam_role_arn = aws_iam_role.backup_role.arn
  name         = "Backup-yes"
  plan_id      = aws_backup_plan.main-backup-plan.id

  resources = [
    "arn:aws:ec2:*:*:volume/*",
    "arn:aws:elasticfilesystem:*:*:file-system/*",
    "arn:aws:rds:*:*:db:*"
  ]

  condition {
    string_equals {
      key   = "aws:ResourceTag/Backup"
      value = "yes"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Happy building!

Top comments (0)