How to automatically update IP addresses without using Elastic IPs on Amazon Route:53
Tags: aws, ec2, route53, elasticip
Published: 2020-06-20 14:28:10

---
title: How to automatically update IP addresses without using Elastic IPs on Amazon Route:53
published: true
date: 2020-06-09 06:21:33 UTC
tags: aws,ec2,route53,elasticip
canonical_url: https://medium.com/innovation-incubator/how-to-automatically-update-ip-addresses-without-using-elastic-ips-on-amazon-route-53-4593e3e61c4c
---

Here’s a handy way to automatically update an A-Record in Amazon Route 53 whenever an EC2 instance changes IP address.

**Scenario:** When you have a domain name in Amazon Route 53 pointing to an Amazon EC2 instance. However, if the instance is stopped and started, its public IP address changes. This breaks the A-Record since it is pointing to the wrong IP address.

**You could simply use an Elastic IP address**

Yes, using an Elastic IP address on the instance will prevent the A-Record from breaking. However, AWS gives a default limit of 5 Elastic IP addresses per region. You can request a limit increase, but in cases, you need a lot of them its still hard and still a pain.

As an example, let's assume a service providing a separate Amazon EC2 instance for each customer, to ensure secure separation of data. Each customer is given a domain name to access their server (x.medium.com). The required number of Elastic IP addresses could be _huge_.

There is a simple way to do this without elastic ip though there is a fairly simple way to achieve the objective without needing _any_ Elastic IP addresses.

![](https://cdn-images-1.medium.com/max/1024/1*I1Z12DzQ32DF0D_DVQf1kw.png)

The architecture is quite simple:

- When an EC2 instance starts, it should get its new public IP address and update its own record in Route 53
- The DNS name to update is stored in a **Tag** on the EC2 instance
- The script should execute every time the EC2 instance starts (that is, _every_ time it starts, not just the first boot)

**Implementation**

First, there should be a **Record Set in Amazon Route 53** that defines the existing domain name.

![](https://cdn-images-1.medium.com/max/880/0*on0GIGzLggMkdBSR.png)

It is currently pointing to the public IP address of an EC2 instance.

Next, add some tags to the EC2 instance that will be used by the script:

- **DNS Name:** The DNS Name to associate with the instance
- **Hosted Zone ID:** Uniquely identifies the Zone record in Route 53 that needs to be updated (get it from your Route 53 Hosted Zone record)

![](https://cdn-images-1.medium.com/max/880/0*ekVbgA8QPW2QpatT.png)

Whenever the EC2 instance starts, it will run a script that will:

- Grab the information from the above tags
- Retrieve the instance’s current public IP address
- Update the Route 53 record set with the new IP address

```
#!/bin/bash
# Extract information about the Instance
INSTANCE\_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id/)
AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone/)
MY\_IP=$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4/)

# Extract tags associated with instance
ZONE\_TAG=$(aws ec2 describe-tags --region ${AZ::-1} --filters "Name=resource-id,Values=${INSTANCE\_ID}" --query 'Tags[?Key==`AUTO_DNS_ZONE`].Value' --output text)
NAME\_TAG=$(aws ec2 describe-tags --region ${AZ::-1} --filters "Name=resource-id,Values=${INSTANCE\_ID}" --query 'Tags[?Key==`AUTO_DNS_NAME`].Value' --output text)

# Update Route 53 Record Set based on the Name tag to the current Public IP address of the Instance
aws route53 change-resource-record-sets --hosted-zone-id $ZONE\_TAG --change-batch '{"Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"'$NAME\_TAG'","Type":"A","TTL":300,"ResourceRecords":[{"Value":"'$MY\_IP'"}]}}]}'
```

To execute the script automatically each time the instance starts (as opposed to User Data scripts that only run on the _first_ boot), put the above script in this directory:

```
/var/lib/cloud/scripts/per-boot/
```

Finally, the EC2 instance will need an IAM Role assigned that has permission to run the above commands:

```
{
    "Version": "2020-06-9",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:DescribeTags",
            "Resource": "\*"
        },
        {
            "Effect": "Allow",
            "Action": "route53:ChangeResourceRecordSets",
            "Resource": "arn:aws:route53:::hostedzone/HOSTED-ZONE-ID"
        }
    ]
}
```

**How to test**

To test the script, simply **Stop** the instance then **Start** it again.

This will result in a new public IP address being assigned to the instance. The script will call Amazon Route 53 to update the record set. This might take a minute to update.

Then, return to Route 53 and look at the IP address assigned to the A-Record. It should be updated with the new IP address.

* * *