How to take Hourly RDS snapshots for Disaster Recovery?
Tags: aws, github, devops, rds
Published: 2022-02-08 06:13:07

Amazon RDS creates and saves automated backups of your DB instance during the backup window of your DB instance. 

* RDS creates a storage volume snapshot of your DB instance, backing up the entire DB instance and not just individual databases. 
* RDS saves the automated backups of your DB instance according to the backup retention period that you specify. 
* You can recover your database to any point in time during the backup retention period.

## Creating a DB snapshot

Amazon RDS creates a storage volume snapshot of your DB instance, backing up the entire DB instance and not just individual databases. * Creating this DB snapshot on a Single-AZ DB instance results in a brief I/O suspension that can last from a few seconds to a few minutes, depending on the size and class of your DB instance. 
* For MariaDB, MySQL, Oracle, and PostgreSQL, I/O activity is not suspended on your primary during backup for Multi-AZ deployments, because the backup is taken from the standby. 
* For SQL Server, I/O activity is suspended briefly during backup for Multi-AZ deployments. 

`Unlike automated backups, manual snapshots aren't subject to the backup retention period. Snapshots don't expire.`

### Taking Backups using AWS Cli

When you create a DB snapshot using the AWS Cli, you need to identify which DB instance you are going to back up, and then give your DB snapshot a name so you can restore from it later. 
You can do this by using the AWS Cli create-db-snapshot command with the following parameters:

   * `--db-instance-identifier`
   * `--db-snapshot-identifier`

## The Action to do this. 

The Action requires the following environment variables to be set as secrets in the repository you will be running this action from. 

* AWS_REGION -> Your AWS Region
* AWS_ACCESS_KEY_ID -> Access key ID
* AWS_SECRET_ACCESS_KEY -> Access Secret
* DB_INSTANCE_IDENTIFIER -> DB Name

The above access key should have the permission to create snapshots.
The action has a cron based trigger that runs every hour and also a manual trigger that you can run if you want to take a snapshot manually(eg snapshot before running a migration). 

```
name: Take Database Snapshots
on:
  schedule:
    - cron: '0 */1 * * *'
  workflow_dispatch:

env:
  AWS_REGION: ${{ secrets.AWS_REGION}}
  AWS_DEFAULT_OUTPUT: json
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  DB_INSTANCE_IDENTIFIER: ${{ secrets.DB_INSTANCE_IDENTIFIER }}

jobs:
  snapshot:
    runs-on: ubuntu-latest
    name: Take Database Snapshot
    steps:
      - name: Set current date & time as ENV variable
        run: echo "NOW=$(date +'%Y-%m-%d-%H-%M-%S')" >> $GITHUB_ENV

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: $AWS_ACCESS_KEY_ID
          aws-secret-access-key: $AWS_SECRET_ACCESS_KEY }}
          aws-region: $AWS_REGION
      - name: Take the Snapshot
        run: |
          aws rds create-db-snapshot --db-instance-identifier $DB_INSTANCE_IDENTIFIER --db-snapshot-identifier $DB_INSTANCE_IDENTIFIER-$NOW
```

The above GitHub action uses the AWS cli to trigger a snapshot creation .
The creation time depends on the actual db size. 
PS. AWS charges you `$0.095 per GB-Month ( us-east-1) ` for RDS snapshot storage as part of backup service .