Automate IP Whitelisting in CI/CD Pipelines with Free IP Lookup API

MyIP.foo logo

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.



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.

MyIP.foo web interface showing response with IP address, location data, network information, and browser details

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:

  1. Runner fetches its own public IP via curl https://myip.foo/plain
  2. Azure CLI adds temporary firewall rule for that IP
  3. Migrations run with database access
  4. 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

EndpointFormatUse CaseExample
/plainPlain textShell scripts, one-linerscurl https://myip.foo/plain
/apiJSONPowerShell, Python, automationInvoke-RestMethod https://myip.foo/api
/HTMLBrowser, visual checkshttps://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

Featuremyip.fooipify.orgip-api.comifconfig.me
Auth Required❌ No❌ No✅ Yes (Paid)❌ No
Geolocation✅ Yes❌ No✅ Yes❌ No
Rate LimitsNoneNone45/minUnknown
IPv6 Support✅ Dual-stack✅ Yes❌ No✅ Yes
Response Time~20ms~30ms~40ms~50ms
JSON + Plain Text✅ Yes✅ Yes✅ Yes✅ Yes

Best Practices

  1. Cache responses – IP addresses don’t change every second. Cache for 5-10 minutes.
  2. Use /plain for scripts – Faster parsing than JSON when you only need the IP.
  3. Always clean up firewall rules – Use if: always() in GitHub Actions to remove IPs even on failure.
  4. Verify VPN before production – Check geolocation data, not just connectivity.
  5. Force IPv4 or IPv6 – Use curl -4 or curl -6 to 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:


0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x