It was difficult to find a good example for using the Route53 C# API for Amazon AWS. In this post I'll explain how the API works and show a few methods for adding and deleting DNS records from Amazon's Route53 system.

Understanding the Route53 API

The full documentation is available on the AWS website under the AWS SDK for .NET. This documentation gives you little more than the classes available in this  namespace.

The main area of focus in this article is for addding and removing DNS records for Route53. I only briefly explored querying the system, so you'll have to experiment on your own!

I'll explain some of the key components needed to perform the creation and deletion operations. This API uses batch requests to Route53 to perform manipulation of the DNS records. In this system, these are called ResourceRecordSets.

Additionally, you should check the request limits to ensure you are not exceeding them. Failure to properly follow this will result in exceptions being thrown while attempting to submit your requests.

AmazonRoute53Client

The class that you will be using to make your requests is the AmazonRoute53Client. This class is used to make the requests to Route53. In order to use this class you can use the AmazonClientFactory to create a new client. Once you have a client you can make requests.

var client = AWSClientFactory.CreateAmazonRoute53Client("AccessKeyID", "SecretAccessKeyID");

ChangeResourceRecordSetsRequest

The ChangeResourceRecordSetsRequest is used to make change requests to your Hosted Zone.  This object is the key to adding and deleting records.  It acts as a way to group a number of changes together into a single API call.  The two properties that need to be set are:

  1. HostedZoneId -> enter the numeric ID for your hosted zone
  2. ChangeBatch  -> groups all your change requests here

The ChangeBatch contains a collection of Change objects.

Change

The Change class represents a change that is included in the ChangeBatch. It is in this object that you specify the action to perform. The action can either be CREATE or DELETE to create a record or delete a record; imagine that. Additionally, the Change object requires setting the ResourceRecordSet property, which is a ResourceRecordSet object.

ResourceRecordSet

The ResourceRecordSet object is what we could think of a DNS record. This single object encapsulates the various types of DNS records, their name, value, TTL, and a few other Route53 configurable options. When making requests it is required that your specify the following:

  • Name -> The name of your DNS record
  • TTL -> The time to live of your record
  • Type -> The type of record (SOA, A, TXT, NS, CNAME, MX, PTR, SRV, SPF, AAAA)
  • ResourceRecords -> Objects that represent the values of the DNS record

Now that you've seen some of the objects, I'll show you how use the API.

"A" Record Example

Of primary importance is the Type property and the ResourceRecord value. Obviously the Type propety gets set to "A" for since we are creating an A Record. The value must be a valid IP address.

This example creates the following DNS record:

Type: A
TTL: 300
Name: example.com
Value: 1.2.3.4

var client = AWSClientFactory.CreateAmazonRoute53Client("AccessKeyID", "SecretAccessKeyID");

var request = new ChangeResourceRecordSetsRequest()
.WithHostedZoneId("HostedZoneId")
.WithChangeBatch(new ChangeBatch()
    .WithChanges(new Change()
        .WithAction("CREATE")
        .WithResourceRecordSet(new ResourceRecordSet()
        {
            Name = "example.com",
            Type = "A",
            TTL = 300,
            ResourceRecords = new List<ResourceRecord>()
            {
                new ResourceRecord()
                {
                    Value = "1.2.3.4"
                }
            }
        })));

client.ChangeResourceRecordSets(request);

CNAME Record Example

Similar to the A Record, you need to set the Type and ResourceRecord values correctly. In this case, change the Type property to CNAME and the ResourceRecord to point to the DNS hostname of your choice.

This example creates the following DNS record:

Type: CNAME
TTL: 300
Name: www.example.com
Value: example.com

var client = AWSClientFactory.CreateAmazonRoute53Client("AccessKeyID", :SecretAccessKeyID");

var request = new ChangeResourceRecordSetsRequest()
.WithHostedZoneId("HostedZoneId")
.WithChangeBatch(new ChangeBatch()
    .WithChanges(new Change()
        .WithAction("CREATE")
        .WithResourceRecordSet(new ResourceRecordSet()
        {
            Name = "www.example.com",
            Type = "CNAME",
            TTL = 300,
            ResourceRecords = new List<ResourceRecord>()
            {
                new ResourceRecord()
                {
                    Value = "example.com"
                }
            }
        })));

client.ChangeResourceRecordSets(request);

Helper API

Using the knowledge of how this API works, I was able to create a wrapper that makes the API easier to work with.

public class Route53Helper
{
    public Route53Helper(string hostedZoneId, string accessKeyId, string secretAccessKeyId)
    {
        this.HostedZoneId = hostedZoneId;
        this.AccessKeyId = accessKeyId;
        this.SecretAccessKeyId = secretAccessKeyId;
    }

    public string HostedZoneId { get; set; }
    public string AccessKeyId { get; set; }
    public string SecretAccessKeyId { get; set; }

    /// Adds a record to the hosted zone
    public void AddRecord(string type, string name, string value)
    {
        ChangeRecord("CREATE", type, name, value);
    }

    /// Deletes a record from the hosted zone
    public void DeleteRecord(string type, string name, string value)
    {
        ChangeRecord("DELETE", type, name, value);
    }

    protected void ChangeRecord(string action, string type, string name, string value)
    {
        var client = AWSClientFactory.CreateAmazonRoute53Client(AccessKeyID, SecretAccessKeyID);

        var request = new ChangeResourceRecordSetsRequest()
        .WithHostedZoneId(HostedZoneId)
        .WithChangeBatch(new ChangeBatch()
            .WithChanges(new Change()
                .WithAction(action)
                .WithResourceRecordSet(new ResourceRecordSet()
                {
                    Name = name,
                    Type = type,
                    TTL = 300,
                    ResourceRecords = new List<ResourceRecord>()
                    {
                        new ResourceRecord() { Value = value }
                    }
                })));

        client.ChangeResourceRecordSets(request);
    }
}

Conclusion

Hopefully from this example you can see how this library can be used to add and delete records from Route53. If you have better ways for using this API please share in the comments!