AWS Backup plan com terraform
Tags: community, aws, backup, terraform
Published: 2024-01-28 23:54:29

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8yo1qs5ncjiygzip4kkp.png)

[Código terraform aqui.](https://github.com/paulofponciano/AWSBackupAutoStack)

### **Pré-requisitos**

* [Terraform](https://www.terraform.io/downloads) instalado

* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) 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:

```tf
variable "AWS_REGION" {
  default = "us-east-1"
}
    
variable "customer_env" {
  default = "ENV_NAME"
}
```

### Construção

- Chave KMS para vault de backup:

```tf
resource "aws_kms_key" "backup_kms_key" {
  description             = join("-", [var.customer_env, "KMS-Key-Backup", var.AWS_REGION])
  deletion_window_in_days = 10
}
```

- Vault de backup criptografado:

```tf
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
}
```

- Role para backup (utilizando policy AWS):

```tf
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
}

```
- Plano de backup com regras: _daily, weekly, monthly:_

```tf
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
  ]
}
```
- Gatilho de backup e filtro de recursos:

```tf
# 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"
    }
  }
}
```

Happy building!