Having just wrapped a post on keeping FreeIPA DNS records correctly reflecting a GCP instance’s dynamic IP address, I figured I would do the same for Cloudflare DNS since I use both. This will be very to-the-point, so post a comment or send an email if any clarification is needed. In a nutshell, this is how I approached keeping my Cloudflare DNS record for gcloud.cthudson.com up to date given my free-tier e2-micro instance having a dynamic IP address.
Google Cloud CLI
First off, install the google-cloud-cli tool. OS-dependent docs over at Google can be found here. I happen to be running Fedora on this instance and went the generic Linux route (for some reason, although there is a dnf route as well):
Pull down archive with wget
$ wget https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-455.0.0-linux-x86_64.tar.gz
Extract archive
$ tar xzvf google-cloud-cli-455.0.0-linux-x86_64.tar.gz
Install
$ ./google-cloud-sdk/install.sh
Initialize gcloud
$ ./google-cloud-sdk/bin/gcloud init
Test
$ ./google-cloud-sdk/bin/gcloud compute instances list
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
fedora-e2-micro us-east1-b e2-micro 10.142.0.2 34.73.48.111 RUNNING
The Script
Now that we have the gcloud cli tool up and running, we can use that to determine our instances public IP to compare against what’s in Cloudflare and updating if necessary (I named this script gcp_cloudflare_dns_updater.sh for reference):
#!/bin/bash
LOCALIP=`./google-cloud-sdk/bin/gcloud compute instances describe fedora-e2-micro | grep natIP | sed s/"natIP: "//g | xargs`
ZONEID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=cthudson.com&status=active" \
-H "X-Auth-Email: <email>" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" | grep id | cut -d'"' -f6)
DNSRECORDID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records?type=A&name=gcloud.cthudson.com" \
-H "X-Auth-Email: <email>" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" | grep id | cut -d'"' -f6)
CURRENTDNSIP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records?type=A&name=gcloud.cthudson.com" \
-H "X-Auth-Email: <email>" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" | grep id | cut -d'"' -f26)
if [[ "$LOCALIP" == "$CURRENTDNSIP" ]]; then
/usr/bin/logger "VM natIP matched Cloudflare gcloud.cthudson.com record. No update necessary."
exit
else
curl --request PUT \
--url https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records/$DNSRECORDID \
--header 'Content-Type: application/json' \
--header 'X-Auth-Email: <email>' \
--header 'Authorization: Bearer <token>' \
--data '{
"content": "'"$LOCALIP"'",
"name": "gcloud.cthudson.com",
"proxied": false,
"type": "A",
"comment": "Domain verification record",
"ttl": 3600
}'
/usr/bin/logger "VM natIP did not match Cloudflare gcloud.cthudson.com record. Updated."
fi
Script Callouts
- Change domain references to your domain, of course.
X-Auth-Emailis the email (login) associated with the Cloudflare account managing your blog domain.- The Bearer
<token>is created via the Cloudfare admin panel and needs theDNS:Editpermission for DNS zone. Details can be found here. - If the log messages get too chatty, remove or comment out one or both of the
loggerlines.
Running
In my case, I rely on cron to perform a check every 5 minutes by placing the following in a file under /etc/cron.d/dns:
*/5 * * * * <user> /path/to/gcp_cloudflare_dns_updater.sh
Cheers!