It is further assumed that you are using the Google Cloud DNS for foo.bar.com (that is, the dns name is “foo.bar.com.”) With the zone name “foo-bar-com” in the same project as your virtual machine and that your virtual machine has a configuration parameter "This instance has full API access for all Google Cloud services." selected. Your virtual machine will be called "my-vm.foo.bar.com" in DNS.
I am sure that this can be changed accordingly to work with DNS in another project and / or more limited permissions.
Perhaps it’s worth noting: it is assumed that you are using the “Google Cloud DNS” and not the (simple) Google Domains registrar, if you use the latter (to host your DNS, and not just as a registrar), then they have direct support for synthetic dynamic IP -addresses with some dyndns, such as the update mechanism (but they are more limited by other methods).
Also note that for a successful transaction there should already be a record with the correct IP and the correct TTL (i.e., at the first start you can delete any record manually through the user interface and run its code with dns_del commented out).
#!/bin/bash ttlify() { local i for i in " $@ "; do [[ "${i}" =~ ^([0-9]+)([az]*)$ ]] || continue local num="${BASH_REMATCH[1]}" local unit="${BASH_REMATCH[2]}" case "${unit}" in weeks|week|wee|we|w) unit=''; num=$[num*60*60*24*7];; days|day|da|d) unit=''; num=$[num*60*60*24];; hours|hour|hou|ho|h) unit=''; num=$[num*60*60];; minutes|minute|minut|minu|min|mi|m) unit=''; num=$[num*60];; seconds|second|secon|seco|sec|se|s) unit=''; num=$[num];; esac echo "${num}${unit}" done } dns_start() { gcloud dns record-sets transaction start -z "${ZONENAME}" } dns_info() { gcloud dns record-sets transaction describe -z "${ZONENAME}" } dns_abort() { gcloud dns record-sets transaction abort -z "${ZONENAME}" } dns_commit() { gcloud dns record-sets transaction execute -z "${ZONENAME}" } dns_add() { if [[ -n "$1" && "$1" != '@' ]]; then local -r name="$1.${ZONE}." else local -r name="${ZONE}." fi local -r ttl="$(ttlify "$2")" local -r type="$3" shift 3 gcloud dns record-sets transaction add -z "${ZONENAME}" --name "${name}" --ttl "${ttl}" --type "${type}" " $@ " } dns_del() { if [[ -n "$1" && "$1" != '@' ]]; then local -r name="$1.${ZONE}." else local -r name="${ZONE}." fi local -r ttl="$(ttlify "$2")" local -r type="$3" shift 3 gcloud dns record-sets transaction remove -z "${ZONENAME}" --name "${name}" --ttl "${ttl}" --type "${type}" " $@ " } lookup_dns_ip() { host "$1" | sed -rn ' s@ ^.* has address @@p' } my_ip() { ip -4 addr show dev eth0 | sed -rn ' s@ ^ inet ([0-9.]+).*@\ 1@p ' } doit() { ZONE=foo.bar.com ZONENAME=foo-bar-com dns_start dns_del my-vm 5min A `lookup_dns_ip "my-vm.${ZONE}."` dns_add my-vm 5min A `my_ip` dns_commit }
source share