Sunday, July 23, 2017

Create a Hosted Zone using CLI

Install AWS CLI

pip install --upgrade --user awscli
aws --version


aws-cli/1.11.123 Python/2.7.10 Darwin/14.5.0 botocore/1.5.86

Configure AWS CLI

$ aws configure
AWS Access Key ID [None]: YOUR-ACCESS-KEY-ID  
AWS Secret Access Key [None]: YOUR-SECRET-ACCESS-KEY
Default region name [None]: us-east-1
Default output format [None]:

Provide the access key ID and secret access key when prompted. Accept defaults for region and format (json).

Create a Hosted Zone in Route 53

If you registered your domain with Amazon, they will automatically create a hosted zone with a set of name servers. Otherwise, you can create the name servers using Amazon CLI like this:

aws route53 create-hosted-zone --name www.clickplan.net --caller-reference 2017-07-23-13:35

{
    "HostedZone": {
        "ResourceRecordSetCount": 2, 
        "CallerReference": "2017-07-23:15:35", 
        "Config": {
            "PrivateZone": false
        }, 
        "Id": "/hostedzone/Z3F02TIXYMYTDY", 
        "Name": "www.clickplan.net."
    }, 
    "DelegationSet": {
        "NameServers": [
            "ns-1438.awsdns-51.org", 
            "ns-975.awsdns-57.net", 
            "ns-150.awsdns-18.com", 
            "ns-1978.awsdns-55.co.uk"
        ]
    }, 
    "Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/Z3F02TIXYMYTDY", 
    "ChangeInfo": {
        "Status": "PENDING", 
        "SubmittedAt": "2017-07-24T01:36:35.194Z", 
        "Id": "/change/CO73DYX4SHITQ"
    }

}

You can see that the status is pending. It will take some time for this to complete. I checked the status in the AWS console. You can see that clickplan.biz ns records was created by Amazon, since that domain was registered on Amazon. We see the ns records for the domain registered on namecheap below that we created using AWS CLI.



After few hours, we can run the following command to check the resource record sets:

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

{
    "ResourceRecordSets": [
        {
            "ResourceRecords": [
                {
                    "Value": "ns-1438.awsdns-51.org."
                }, 
                {
                    "Value": "ns-975.awsdns-57.net."
                }, 
                {
                    "Value": "ns-150.awsdns-18.com."
                }, 
                {
                    "Value": "ns-1978.awsdns-55.co.uk."
                }
            ], 
            "Type": "NS", 
            "Name": "www.clickplan.net.", 
            "TTL": 172800
        }, 
        {
            "ResourceRecords": [
                {
                    "Value": "ns-1438.awsdns-51.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"
                }
            ], 
            "Type": "SOA", 
            "Name": "www.clickplan.net.", 
            "TTL": 900
        }
    ]
}

You can see that there are two resource records have been created. One is of type NS and the other is SOA.

Retrieve a list of hosted zones.

$ aws route53 list-hosted-zones
{
    "HostedZones": [
        {
            "ResourceRecordSetCount": 2, 
            "CallerReference": "RISWorkflow-RD:3b4397e2-1ea4-4809-bb0c-b1c1714c4527", 
            "Config": {
                "Comment": "HostedZone created by Route53 Registrar", 
                "PrivateZone": false
            }, 
            "Id": "/hostedzone/Z5PP9SH99T8H9", 
            "Name": "clickplan.biz."
        }, 
        {
            "ResourceRecordSetCount": 2, 
            "CallerReference": "2017-07-23:15:35", 
            "Config": {
                "PrivateZone": false
            }, 
            "Id": "/hostedzone/Z3F02TIXYMYTDY", 
            "Name": "www.clickplan.net."
        }
    ]

}

The first record was created by Amazon when I registered clickplan.biz domain with Amazon domain registration. The second record was created by the command we ran using CLI for the clickplan.net domain that was registered with namecheap.

TO BE TESTED

The next step is to create a record set (A record and CNAME). The A record must point to the Elastic Beanstalk instance. 

 To create a new record set, first create a JSON file to describe the new record:

{
  "Comment": "CNAME record set for the zone.",
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "clickplan.net.",
        "Type": "CNAME",
        "TTL": 60,
        "ResourceRecords": [
          {
            "Value": "www.clickplan.net"
          }
        ]
      }
    }
  ]
}

