RDS Snapshots using C#

Introduction

Recently, I had to work on a task to take AWS RDS snapshots using C#  programmatically. It looks pretty straightforward, but unfortunately it was not. So, I had to do some research on this and finally came across a simple solution using AWS SDK. Here, I’m going to give you some idea on how to do this using C# and .NET.

Pre-requisites

First, you need access to the AWS account which has permissions to perform snapshots of your databases. Since we are using AWS SDK to perform this task, we need Access Key and Secret key to access the AWS RDS. 

Create Solution

We are going to use two nuget packages for this demo solution.

  1. AWSSDK.RDS
  2. Microsoft.Extensions.Configuration.Abstractions

Install both packages into your solution.

RDS nuget package for RDS snapshots using C#.

config nuget package for RDS Snapshots using C#.

Once installing both packages, create a class and implement the solution. Here, I’m using appsettings json file to store AWS access key and secret just for demo.

Using Configurations, we can read them from appsettings and use it in our service class.

Code sample for RDS Snapshots using C#

using Amazon;
using Amazon.RDS;
using Amazon.RDS.Model;
using Microsoft.Extensions.Configuration;

namespace AWS_Snapshot_demo
{
    public class RDSSnapshotService 
    {

        public RDSSnapshotService(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        public async Task<bool> CreateSnapshot(string instanceId)
        {
            bool snapshotCompleted = false;

            string snapshotIdentifier = $"{instanceId}{DateTime.Now.ToString("ddMMyyyyHHmmss")}";
            Console.WriteLine($"Please wait while creating snapshot:{snapshotIdentifier}");

            var result = await TakeSnapshotAsync(instanceId, snapshotIdentifier);
            if (result != null && result.HttpStatusCode == System.Net.HttpStatusCode.OK)
            {
                DescribeDBSnapshotsResponse snapshotStatus = new();

                do
                {
                    Thread.Sleep(15000);
                    snapshotStatus = GetSnapshotStatus().Result;
                    if (snapshotStatus.DBSnapshots.FirstOrDefault(s => s.DBSnapshotIdentifier == snapshotIdentifier)?.Status == "available")
                    {
                        snapshotCompleted = true;
                    }
                    var progress = snapshotStatus.DBSnapshots.FirstOrDefault(s => s.DBSnapshotIdentifier == snapshotIdentifier);
                    Console.WriteLine($"Snapshot status:{progress?.Status} and progress:{progress?.PercentProgress}%");
                }
                while (!snapshotCompleted);

                return snapshotCompleted;
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"Error occurred during RDS API call. HTTP status code:{result?.HttpStatusCode}");
                return false;
            }
        }

        private async Task<CreateDBSnapshotResponse> TakeSnapshotAsync(string instanceId, string snapshotIdentifier)
        {
            var rdsClient = GetRDSClient();
            return await rdsClient.CreateDBSnapshotAsync(new CreateDBSnapshotRequest(snapshotIdentifier, instanceId));
        }

        private async Task<DescribeDBSnapshotsResponse> GetSnapshotStatus()
        {
            var rdsClient = GetRDSClient();
            return await rdsClient.DescribeDBSnapshotsAsync(new DescribeDBSnapshotsRequest());
        }

        private AmazonRDSClient GetRDSClient()
        {
            var awsKey = _configuration["AWSAccessKey"];
            var awsSecret = _configuration["AWSSecretAccesskey"];
            var endpoint = _configuration["AWSRegionEndpoint"];
            var regionEndPoint = RegionEndpoint.GetBySystemName(endpoint) != null ? RegionEndpoint.GetBySystemName(endpoint) : RegionEndpoint.APSoutheast1;
            var rdsClient = new AmazonRDSClient(awsKey, awsSecret, regionEndPoint);
            return rdsClient;
        }
    }
}

Code explanation for snapshots taking using C#

In GetRDSClient methos we are creating the RDS client using the credentials and AWSRegionEndpoint and returing. We need this clien to access AWS service. This RDS client has basic methods like perform snapshots, get status. 

In the main method CreateSnapshot we are passing the instance id of the database which we need to take snapshot. This is an async method and depending on our requirements, we can wait until it completes the snapshot taking. So we are checking the status time to time until it completes the process. This may take time based on the database size.

Summary

So, it seems very simple and straightforward isn’t it? Yes, of course its simple but you need to get your hands dirty with AWS SDK before you start any new tasks. However, As I feel there are no good code examples to getting started with this AWS SDK. That’s why I thought to write this post as it could help someone looking for perform RDS Snapshots using C#.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.