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-Email
is 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:Edit
permission for DNS zone. Details can be found here. - If the log messages get too chatty, remove or comment out one or both of the
logger
lines.
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!