aws route53 change-resource-record-sets --hosted-zone-id 1234567890ABC --change-batch file:///path/to/record.json
{
  "ChangeInfo": {
    "Status": "PENDING",
    "Comment": "A new record set for the zone.",
    "SubmittedAt": "2017-07-24T00:00:00.000Z",
    "Id": "/change/CHANGEID123"
  }
}

The status of adding the new record is currently pending. Poll the server to get the updated status:

$ aws route53 get-change --id CHANGEID123
{
  "ChangeInfo": {
    "Status": "INSYNC",
    "Comment": "A new record set for the zone.",
    "SubmittedAt": "2013-12-06T00:00:00.000Z",
    "Id": "/change/CHANGEID123"
  }
}

A new record has been created and has been propagated to all hosts.

To create a A record:

Create the JSON file with the following:

{
    "Comment": "Create A record to point to Elastic Beanstalk",
    "Changes": [
        {
            "Action": "UPSERT",
            "ResourceRecordSet": {
                "Name": "www.clickplan.net",
                "Type": "A",
                "TTL": 300,
                "ResourceRecords": [
                    {
                        "Value": "This must be elastic beanstalk : FIGURE OUT THIS PART"
                    }
                ]
            }
        }
    ]
}

aws route53 change-resource-record-sets --hosted-zone-idZ1W9BXXXXXXXLB --change-batch file:///root/change-resource-record-sets.json

Check status:

aws route53 get-change --id C2JAIG0XXXXXXX

Helpful output to create JSON file for the aws cli command:

$ aws route53 change-resource-record-sets --generate-cli-skeleton
{
    "HostedZoneId": "", 
    "ChangeBatch": {
        "Comment": "", 
        "Changes": [
            {
                "Action": "UPSERT", 
                "ResourceRecordSet": {
                    "Name": "", 
                    "Type": "SPF", 
                    "SetIdentifier": "", 
                    "Weight": 0, 
                    "Region": "eu-west-1", 
                    "GeoLocation": {
                        "ContinentCode": "", 
                        "CountryCode": "", 
                        "SubdivisionCode": ""
                    }, 
                    "Failover": "PRIMARY", 
                    "MultiValueAnswer": true, 
                    "TTL": 0, 
                    "ResourceRecords": [
                        {
                            "Value": ""
                        }
                    ], 
                    "AliasTarget": {
                        "HostedZoneId": "", 
                        "DNSName": "", 
                        "EvaluateTargetHealth": true
                    }, 
                    "HealthCheckId": "", 
                    "TrafficPolicyInstanceId": ""
                }
            }
        ]
    }

}

# This is an example that creates an A record.
$ aws route53 change-resource-record-sets --cli-input-json '{
    "HostedZoneId": "Z35CNAMBBVZ957",
    "ChangeBatch": {
        "Comment": "This is a test and may be deleted.",
        "Changes": [
            {
                "Action": "CREATE",
                "ResourceRecordSet": {
                    "Name": "noah-test.zephyrhealth.com",
                    "Type": "A",
                    "TTL": 600,
                  "ResourceRecords": [
                    {
                      "Value": "192.168.0.1"
                    }
                  ]
                }
            }
        ]
    }
}'

# You may want to test your new A record using `host`:
$ host noah-test.zephyrhealth.com
noah-test.zephyrhealth.com has address 192.168.0.1

# This updates an existin A record.
$ aws route53 change-resource-record-sets --cli-input-json '{
    "HostedZoneId": "Z35CNAMBBVZ957",
    "ChangeBatch": {
        "Comment": "This is a test A and may be deleted.",
        "Changes": [
            {
                "Action": "UPSERT",
                "ResourceRecordSet": {
                    "Name": "noah-test.zephyrhealth.com",
                    "Type": "A",
                    "TTL": 600,
                  "ResourceRecords": [
                    {
                      "Value": "192.168.1.2"
                    }
                  ]
                }
            }
        ]
    }
}'

# This creates an alias (CNAME) to an A record.
$ aws route53 change-resource-record-sets --cli-input-json '{
    "HostedZoneId": "Z35CNAMBBVZ957",
    "ChangeBatch": {
        "Comment": "This is a test CNAME and may be deleted.",
        "Changes": [
            {
                "Action": "CREATE",
                "ResourceRecordSet": {
                    "Name": "noah-test-cname.zephyrhealth.com",
                    "Type": "CNAME",
                    "TTL": 600,
                  "ResourceRecords": [
                    {
                      "Value": "noah-test.zephyrhealth.com"
                    }
                  ]
                }
            }
        ]
    }
}'

References

AWS CLI Reference