If you’ve ever worked with CI/CD pipelines that need to access firewalled databases or APIs, you’ve hit the classic problem: GitHub Actions runners, Azure DevOps agents, and GitLab CI workers use dynamic IP addresses that change constantly.
Manually whitelisting IPs is tedious and error-prone. Leaving your firewall wide open is a security nightmare.
The solution? Automate IP detection and firewall updates using a free IP lookup API.
Table of Contents
The Problem: Dynamic CI/CD Runner IPs
Modern CI/CD platforms run builds on ephemeral virtual machines with constantly rotating public IPs:
- GitHub Actions: Runners use Azure-hosted VMs with dynamic IPs
- Azure DevOps: Microsoft-hosted agents change IPs between builds
- GitLab CI: Shared runners on Google Cloud with rotating addresses
If your production database or internal API requires IP whitelisting (common in enterprise environments), your builds fail with connection errors unless you can dynamically whitelist the runner’s current IP.
The Solution: myip.foo API
myip.foo is a free IP lookup service built on Cloudflare’s edge network. It provides:
- No authentication required – No API keys, no sign-up
- Instant IP detection – Returns your public IPv4/IPv6 address
- Geolocation data – Country, city, ISP, timezone (from Cloudflare)
- Multiple endpoints – JSON (
/api), plain text (/plain), HTML UI - No rate limits – Service auto-scales as needed
- Global low latency – Edge-deployed, <50ms response times worldwide
Perfect for scripting and automation.
Use Case 1: GitHub Actions IP Whitelisting
Automatically whitelist your GitHub Actions runner IP in an Azure SQL Database firewall.
name: Deploy with Database Migration
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Get GitHub Actions Runner IP
id: runner_ip
run: |
RUNNER_IP=$(curl -s https://myip.foo/plain)
echo "ip=$RUNNER_IP" >> $GITHUB_OUTPUT
echo "🌐 Runner IP: $RUNNER_IP"
- name: Whitelist IP in Azure SQL Firewall
run: |
az sql server firewall-rule create \
--resource-group ${{ secrets.AZURE_RG }} \
--server ${{ secrets.SQL_SERVER }} \
--name "GitHubActions-${{ github.run_id }}" \
--start-ip-address ${{ steps.runner_ip.outputs.ip }} \
--end-ip-address ${{ steps.runner_ip.outputs.ip }}
- name: Run Database Migrations
run: |
# Now the runner can connect to Azure SQL
dotnet ef database update
- name: Remove IP from Firewall (cleanup)
if: always()
run: |
az sql server firewall-rule delete \
--resource-group ${{ secrets.AZURE_RG }} \
--server ${{ secrets.SQL_SERVER }} \
--name "GitHubActions-${{ github.run_id }}"
How it works:
- Runner fetches its own public IP via
curl https://myip.foo/plain - Azure CLI adds temporary firewall rule for that IP
- Migrations run with database access
- Firewall rule is deleted in cleanup step (runs even if build fails)
Result: Zero manual firewall management, no hardcoded IPs, secure by default.
Use Case 2: PowerShell Firewall Automation
Check your server’s public IP before updating firewall rules (useful for dynamic DNS, VPN verification, or outbound IP tracking).
# Get current public IP
$CurrentIP = (Invoke-RestMethod -Uri "https://myip.foo/api").ip
Write-Host "Current Public IP: $CurrentIP" -ForegroundColor Cyan
# Update Windows Firewall rule
$RuleName = "Allow-DevOps-Agent"
if (Get-NetFirewallRule -DisplayName $RuleName -ErrorAction SilentlyContinue) {
Remove-NetFirewallRule -DisplayName $RuleName
}
New-NetFirewallRule `
-DisplayName $RuleName `
-Direction Inbound `
-RemoteAddress $CurrentIP `
-Action Allow `
-Protocol TCP `
-LocalPort 3389
Write-Host "✅ Firewall rule updated for $CurrentIP" -ForegroundColor Green
Use cases:
- Azure DevOps self-hosted agents updating their own firewall rules
- Remote desktop access from dynamic IPs (home office, VPN)
- Automated security group management in AWS/Azure
Use Case 3: VPN Verification in Deployment Scripts
Verify your deployment script is running through the correct VPN before pushing to production.
#!/bin/bash
# verify-vpn.sh - Ensure VPN is active before deployment
EXPECTED_COUNTRY="NL" # Netherlands VPN
CURRENT_COUNTRY=$(curl -s https://myip.foo/api | jq -r '.location.country')
if [ "$CURRENT_COUNTRY" != "$EXPECTED_COUNTRY" ]; then
echo "❌ VPN verification failed!"
echo "Expected: $EXPECTED_COUNTRY, Got: $CURRENT_COUNTRY"
exit 1
fi
echo "✅ VPN active: Connected via $EXPECTED_COUNTRY"
# Safe to deploy
kubectl apply -f production.yaml
Why this matters: In regulated industries (finance, healthcare), deployments may be required to originate from specific countries or data centers. This script prevents accidental deployments from unauthorized locations.
Use Case 4: Dynamic DNS Updates for Home Labs
Automatically update your DNS A record when your ISP changes your home IP (replace DynDNS, No-IP, etc.).
#!/bin/bash
# dyndns-update.sh - Update Cloudflare DNS with current IP
ZONE_ID="your_zone_id"
RECORD_ID="your_dns_record_id"
API_TOKEN="your_cloudflare_api_token"
DOMAIN="homelab.example.com"
# Get current public IP
CURRENT_IP=$(curl -s https://myip.foo/plain)
# Update Cloudflare DNS
curl -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$CURRENT_IP\",\"ttl\":120}"
echo "✅ DNS updated: $DOMAIN → $CURRENT_IP"
Add to cron:
*/10 * * * * /home/user/scripts/dyndns-update.sh
Checks every 10 minutes, updates DNS only when IP changes. No monthly fees, no captcha checks like legacy DynDNS services.
API Reference
| Endpoint | Format | Use Case | Example |
|---|---|---|---|
| /plain | Plain text | Shell scripts, one-liners | curl https://myip.foo/plain |
| /api | JSON | PowerShell, Python, automation | Invoke-RestMethod https://myip.foo/api |
| / | HTML | Browser, visual checks | https://myip.foo |
JSON Response Structure
{
"ip": "203.0.113.45",
"type": "IPv4",
"location": {
"country": "NL",
"city": "Amsterdam",
"region": "North Holland",
"timezone": "Europe/Amsterdam",
"latitude": "52.3740",
"longitude": "4.8897"
},
"network": {
"asn": 1136,
"isp": "KPN B.V."
},
"browser": {
"name": "Chrome",
"platform": "Windows"
}
}
Comparison: myip.foo vs Alternatives
| Feature | myip.foo | ipify.org | ip-api.com | ifconfig.me |
|---|---|---|---|---|
| Auth Required | ❌ No | ❌ No | ✅ Yes (Paid) | ❌ No |
| Geolocation | ✅ Yes | ❌ No | ✅ Yes | ❌ No |
| Rate Limits | None | None | 45/min | Unknown |
| IPv6 Support | ✅ Dual-stack | ✅ Yes | ❌ No | ✅ Yes |
| Response Time | ~20ms | ~30ms | ~40ms | ~50ms |
| JSON + Plain Text | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
Best Practices
- Cache responses – IP addresses don’t change every second. Cache for 5-10 minutes.
- Use
/plainfor scripts – Faster parsing than JSON when you only need the IP. - Always clean up firewall rules – Use
if: always()in GitHub Actions to remove IPs even on failure. - Verify VPN before production – Check geolocation data, not just connectivity.
- Force IPv4 or IPv6 – Use
curl -4orcurl -6to explicitly choose protocol.
Security Considerations
Is it safe to whitelist dynamic IPs?
Yes, with these precautions:
- ✅ Temporary rules only – Delete firewall rules after job completion
- ✅ Narrow scope – Whitelist specific ports (3306, 5432, 1433), not all traffic
- ✅ Short TTL – GitHub Actions jobs run <15 minutes, firewall rules should expire quickly
- ✅ Logging – Tag rules with job IDs for audit trails
Privacy:
myip.foo does not log IP addresses (privacy policy: https://myip.foo/privacy.html)
Geolocation data comes from Cloudflare’s network metadata (public information)
Try It Now
# Bash/Linux
curl https://myip.foo/plain
# PowerShell
(Invoke-RestMethod https://myip.foo/api).ip
# Windows CMD
curl https://myip.foo/plain
# Python
import requests
print(requests.get('https://myip.foo/api').json()['ip'])
Conclusion
Automating IP whitelisting in CI/CD pipelines eliminates manual toil and security risks. With a free, no-auth API like myip.foo, you can:
- ✅ Dynamically whitelist GitHub Actions/Azure DevOps runners
- ✅ Update DNS records when your ISP changes your IP
- ✅ Verify VPN connections in deployment scripts
- ✅ Automate firewall rules in PowerShell/Bash
No API keys, no rate limits, no registration. Just automation.
Resources:
- 🌐 Website: myip.foo
- 📚 API Docs: myip.foo/api-docs.html
- 🔒 Privacy Policy: myip.foo/privacy.html