dynamic-route53/README.md

1 line
13 KiB
Markdown
Raw Permalink Normal View History

# Dynamic DNS hostnames with Route53 and EC2 I keep a lot of one-off EC2 instances for specialty tasks that I do once in a while. I have a FreeBSD instance, a phpMyAdmin instance, a forensic analysis instance, and so on. It's a good practice with AWS EC2 to stop these instances when they aren't needed. It means that I don't pay for instance hours that I'm not using. I start them, do what I need to do, and then stop them when I'm done. I assign public IP addresses to these instances so that I can reach them, but the instance gets a new IP public address each time it starts up. Rather than looking up the new public IP address each time the instance starts, I want to use a DNS name to reach it. I need an A record in DNS to be updated each time the instance boots, so that I can reach it by name, instead of looking up its new public IP address every time I start it. In this blog post I provide a script that runs at boot time to update DNS each time an instance boots with a public IP. The script figures out the DNS record that needs to be created by looking at the instance metadata, and then it updates records in the right zone in Route53. Because the script pulls all the important information from the instance metadata, there's no unique code or configuration that has to be installed on the instance. I just install this one script and it will figure out the rest from EC2 metadata. If you launch an instance from an AMI, and you tag that instance correctly and you put the instance into the right role, this will work without any changes specific to the individual instance itself. # Assumptions To make this work, you need a few things before you start. I am not going to describe how to do them. 1. You need a public hosted zone in Route53 2. You need python and boto3 installed in your instance 3. You need to create your own AMI, or your own way of customising instances after launch. Public hosted zones are described in the Route53 documentation, and installing python and boto3 are described in the boto3 documentation. # Overview The process looks like this. 1. Create a dynamic subzone for these host names 2. Create a policy that allows editing the subzone 3. Create a role and attach the policy to it (or attach the policy to an existing role) 4. Load the script onto the instance and enable it at boot time 5. Launch an instance with the role and correct tags # Create a Hosted DNS Zone In the interest of security, we want a dedicated zone for these dynamic host names. We don't want to grant EC2 instances the privilege of writing into our top-level zone. For example, if your organisation is “example.com”, you don't want EC2 instances launching that have rights to modify DNS records in the example.com domain. In this example, I'll use a subzone of example.com, `ec2.example.com`, for all my dynamic host names. You can imagine uses like `dev.example.com`, `test.example.com`, `sandbox.example.com`, and so on. We can grant permissions to modify one specific hosted domain without worrying about unauthorised changes to `example.com` itself. This also works if `example.com` is not running in Route53, but we want `ec2.example.com` to be dynamic and hosted in Route53. It requires cooperation with the `example.com` domain owner, but just once. ## Create the Subzone In the AWS Console, create a zone called ec2.example.com. This is not a record set in example.com whose name is “ec2” (we'll create one of those in a second). First you create a new hosted zone. ## Capture Some Details When you create the hosted zone, you immediately see some NS records. It's a list of DNS server names. Copy these NS records. You will also see a Hosted Zone ID. It looks like this: ZZ123ABCD123. Make note of that ID for future use. ## Create the Glue Records Go to your example.com hosted zone and create a record set. 1. For the name, choose whatever subzone you're creating. In my case, I type `ec2` so that I am creating a record set `ec2.example.com.` 2. For the record set type, choose “NS Name Server”. 3. In the Value box, paste the na