Skip to content

Instantly share code, notes, and snippets.

@OliPassey
Created November 8, 2024 17:26
Show Gist options
  • Save OliPassey/651da51731b5b60f7911850a9bf88d16 to your computer and use it in GitHub Desktop.
Save OliPassey/651da51731b5b60f7911850a9bf88d16 to your computer and use it in GitHub Desktop.
Auto IP Check & Update Azure DNS A Record
import requests
from azure.identity import DefaultAzureCredential
from azure.mgmt.dns import DnsManagementClient
from azure.mgmt.dns.models import RecordSet, ARecord
import time
import logging
from datetime import datetime
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('dns_updater.log'),
logging.StreamHandler()
]
)
class AzureDNSUpdater:
def __init__(self, subscription_id, resource_group_name, zone_name, record_name):
self.subscription_id = subscription_id
self.resource_group_name = resource_group_name
self.zone_name = zone_name
self.record_name = record_name
self.current_ip = None
# Initialize Azure credentials and DNS client
self.credential = DefaultAzureCredential()
self.dns_client = DnsManagementClient(
credential=self.credential,
subscription_id=self.subscription_id
)
def get_external_ip(self):
"""Get external IP address using a public IP API"""
try:
response = requests.get('https://api.ipify.org?format=json', timeout=10)
response.raise_for_status()
return response.json()['ip']
except requests.RequestException as e:
logging.error(f"Failed to get external IP: {e}")
return None
def update_dns_record(self, ip_address):
"""Update Azure DNS A record with new IP address"""
try:
record_set = RecordSet(
ttl=300,
a_records=[ARecord(ipv4_address=ip_address)]
)
self.dns_client.record_sets.create_or_update(
resource_group_name=self.resource_group_name,
zone_name=self.zone_name,
relative_record_set_name=self.record_name,
record_type='A',
parameters=record_set
)
logging.info(f"Successfully updated DNS record with IP: {ip_address}")
return True
except Exception as e:
logging.error(f"Failed to update DNS record: {e}")
return False
def run(self, check_interval=300):
"""Main loop to check IP and update DNS if needed"""
logging.info("Starting Azure DNS updater...")
while True:
try:
new_ip = self.get_external_ip()
if new_ip and new_ip != self.current_ip:
logging.info(f"IP change detected - Old: {self.current_ip}, New: {new_ip}")
if self.update_dns_record(new_ip):
self.current_ip = new_ip
time.sleep(check_interval)
except Exception as e:
logging.error(f"Error in main loop: {e}")
time.sleep(60) # Wait a minute before retrying on error
if __name__ == "__main__":
# Configuration
SUBSCRIPTION_ID = "xxx"
RESOURCE_GROUP = "xxx"
ZONE_NAME = "xxx"
RECORD_NAME = "xxx"
CHECK_INTERVAL = 3600 # 60 minutes
updater = AzureDNSUpdater(
subscription_id=SUBSCRIPTION_ID,
resource_group_name=RESOURCE_GROUP,
zone_name=ZONE_NAME,
record_name=RECORD_NAME
)
updater.run(check_interval=CHECK_INTERVAL)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment