Skip to content

Dynamic DNS (DDNS) tool for Azure DNS

License

Notifications You must be signed in to change notification settings

mburumaxwell/azddns

Repository files navigation

azddns โ€“ Azure Dynamic DNS CLI Tool

NuGet GitHub Workflow Status Release license

A CLI tool to update Azure DNS A or AAAA records with the current public IP address of the machine it runs on (e.g., a Pi, dev laptop, container, or VM). Intended for use cases like keeping dynamic IPs updated in Azure DNS so they can be referenced in firewall rules or other infrastructure.

Keeps records like office.maxwellweru.io or office.contoso.com up-to-date with the current public IP of dynamic endpoints. This consequently enables firewall rules to allow access based on hostname/IPs synced via azfwrmgr.

IP information sourced from ipify using https://api64.ipify.org?format=json

โœ… Features

  • Support IPv6 alongside IPv4 (i.e. AAAA and A records).
  • Support for dry run (useful to see if it will work as expected).
  • Check current IP to prevent unnecessary updates.
  • Runs on headless devices (e.g., Raspberry Pi) and in automated environments (e.g., cron jobs, ACA, AKS, ACI).
  • Support homebrew, scoop, docker and standalone binaries.

๐Ÿš€ CLI Usage

1. Interactive / Developer Mode

azddns update \
  --zone maxwellweru.io \
  --record office \
  --resource-group infra \
  --subscription personal \
  --ttl 3600 \
  --interactive \
  --dry-run
  • Uses DefaultAzureCredential with interactive browser login allowed.
  • Useful on dev laptops where az login has already been run.

2. Headless / Automated Mode

azddns run --config ~/.az-ddns/config.json
  • Uses config file instead of CLI args.
  • Designed for headless environments like:
    • Raspberry Pi
    • GitHub Actions
    • Azure Container Apps / AKS / ACI
    • systemd services

โš™๏ธ Config File Format (config.json)

{
  "subscription": "personal",
  "resourceGroup": "infra",
  "zoneName": "maxwellweru.io",
  "recordName": "office",
  "ttl": 3600,
  "interval": 900,
  "dryRun": false
}
  • subscription: Azure subscription ID or name.
  • resourceGroup: Azure resource group for the DNS zone.
  • zoneName: DNS zone name.
  • recordName: A/AAAA record to update.
  • ttl: Optional TTL (time-to-live) in seconds for the record (default: 3600).
  • interval: Optional interval in seconds to check for changes (default: 900).
  • dryRun: Optionally test the logic without actually updating the DNS records. (default: false).

๐Ÿ” Authentication Strategy

Authentication is handled using Azure.Identity's DefaultAzureCredential. It chains multiple sources as described in the official docs

Service Principal (preferred for headless)

export AZURE_TENANT_ID=ttt
export AZURE_CLIENT_ID=ccc
export AZURE_CLIENT_SECRET=sss
azddns run --config ~/.az-ddns/config.json

A managed identity is basically a service principal that you use without having to manage the credentials. System assigned managed identities are simple and no further configuration is required. For User assigned managed identity, you only need to set the AZURE_CLIENT_ID environment variable to disambiguate from any other being used by the platform such as when using ACA jobs.

๐Ÿ“ฅ Installation

The CLI tool is available for macOS, Windows and Linux. You can download each of the binaries in the releases or you can use package managers in the respective platforms.

๐ŸŽ macOS

The CLI tool is available on macOS via Homebrew:

brew install mburumaxwell/tap/azddns

๐Ÿง Linux (DEB, RPM, APK)

The CLI is also available as native packages for Linux: Debian/Ubuntu (.deb), RHEL/Fedora/AlmaLinux (.rpm), and Alpine (.apk). Download from Releases and install with:

# Example for Debian/Ubuntu
sudo dpkg -i azddns-<version>-linux-<arch>.deb

# Example for RHEL/Fedora/AlmaLinux
sudo dnf install -y azddns-<version>-linux-<arch>.rpm

