How to update Google Cloud DNS with ephemeral IP for an instance

前端 未结 3 1698
清酒与你
清酒与你 2020-12-30 10:00

I have couple of instances on GCE that I don\'t really need static addresses for, but I still need to make them accessible via dns name. Since ephemeral external ip addresse

相关标签:
3条回答
  • 2020-12-30 10:11

    It's been a while since you've posted this question, but i'll post my answer here for future reference.

    I've had a similar need and I didn't want to use gcloud CLI.

    I've created a simple python script that does pretty much the same as the bash script above does, but uses Apache Libcloud and Google Cloud API credentials (service account and key).

    You can find the code in GitHub.

    0 讨论(0)
  • 2020-12-30 10:14

    I'm going to take a slight spin on the answer from @MaZe. Also, I'll show using systemd so this script starts automatically at startup if you're on Ubuntu or another distro that uses systemd.

    #!/bin/bash
    
    EXISTING=`gcloud dns record-sets list --zone="{your domain}" | grep xxx.yyyy.com | awk '{print $4}'`
    NEW=`gcloud compute instances describe {your instance} --zone={your zone} | grep natIP | awk -F': ' '{print $2}'`
    gcloud dns record-sets transaction start -z={your domain}
    gcloud dns record-sets transaction remove -z={your domain} \
        --name="xxx.yyyy.com." \
        --type=A \
        --ttl=300 "$EXISTING"
    gcloud dns record-sets transaction add -z={your domain} \
       --name="xxx.yyyy.com." \
       --type=A \
       --ttl=300 "$NEW"
    gcloud dns record-sets transaction execute -z={your domain}
    

    Save it to /path/to/script.sh and start it up in systemd:

    [Unit]
    Description=Set xxx.yyyy.com to the correct external ip address of this instance
    After=network.target auditd.service
    
    [Service]
    ExecStart=/path/to/script.sh
    Type=oneshot
    
    [Install]
    WantedBy=multi-user.target
    

    Save it in /etc/systemd/system as filename.service and enabled it with:

    sudo systemctl enable filename.service
    
    0 讨论(0)
  • 2020-12-30 10:20

    The following assumes that you are using Google Cloud DNS for foo.bar.com (ie. dns name "foo.bar.com.") with zone name "foo-bar-com" in the same project as your VM and that your VM has configuration option "This instance has full API access to all Google Cloud services." selected. Your VM will be called "my-vm.foo.bar.com" in DNS.

    I'm sure this could be appropriately modified to work with DNS in a different project and/or more limited permissions.

    Probably worth noting: this assumes you are using 'Google Cloud DNS' and not (just) 'Google Domains' registrar, if you're using the latter (to host your DNS, and not just as a registrar) then they have direct support for synthetic dynamic ip address with some dyndns like update mechanism (but they're more limited in a bunch of other ways).

    Also note that for transaction to succeed there already has to be a record with the right IP and the right TTL (ie. the first time you run this you may want to delete any entry by hand via the UI, and run this code with dns_del commented out).

    #!/bin/bash
    
    ttlify() {
      local i
      for i in "$@"; do
        [[ "${i}" =~ ^([0-9]+)([a-z]*)$ ]] || 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
    }
    
    0 讨论(0)
提交回复
热议问题