Introduction

AWS Route 53 is a Domain Name System (DNS) service provided by AWS. In this article, we will look at how to use the AWS CLI to perform common Route 53 operations.

Table of contents

Prerequisites

  • AWS CLI
  • AWS Credentials: If you haven’t setup your AWS credentials before, this resource from AWS is helpful.

How to create a hosted zone?

We will use the create-hosted-zone subcommand to create a new hosted zone. A hosted zone is similar to a traditional DNS file. It represents a collection of records that are managed together and these records belong to a single parent domain. All resource records within a hosted zone should end with the hosted zone’s domain as a suffix.

Some of the required parameters for this command are:

  • name: Domain name for the hosted zone
  • caller-reference: A unique identifier for the request. This string needs to be unique every time you use the command.

In the following example, this command creates a new hosted zone for the domain mytestdomain.com:

aws route53 create-hosted-zone --name mytestdomain.com --caller-reference 2-3-2022

Output:

{
    "Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/Z06370XXXXX",
    "HostedZone": {
        "Id": "/hostedzone/Z06370XXXXX",
        "Name": "mytestdomain.com.",
        "CallerReference": "2-3-2022",
        "Config": {
            "PrivateZone": false
        },
        "ResourceRecordSetCount": 2
    },
    "ChangeInfo": {
        "Id": "/change/C022909328XR6FZ964JJ8",
        "Status": "PENDING",
        "SubmittedAt": "2022-02-04T04:24:17.206000+00:00"
    },
    "DelegationSet": {
        "NameServers": [
            "ns-696.awsdns-23.net",
            "ns-1669.awsdns-16.co.uk",
            "ns-1319.awsdns-36.org",
            "ns-209.awsdns-26.com"
        ]
    }
}

AWS provides the NameServers record for all new hosted zones. If your domain is registered outside of AWS, you would provide these nameservers to your domain provider.

How to list all hosted zones?

We will use the list-hosted-zones subcommand to list all hosted zones in our account.

aws route53 list-hosted-zones

Output:

{
    "HostedZones": [
        {
            "Id": "/hostedzone/Z06370XXXXX",
            "Name": "mytestdomain.com.",
            "CallerReference": "2-3-2022",
            "Config": {
                "PrivateZone": false
            },
            "ResourceRecordSetCount": 2
        }
    ]
}

How to add or delete any resource records in a hosted zone?

After creating a hosted zone, we will be using the change-resource-record-sets subcommand to create Resource records for our hosted zone. This record would contain authoritative DNS information for a specified domain or subdomain. This command supports the following actions:

  • CREATE: Creates a recordset that has the specified values
  • DELETE: Deletes an existing record that has the specified value
  • UPSERT: If a resource record set does not already exist, AWS creates it. If a resource set does exist, Route 53 updates it with the values in the request.

The required arguments for this command are:

  • hosted-zone-id: Id for the hosted zone you want to modify
  • change-batch: Contains the actual changes that we want to apply.

We will be providing a JSON file as input to the change-batch argument. The contents of the file are as follows:

{
    "Comment": "Update record to add new CNAME record",
    "Changes": [
        {
            "Action": "UPSERT",
            "ResourceRecordSet": {
                "Name": "sub.mytestdomain.com.",
                "Type": "CNAME",
                "TTL": 300,
                "ResourceRecords": [
                    {
                        "Value": "google.com"
                    }
                ]
            }
        }
    ]
}

We want to use the UPSERT action to add a new CNAME record for a subdomain in our hosted zone.

We will invoke the command like this:

aws route53 change-resource-record-sets --hosted-zone-id Z06370712F3OMF8G17950 --change-batch file://change-config.json

Output:

{
    "ChangeInfo": {
        "Id": "/change/C00854841UU4NWG0R4GZU",
        "Status": "PENDING",
        "SubmittedAt": "2022-02-04T04:31:21.655000+00:00",
        "Comment": "Update record to add new CNAME record"
    }
}

How to query the status of a change?

We will use the get-change subcommand to query the status of a change operation we invoked. In the previous example, our change status was PENDING. We will use this command to see if our change has been synced.

aws route53 get-change --id C00854841UU4NWG0R4GZU

Output:

{
    "ChangeInfo": {
        "Id": "/change/C00854841UU4NWG0R4GZU",
        "Status": "INSYNC",
        "SubmittedAt": "2022-02-04T04:31:21.655000+00:00",
        "Comment": "Update record to add new CNAME record"
    }
}