# Example for Alpine
sudo apk add --allow-untrusted azddns-<version>-linux-<arch>.apk

The systemd unit file is bundled in all these formats.

๐Ÿ–ฅ๏ธ Windows

The CLI tool is available on Windows via Scoop package manager:

scoop bucket add mburumaxwell https://github.com/mburumaxwell/scoop-tools.git
scoop install azddns

๐Ÿ› ๏ธ .NET Tool

The CLI tool is available anywhere .NET is installed as a local tool or a global tool:

dotnet tool install --global azddns
azddns --help

๐Ÿณ Docker

The CLI tool is also available as a Docker image: mburumaxwell/azddns.

With the update command

docker run --rm -it \
  --env AZURE_TENANT_ID=ttt \
  --env AZURE_CLIENT_ID=ccc \
  --env AZURE_CLIENT_SECRET=sss \
  ghcr.io/mburumaxwell/azddns update \
  --zone maxwellweru.io \
  --record office \
  --resource-group infra \
  --subscription personal \
  --ttl 3600 \
  --dry-run

With a config file:

docker run --rm -it \
  --env AZURE_TENANT_ID=ttt \
  --env AZURE_CLIENT_ID=ccc \
  --env AZURE_CLIENT_SECRET=sss \
  --volume "$HOME/.az-ddns:/config" \
  ghcr.io/mburumaxwell/azddns \
  run --config /config/config.json

โšก Using Azure CLI authentication (no env vars)

If you've already authenticated locally with az login. You can mount your Azure CLI credentials into the container to enable DefaultAzureCredential pick up your local az login session automatically:

docker run --rm -it \
  --volume "$HOME/.azure:/root/.azure" \
  --volume "$HOME/.az-ddns:/config" \
  ghcr.io/mburumaxwell/azddns \
  run --config /config/config.json

๐Ÿ› ๏ธ Running with systemd (Recommended for Linux / Home Assistant Core users)

If youโ€™re using azddns on a Raspberry Pi, server, or anywhere systemd is available, you can set it up as a service for automatic startup/restarts.

![NOTE] Ensure azddns is installed before proceeding using any of the methods in this guide.

  1. Copy your config file to a system-wide location:

    sudo mkdir -p /etc/azddns
    sudo cp ~/.az-ddns/config.json /etc/azddns/config.json
  2. Create a file for environment variables:

    sudo tee /etc/azddns/env <<EOF
    AZURE_TENANT_ID=your-tenant-id
    AZURE_CLIENT_ID=your-client-id
    AZURE_CLIENT_SECRET=your-client-secret
    EOF
    
    sudo chmod 600 /etc/azddns/env
    sudo chown root:root /etc/azddns/env
  3. Copy and enable the systemd unit:

    If you have installed .deb, .rpm, or .apk, the systemd unit file is already included.

    sudo systemctl daemon-reexec
    sudo systemctl enable --now azddns

    If you are using homebrew or have downloaded the binaries, you need to copy the systemd unit file or download it from GitHub.

    sudo cp packaging/azddns.service /etc/systemd/system/azddns.service
    # You can instead download if you have not cloned the repo
    # sudo curl -o /etc/systemd/system/azddns.service -L https://raw.githubusercontent.com/mburumaxwell/azddns/main/packaging/systemd/azddns.service
    sudo systemctl daemon-reexec
    sudo systemctl enable --now azddns
  4. Check logs:

    journalctl -u azddns -f

โ˜ธ๏ธ Kubernetes Deployment

You can deploy to any Kubernetes cluster by applying the sample manifest

kubectl apply -f k8s.yaml
kubectl logs -l app=azddns -f

Alternatives

There are quite a number of alternatives but nothing quite matched what I needed. This is what I looked at:

License

The Library is licensed under the MIT license. Refer to the LICENSE file for more information.

About

Dynamic DNS (DDNS) tool for Azure DNS

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors 2

  •  
  •