Creating Secure Backups for DynamoDB Tables with Terraform
Tags: aws, terraform, dynamodb
Published: 2024-07-03 10:43:50

Creating DynamoDB tables using Terraform is straightforward, but ensuring these tables are securely backed up is crucial for data protection and recovery. In this blog post, I will guide you through configuring secure backups for your DynamoDB tables, storing them in a secure AWS vault using Terraform. Additionally, I will explain the configuration of the cron expression used to schedule these backups.

### Step-by-Step Guide to Secure DynamoDB Backups with Terraform

### Step 1: Define Your Resources

We need to define several resources to achieve secure backups:
1. **AWS Backup Vault**: A secure vault to store backups.
2. **KMS Key**: For encrypting the backups.
3. **AWS Backup Plan**: Defines when and how often to create backups.
4. **AWS Backup Selection**: Specifies which resources to back up.
5. **IAM Role**: Grants necessary permissions to AWS Backup service.

### Step 2: Create Terraform Configuration

Here is the Terraform configuration template to set up secure backups for DynamoDB tables.

```hcl
# Define KMS Key for Backup Vault Encryption
resource "aws_kms_key" "backup_vault_key" {
  description = "KMS key for backup vault encryption"
}

# Define AWS Backup Vault
resource "aws_backup_vault" "source_backup_vault" {
  name        = "source-backup-vault"
  kms_key_arn = aws_kms_key.backup_vault_key.arn
}

# Define AWS Backup Plan
resource "aws_backup_plan" "dynamodb_backup_plan" {
  name = "dynamodb-backup"

  rule {
    rule_name         = "daily-backup"
    target_vault_name = aws_backup_vault.source_backup_vault.name
    schedule          = "cron(0 12 * * ? *)" # Daily at 12 PM UTC

    lifecycle {
      delete_after = 30 # Retain for 30 days
    }
  }
}

# Define AWS Backup Selection
resource "aws_backup_selection" "dynamodb_backup_selection" {
  plan_id      = aws_backup_plan.dynamodb_backup_plan.id
  name         = "dynamodb-backup-selection"
  iam_role_arn = aws_iam_role.backup_role.arn

  resources = [
    "<your-table-arn>"
  ]
}

# Define IAM Role for Backup
resource "aws_iam_role" "backup_role" {
  name = "backup-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect = "Allow",
        Principal = {
          Service = "backup.amazonaws.com"
        },
        Action : "sts:AssumeRole"
      }
    ]
  })

  inline_policy {
    name = "backup-policy"

    policy = jsonencode({
      Version = "2012-10-17",
      Statement = [
        {
          Effect = "Allow",
          Action = [
            "dynamodb:CreateBackup",
            "dynamodb:DeleteBackup",
            "dynamodb:DescribeBackup",
            "dynamodb:ListBackups",
            "dynamodb:ListTables",
            "dynamodb:RestoreTableFromBackup",
            "dynamodb:ListTagsOfResource",
            "dynamodb:StartAwsBackupJob",
            "dynamodb:RestoreTableFromAwsBackup"
          ],
          Resource = "*"
        },
        {
          Effect = "Allow",
          Action = [
            "backup:StartBackupJob",
            "backup:StopBackupJob",
            "backup:TagResource",
            "backup:UntagResource"
          ],
          Resource = "*"
        }
      ]
    })
  }
}
```

### Explanation of the Configuration

1. **KMS Key**: This resource `aws_kms_key` defines a KMS key used to encrypt the backups stored in the backup vault.

2. **AWS Backup Vault**: This vault `aws_backup_vault` will store the backups securely, using the KMS key for encryption.

3. **AWS Backup Plan**: This `aws_backup_plan` plan schedules the backup jobs. In this example, backups are scheduled to run daily at 12 PM UTC and are retained for 30 days.

4. **AWS Backup Selection**: This selection `aws_backup_selection` specifies which resources (DynamoDB tables) to back up.

5. **IAM Role**: This role `aws_iam_role` grants AWS Backup the necessary permissions to create, delete, describe, and list backups, as well as manage tags and restore tables.

### Working of Cron and Its Configuration

The cron expression in the `aws_backup_plan` resource specifies the schedule for the backup jobs. Here’s a breakdown of how the cron expression works:

```hcl
schedule = "cron(0 12 * * ? *)"
```

- **0**: The first field specifies the minute (0).
- **12**: The second field specifies the hour (12 PM UTC).
- **\***: The third field specifies the day of the month (any day).
- **\***: The fourth field specifies the month (any month).
- **?**: The fifth field specifies the day of the week (any day of the week).
- **\***: The sixth field specifies the year (optional field, any year).

In this example, the backup job is scheduled to run every day at 12 PM UTC.

### Conclusion

By using Terraform, you can automate the setup of secure backups for your DynamoDB tables, ensuring that your data is safely stored and easily recoverable. This approach leverages AWS Backup, KMS encryption, and IAM roles to provide a robust backup solution. Additionally, the use of cron expressions allows you to customize the backup schedule to meet your requirements. Following the steps outlined above, you can set up a secure backup system that meets your organization's data protection needs.