It looks like our change has been synced and should be available.

How to create a new traffic policy?

AWS Route 53 allows you to create different routing configurations to specify how traffic should be routed to the specified domain or subdomain. We will be using the create-traffic-policy subcommand to create the traffic policy.

The Traffic policy document has a specific format that can be found here.

We will create a traffic policy to use a weighted Rule to route traffic between three endpoints. The policy looks like this:

{
  "AWSPolicyFormatVersion":"2015-10-01",
  "RecordType":"A",
  "StartRule":"round_robin",
  "Endpoints":{
    "srv1":{
      "Type":"value",
      "Value":"192.0.2.1"
    },
    "srv2":{
      "Type":"value",
      "Value":"192.0.2.2"
    },
    "srv3":{
      "Type":"value",
      "Value":"192.0.2.3"
    }
  },
  "Rules":{
    "round_robin":{
      "RuleType":"weighted",
      "Items":[
        {
          "EndpointReference":"srv1",
          "Weight":"3"
        },
        {
          "EndpointReference":"srv2",
          "Weight":"1"
        },
        {
          "EndpointReference":"srv3",
          "Weight":"1"
        }
      ]
    }
  }
}

Now that we have a policy, we can create the policy like this:

aws route53 create-traffic-policy --name weighted-traffic-policy --document file://traffic-policy.json

Output

{
    "Location": "https://route53.amazonaws.com/2013-04-01/trafficpolicy/d48c57d7-8eb7-4869-b1c3-xxxx/1",
    "TrafficPolicy": {
        "Id": "d48c57d7-8eb7-4869-b1c3-xxxx",
        "Version": 1,
        "Name": "weighted-traffic-policy",
        "Type": "A",
        "Document": "{\n  \"AWSPolicyFormatVersion\":\"2015-10-01\",\n  \"RecordType\":\"A\",\n  \"StartRule\":\"round_robin\",\n  \"Endpoints\":{\n    \"srv1\":{\n      \"Type\":\"value\",\n      \"Value\":\"192.0.2.1\"\n    },\n    \"srv2\":{\n      \"Type\":\"value\",\n      \"Value\":\"192.0.2.2\"\n    },\n    \"srv3\":{\n      \"Type\":\"value\",\n      \"Value\":\"192.0.2.3\"\n    }\n  },\n  \"Rules\":{\n    \"round_robin\":{\n      \"RuleType\":\"weighted\",\n      \"Items\":[\n        {\n          \"EndpointReference\":\"srv1\",\n          \"Weight\":\"3\"\n        },\n        {\n          \"EndpointReference\":\"srv2\",\n          \"Weight\":\"1\"\n        },\n        {\n          \"EndpointReference\":\"srv3\",\n          \"Weight\":\"1\"\n        }\n      ]\n    }\n  }\n}\n"
    }
}

How to list all resource records for a hosted zone?

We will use the list-resource-record-sets method to list all resource records in a particular hosted zone.

aws route53 list-resource-record-sets --hosted-zone-id Z06370XXXXX

Output:

{
    "ResourceRecordSets": [
        {
            "Name": "mytestdomain.com.",
            "Type": "NS",
            "TTL": 172800,
            "ResourceRecords": [
                {
                    "Value": "ns-696.awsdns-23.net."
                },
                {
                    "Value": "ns-1669.awsdns-16.co.uk."
                },
                {
                    "Value": "ns-1319.awsdns-36.org."
                },
                {
                    "Value": "ns-209.awsdns-26.com."
                }
            ]
        },
        {
            "Name": "mytestdomain.com.",
            "Type": "SOA",
            "TTL": 900,
            "ResourceRecords": [
                {
                    "Value": "ns-696.awsdns-23.net. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"
                }
            ]
        },
        {
            "Name": "policy.mytestdomain.com.",
            "Type": "A",
            "TTL": 300,
            "ResourceRecords": [
                {
                    "Value": "1.2.3.4"
                },
                {
                    "Value": "8.8.8.8"
                },
                {
                    "Value": "123.123.123.123"
                }
            ]
        },
        {
            "Name": "sub.mytestdomain.com.",
            "Type": "CNAME",
            "TTL": 300,
            "ResourceRecords": [
                {
                    "Value": "google.com"
                }
            ]
        }
    ]
}