My DNS Auto Updater application keeps an AWS Route 53 A record pointed at your current public IP, so a subdomain always resolves to wherever your connection happens to be.
Background
My home internet connection doesn't have a static IP, but I still wanted a reliable domain name pointing at it — for reaching devices on my home network without having to remember or look up whatever address my ISP handed out that day. I already run several domains through AWS Route 53, so rather than signing up for a third-party dynamic DNS service, I built a small menu bar app that keeps a Route 53 A record in sync with my current public IP.
DNS Auto Updater sits quietly in the macOS menu bar and checks your public IPv4 address on a schedule you control, anywhere from every 5 minutes to once a day. When the address changes, it pushes a single update to the A record for a subdomain you've chosen in Route 53. If the IP hasn't changed, it does nothing — no needless API calls, no unnecessary DNS churn.
Setup is a handful of steps: enter an AWS Access Key ID and Secret, and the app validates them and loads your Route 53 hosted zones. From there you pick an existing subdomain or create a new one directly from the app, set your update frequency, and flip the service on.
Features
A few things about how it's built that I think are worth calling out:
- Credentials never touch disk. AWS keys are validated against Route 53 before being saved, then stored exclusively in the macOS Keychain. Everything else — the selected domain, sync frequency, last-updated timestamp — lives in a plist, but the keys themselves stay Keychain-only.
- One dependency. The only third-party code in the app is Soto, an AWS SDK for Swift, used here for its Route 53 client. IP lookups and everything else run on native
URLSessionand Apple frameworks. - Modern Swift concurrency throughout. The whole app is built on Swift 6 with strict concurrency checking — all the AWS and network calls are
async/await, with no completion-handler callbacks anywhere. - No privileged helper for login items. Starting the app automatically at login goes through Apple's
ServiceManagementframework, so there's no separate helper process to install, update, or worry about. - Scoped-down IAM permissions. The app only ever needs four Route 53 actions, which makes it easy to hand it an IAM user with nothing more than it actually requires:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:ListResourceRecordSets",
"route53:ChangeResourceRecordSets",
"route53:GetChange"
],
"Resource": "*"
}
]
}