What to do, if you do not have a luxury of static IP, but still want to host some services using your server? Here is a quick, dirty and hacky workaround. Just perfect.

We would need a three things:

  • domain
  • cloudflare account
  • terraform installed

First, you need to transfer your domain to cloudflare. The main usecase of cloudflare is CDN, DDoS protection and a WAF, but we will leverage the fact, that Cloudflare has a terraform provider.

Next, go to your account settings, and create an API token. We will need it later.

terraform {
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 4.0"
    }
  }
}

provider "cloudflare" {
  api_token = "PUT API TOKEN HERE"
}

variable "zone_id" {
  default = "TAKE ZONE ID FROM CLOUDFLARE"
}

variable "domains" {
  default = ["subdomain1","subdomain2","example.com"]
}

data "http" "myip" {
  url = "https://ipv4.icanhazip.com"
}

output "ip" {
  value = "${chomp(data.http.myip.response_body)}"
}

resource "cloudflare_record" "dynamic-ip" {
  for_each = toset(var.domains)
  zone_id = var.zone_id
  name    = "${each.key}"
  content = "${chomp(data.http.myip.response_body)}"
  type    = "A"
  proxied = false
}

Save it with .tf extension. Change api_token and zone_id. Put your subdomains to the list.

This code is checking for your external IP, and if it changed since the last run, it will update your DNS records.

Now we can add terraform apply –auto-approve to cron, and run it every hour or so. Slightly better would be systemd timer. To configure it, create two files:

/etc/systemd/system/terraform-cloudflare.service

[Unit]
Description=update dns

[Service]
Type=oneshot
WorkingDirectory={{path to your .tf code}}
ExecStart=/usr/bin/terraform apply --auto-approve

/etc/systemd/system/terraform-cloudflare.timer

[Unit]
Description=Timer to update dns

[Timer]
OnCalendar=hourly 
Persistent=true

[Install]
WantedBy=timers.target

now, couple of commands

sudo systemctl daemon-reload
sudo systemctl enable terraform-cloudflare.timer
sudo systemctl start terraform-cloudflare.timer
systemctl list-timers terraform-cloudflare.timer

At any point, if you want to inspect the logs, use

journalctl -u terraform-apply.service

2 responses to “Poor’s Man Static IP”

  1. “Persistent=true” may not be reasonable in such timer. Especially without any “After” statements. This will not only launch all missed launches if your server was disabled for a time… which I don’t think is desirable… It will also launch those missing runs boot-time without any conditions, so probably before even network connection has been established (guaranteed failure). I would disable persistence and make it timer-only. Maybe even launched more often than once per hour.

    BTW: How quickly Cloudflare propagates domain update?

  2. yeah, that is true, its better to leave persistent set to false
    from my observations, updading the record works instantly. never had any issue with creating or updating records.

Leave a Reply

Your email address will not be published. Required fields are marked *

+