I occasionally need to SSH into my laptop, or use other services hosted on it, but my ISP gives me a dynamic IP. While it is stable most of the time, it does occasionally change.

To work around this, I had previously set up a cron job that curl’s a specific URL on my website, and I could get the IP by grep-ing through my server logs. But this is both time-consuming and requires me to update the IP address on different applications every time it changes.

I wanted to have a subdomain that always pointed to my laptop, so I used the AWS CLI to create a DIY dynamic DNS. It fetches your IP from the AWS endpoint, but any source can be used. You can also host this on a server or a serverless function to get the client IP and require less dependencies.

Here’s the shell script that runs every X minutes on my laptop in order to update the domain record.

#!/bin/sh

IP="$(curl -s http://checkip.amazonaws.com/)"

DNS="$(mktemp)"

cat > "${DNS}" <<EOF
{
  "Comment": "DDNS update",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "ResourceRecords": [
          {"Value": "${IP}"}
        ],
        "Name": "subdomain123.gkbrk.com",
        "Type": "A",
        "TTL": 300
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
    --hosted-zone-id "/hostedzone/ZONEID" \
    --change-batch "file://${DNS}"

rm "${DNS}"