- Prerequisites
- Methods to get IP from AWS
- Robot Design: Proposed Architecture
- Quick implementation with Bash + curl (practical example)
- Reliable implementation with Python (practical example)
- Deployment and management (systemd, cron, Lambda)
- Security, key storage, and minimal access
- Practical tips: TTL, Proxy, IPv6, Troubleshooting and Monitoring
- Comparison and practical recommendations for trading, gaming and the web
- Conclusion
- Willingness to receive technical assistance
- Frequently Asked Questions
Prerequisites
Before starting, you need to prepare the following items for the robot to work properly.
- Cloudflare account and access to manage domain DNS.
- Creation API Token In Cloudflare with access level Zone:DNS:Edit For the desired zone.
- Access to Zone ID Domain and record name (e.g.
vpn.example.com). - A server or service in AWS (EC2) with a public IP address that is accessible, or AWS API access for querying.
- Basic tools:
curl,jq, Python3+requests. - Security suggestion: Keep the token in AWS Secrets Manager or protected environment variables.
Methods to get IP from AWS
There are several common methods for obtaining a public IP address from Amazon servers; the choice of method depends on the implementation scenario.
1. Inside EC2 (metadata)
If the script is running on the same EC2 instance, the easiest way is to use the metadata service:
curl -s http://169.254.169.254/latest/meta-data/public-ipv4For IPv6:
curl -s http://169.254.169.254/latest/meta-data/ipv62. With AWS CLI/SDK
Using describe-instances And you can filter by tag or Instance ID to get the IP. With IAM Role you can eliminate the need for access keys.
aws ec2 describe-instances --instance-ids i-0123456789abcdef --query "Reservations[].Instances[].PublicIpAddress" --output text3. Elastic IP and complex networks
For Elastic IP or complex network configurations, check associations with describe-addresses The method is appropriate.
Robot Design: Proposed Architecture
Depending on the need and scale, there are several suitable architectural patterns:
- Simple option: The script runs on the same EC2 and checks the IP every n minutes; if it changes, it is updated with the Cloudflare API.
- Scalable option: Multiple EC2s in different regions → A central Lambda/Serverless is responsible for collecting IPs and updating multiple records.
- Save status: Local file or S3/DB to store the last registered IP to avoid unnecessary updates.
- Error handling and retry: Use backoff and logging (CloudWatch).
Quick implementation with Bash + curl (practical example)
This example assumes the script is running on the same EC2 instance and is updating an A record. First, get the Zone ID and Record ID once:
curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=example.com" -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" | jq -r '.result[0].id'
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=vpn.example.com" -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" | jq -r '.result[0].id'Sample script update-ip.sh:
#!/usr/bin/env bash
set -e
CF_TOKEN="---FROM SECRETS MANAGER OR ENV---"
ZONE_ID="your_zone_id"
RECORD_NAME="vpn.example.com"
RECORD_ID="your_record_id"
PROXY=false
TTL=120
get_ip() {
curl -s http://169.254.169.254/latest/meta-data/public-ipv4
}
current_ip=$(get_ip)
old_ip_file="/var/run/current_ip_${RECORD_NAME}"
if [ -f "$old_ip_file" ]; then
old_ip=$(cat "$old_ip_file")
else
old_ip=""
fi
if [ "$current_ip" = "" ]; then
echo "No public IP found" >&2
exit 1
fi
if [ "$current_ip" != "$old_ip" ]; then
echo "Updating Cloudflare DNS from $old_ip to $current_ip"
payload=$(jq -n --arg type "A" --arg name "$RECORD_NAME" --arg content "$current_ip" --argjson proxied $PROXY --argjson ttl $TTL '{type:$type, name:$name, content:$content, proxied:$proxied, ttl:$ttl}')
resp=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" -H "Authorization: Bearer $CF_TOKEN" -H "Content-Type: application/json" --data "$payload")
success=$(echo "$resp" | jq -r '.success')
if [ "$success" = "true" ]; then
echo "$current_ip" > "$old_ip_file"
echo "Update successful"
else
echo "Update failed: $resp" >&2
exit 2
fi
else
echo "IP unchanged ($current_ip)"
fiTips: From jq Used to build JSON. Store IP in /var/run This is to prevent unnecessary updates. Keep the token in an environment variable or Secrets Manager, not in a script.
Reliable implementation with Python (practical example)
An example of a Python script that can be run as Lambda or on the server and manages multiple records.
requests
boto3import os, requests, json
CF_TOKEN = os.environ['CF_TOKEN']
ZONE_ID = os.environ['ZONE_ID']
RECORDS = json.loads(os.environ.get('RECORDS_JSON', '[]'))
HEADERS = {
"Authorization": f"Bearer {CF_TOKEN}",
"Content-Type": "application/json"
}
def get_ec2_public_ip():
try:
r = requests.get("http://169.254.169.254/latest/meta-data/public-ipv4", timeout=2)
if r.ok:
return r.text.strip()
except:
pass
return None
def find_record_id(name, type="A"):
url = f"https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/dns_records?name={name}&type={type}"
r = requests.get(url, headers=HEADERS)
data = r.json()
if data.get("success") and data["result"]:
return data["result"][0]["id"]
return None
def update_record(record_id, name, ip, type="A", ttl=120, proxied=False):
url = f"https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/dns_records/{record_id}"
payload = {"type": type, "name": name, "content": ip, "ttl": ttl, "proxied": proxied}
r = requests.put(url, headers=HEADERS, json=payload)
return r.json()
def lambda_handler(event, context=None):
ip = get_ec2_public_ip()
if not ip:
print("No public IP found")
return
for rec in RECORDS:
name = rec["name"]
typ = rec.get("type","A")
rec_id = find_record_id(name, typ)
if not rec_id:
print(f"No record id for {name}")
continue
resp = update_record(rec_id, name, ip, typ, rec.get("ttl",120), rec.get("proxied",False))
print(resp)
if __name__ == "__main__":
lambda_handler(None)Deployment and management (systemd, cron, Lambda)
Some common methods for running and managing a robot:
- systemd: Create a unit that runs the script every 5 minutes or a daemon service that monitors changes.
- cron: Periodic execution (every n minutes) with local state memory to avoid redundant updates.
- AWS Lambda + EventBridge: Periodic execution without server maintenance, with IAM role and Secrets Manager.
- Logs: Send logs to CloudWatch and define alarms for persistent errors.
Security, key storage, and minimal access
Security requirements to reduce risk and adhere to the principle of least access:
- API Token Limited: In Cloudflare, use API Token instead of Global API Key and limit the scope to Zone:DNS:Edit Only for the desired zone.
- IAM Role: In AWS, use IAM Role for EC2/Lambda and use AWS Secrets Manager or SSM Parameter Store to store CF_TOKEN.
- Delete token from logs: Clear logs from token storage and use TLS.
- Limit updates: If the IP has not changed, do not send any updates to avoid Rate Limit.
Practical tips: TTL, Proxy, IPv6, Troubleshooting and Monitoring
- TTL: Low TTL (e.g. 120s) is good for fast changes but increases queries.
- Proxy (Cloudflare orange cloud): If you want traffic to go through Cloudflare (CDN, WAF, DDoS protection),
proxy=true. But for allowlist IP like exchanges you needproxy=falseTo preserve the real IP. - IPv6: If IPv6 address exists, update
AAAARecords are also essential. - Retries: Use exponential backoff and log errors when encountering network errors.
- Monitoring: Keep metrics on successful/failed updates, API response times, and IP changes in the dashboard and set up notifications for frequent errors.
Comparison and practical recommendations for trading, gaming and the web
Trade: Ping and stability are very important. It is recommended to use a trading VPS with a location close to the exchange and Anti-DDoS. For a fixed IP, use Elastic IP or an update robot. For some exchange APIs proxy=false It is necessary.
Game: Low latency and stability are important. Use a location close to gamers. Depending on the game, using Cloudflare Spectrum or no proxy is a decision-maker.
Web and API: Using Cloudflare with proxy=true Recommended for CDN, WAF, and DDoS protection. In this case, changing IP is less critical, but the origin must be managed.
Conclusion
Using the methods discussed above, you can automatically and securely update DNS records on Cloudflare based on IPs received from EC2.
- From API Token Limited Use Cloudflare.
- From IAM Role and Secrets Manager Take advantage of AWS.
- Implement appropriate logging, monitoring, and retry to make the process robust.
- For specific needs (trading, gaming, AI/rendering), use specialized servers, Anti-DDoS, and optimized locations to reduce latency and increase stability.
Willingness to receive technical assistance
If you need support with professional implementation, choosing the right location, or secure deployment on AWS and Cloudflare, you can contact the technical team to provide you with a customized solution and full support.









