This script updates a DNS A record (IPv4 address) using the Cloudflare Python API. It expects the A record to be present already.
Also see Python Cloudflare DNS A record create or update example for a variant of this script which creates the record if it doesn’t exist already.
#!/usr/bin/env python3 import CloudFlare import argparse import sys if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-e", "--email", required=True, help="The Cloudflare login email to use") parser.add_argument("-n", "--hostname", required=True, help="The hostname to update, e.g. mydyndns.mydomain.com") parser.add_argument("-k", "--api-key", required=True, help="The Cloudflare global API key to use. NOTE: Domain-specific API tokens will NOT work!") parser.add_argument("-i", "--ip-address", required=True, help="Which IP address to update the record to") parser.add_argument("-t", "--ttl", default=60, type=int, help="The TTL of the records in seconds (or 1 for auto)") args = parser.parse_args() # Initialize Cloudflare API client cf = CloudFlare.CloudFlare( email=args.email, token=args.api_key ) # Get zone ID (for the domain). This is why we need the API key and the domain API token won't be sufficient zone = ".".join(args.hostname.split(".")[-2:]) # domain = test.mydomain.com => zone = mydomain.com zones = cf.zones.get(params={"name": zone}) if len(zones) == 0: print(f"Could not find CloudFlare zone {zone}, please check domain {args.hostname}") sys.exit(2) zone_id = zones[0]["id"] # Fetch existing A record a_record = cf.zones.dns_records.get(zone_id, params={"name": args.hostname, "type": "A"})[0] # Update record & save to cloudflare a_record["ttl"] = args.ttl # 1 == auto a_record["content"] = args.ip_address cf.zones.dns_records.put(zone_id, a_record["id"], data=a_record)
Usage example:
./update-dns.py --api-key ... --email [email protected] --ttl 300 --ip 1.2.3.4 --hostname mysubdomain.domain.com