Created
November 8, 2024 17:26
-
-
Save OliPassey/651da51731b5b60f7911850a9bf88d16 to your computer and use it in GitHub Desktop.
Auto IP Check & Update Azure DNS A Record
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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