A comprehensive AWS infrastructure setup for Polygon blockchain nodes using Terraform, with working P2P connections, RPC fixes, and complete automation.
This project demonstrates building production-ready Polygon validator infrastructure, learning the technical components and operational challenges of running blockchain infrastructure. All sync issues have been solved with proper RPC endpoints, state sync configuration, and working peer connections.
Complete Polygon PoS Node Infrastructure supporting:
- β Full Node Operations (current deployment)
- β Data Node Services (RPC endpoints for dApps)
- β Validator-Ready Infrastructure (add staking to become validator)
This setup creates a non-validating full node that:
- β Syncs complete blockchain data (Heimdall + Bor)
- β Provides RPC services to applications
- β Supports network decentralization
- β Can be upgraded to validator by adding economic stake
- Complete AWS infrastructure deployed with Terraform automation
- Amazon Linux 2023 with proper security configuration
- SSH access with generated key pairs and security groups
- Built Bor v1.5.5 (114MB binary) from source successfully
- Built Heimdall v1.0.7 (heimdalld + heimdallcli) from source
- β SYNC ISSUES FIXED - Node syncs properly without getting stuck
- β External RPC endpoints - Ethereum mainnet access configured
- β Port conflicts resolved - All services run without conflicts
- β Working peer connections - Both layers connecting to peers
- β Rapid sync progress - Heimdall syncing at 1,000+ blocks/minute
- β Complete service architecture with systemd services
- β Built-in REST API working on port 1317
- Cross-platform deployment - Works on Windows, Linux, and macOS
The main issue was Heimdall getting stuck at "Replay last block using real app" due to:
- β Missing external Ethereum RPC - Heimdall couldn't validate checkpoints
- β Wrong command-line flags - Using hyphens instead of underscores
- β Port conflicts - Heimdall and Bor competing for gRPC ports
- β Invalid configuration files - Heimdall config format was wrong
- β
External Ethereum RPC:
--eth_rpc_url https://ethereum-rpc.publicnode.com - β
Correct flags:
--eth_rpc_urland--bor_rpc_url(with underscores) - β Port separation: Heimdall (3132), Bor (3133) for gRPC
- β
Built-in REST: Use Heimdall's
--rest-serverflag instead of separate service - β State sync: Enabled for faster initial sync
- β Working peer addresses: Updated to current mainnet peers
π― Sync Performance Achieved:
βββ Heimdall: 284,006 blocks synced (excellent performance!)
βββ Bor: Running and responding to RPC calls
βββ Heimdall Peers: 6 connected
βββ External RPC: All endpoints accessible
βββ REST API: Built-in service working on port 1317
βββ Status: Fully operational for hands-on learning
This project works on Windows, Linux, and macOS with identical commands:
# Works on all platforms (Windows PowerShell, Linux Bash, macOS Terminal)
git clone https://github.com/b95702041/polygon-validator-infrastructure.git
cd polygon-validator-infrastructure/terraform
# Generate SSH key pair
ssh-keygen -t rsa -b 4096 -f polygon-key
# Deploy infrastructure
terraform init
terraform apply
# Connect to instance
ssh -i polygon-key ec2-user@<PUBLIC_IP>- Your Local Machine: Only Terraform and Git (any OS)
- AWS EC2 Instance: Always Linux (Amazon Linux 2023)
- Polygon Node Software: Always runs on Linux in the cloud
- AWS CLI configured with appropriate permissions
- Terraform installed (any OS)
- SSH client available
# For all platforms
terraform apply
# Get instance IP
terraform output polygon_node_ip
# Connect via SSH
ssh -i polygon-key ec2-user@<PUBLIC_IP># Watch the automated installation
sudo tail -f /var/log/polygon-install.log
# Check installation completion
polygon-status# Check sync progress (should be advancing rapidly)
curl -s localhost:26657/status | jq '.result.sync_info'
# Test Bor RPC
curl -s -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
http://localhost:8545
# Use enhanced monitoring
polygon-statusβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Ethereum Mainnet (Settlement Layer) π EXTERNAL β
β β’ We CONNECT to this via RPC (not deployed by us) β
β β’ Stores checkpoints every ~30 minutes β
β β’ RPC: https://ethereum-rpc.publicnode.com β
βββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β External RPC Connection β
β
βββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ
β Our Heimdall Node (Consensus Client) β
DATA NODE β
β β’ Proof of Stake consensus validation β
β β’ Validator selection and checkpoint management β
β β’ REST API on port 1317 (built-in) β
β β’ RPC on port 26657 β
βββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β Local Communication β
β
βββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ
β Our Bor Node (Execution Client) β
DATA NODE β
β β’ Processes and validates transactions β
β β’ Maintains execution state β
β β’ Provides JSON-RPC for dApps (port 8545) β
β β’ Follows consensus from Heimdall β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- heimdalld.service - Main consensus daemon with built-in REST
- bor.service - Execution layer daemon
- Auto-restart and dependency management
- No port conflicts - Each service uses unique ports
- Cloud Provider: AWS EC2 (t3.medium)
- Infrastructure as Code: Terraform
- Blockchain: Polygon Bor + Heimdall clients
- Operating System: Amazon Linux 2023
- Development: Go 1.24.4, Git, Development Tools
- Instance Type: t3.medium (2 vCPU, 4GB RAM)
- Storage: 50GB GP3 SSD for blockchain data
- Network: Default VPC with custom security group
- Estimated Cost: ~$35/month when running continuously
Port 22 (SSH) - Administrative access
Port 26656 (TCP) - Heimdall P2P communication
Port 26657 (TCP) - Heimdall RPC server
Port 30303 (TCP) - Bor P2P communication
Port 8545 (TCP) - Bor RPC server
Port 1317 (TCP) - Heimdall REST API (built-in)The connection to Ethereum mainnet is configured in the Heimdall service:
# WORKING Heimdall service configuration:
ExecStart=/usr/local/bin/heimdalld start \
--home /var/lib/polygon/heimdall \
--chain mainnet \
--eth_rpc_url https://ethereum-rpc.publicnode.com \ # β ETHEREUM CONNECTION
--bor_rpc_url http://127.0.0.1:8545 \
--rest-server
# WORKING Bor service configuration:
ExecStart=/usr/local/bin/bor server \
--datadir /var/lib/polygon/bor \
--chain mainnet \
--http --http.addr 0.0.0.0 --http.port 8545 \
--grpc.addr :3133 \
--bor.heimdall http://127.0.0.1:26657- External RPC Endpoints: Added Ethereum mainnet RPC for checkpoint validation
- Correct Command Flags: Used underscores (
--eth_rpc_url) not hyphens - Port Management: Separated gRPC ports (Heimdall: 3132, Bor: 3133)
- Built-in REST: Used Heimdall's native
--rest-serverflag - State Sync: Enabled for faster initial synchronization
- Working Bootnodes: Updated to current active peer addresses
1. Terraform Apply β
β
2. AWS EC2 Instance Created β
β
3. Bootstrap Script Runs (small, in user_data) β
β
4. Downloads Fixed Installer from GitHub β
β
5. Executes Complete Installation with All Fixes β
β
6. Services Start & Sync Begins Successfully β
- Overcomes AWS 16KB limit for user_data β
- Maintainable - Update installer in GitHub, not Terraform β
- Universal - Works from any platform β
- All fixes included - External RPC, port fixes, etc. β
- Reliable - Tested automation with proven solutions β
- Heimdall Sync Speed: ~1,000-2,000 blocks/minute β
- Block Progress: Validated progression from block 121,102 to 129,435+ β
- Peer Connections: 6 stable Heimdall peers β
- Memory Usage: ~2-4GB RAM during sync β
- RPC Response: All endpoints responding correctly β
β
Heimdall: Block height advancing rapidly (not stuck)
β
Bor: RPC responding with proper sync status
β
External RPC: Ethereum mainnet connectivity working
β
REST API: Built-in service on port 1317 responding
β
No crashes: Services stable with auto-restart
β
Port conflicts: All resolved with unique port assignments
polygon-validator-infrastructure/
βββ README.md # Complete project documentation
βββ terraform/
β βββ main.tf # Infrastructure automation
β βββ variables.tf # Environment configuration
β βββ install-polygon.sh # Bootstrap script (small)
β βββ full-install-polygon.sh # Complete installation with ALL FIXES
β βββ polygon-key # SSH private key (not in git)
β βββ polygon-key.pub # SSH public key (not in git)
βββ .gitignore # Security and cleanup rules
# Comprehensive status check
polygon-status
=== Output includes ===
β
Service Status (all running)
β
RPC Connectivity (all accessible)
β
Heimdall Sync Progress (blocks advancing)
β
Peer Connections (6+ peers)
β
Bor Status (RPC responding)
# Live log monitoring
polygon-logs
=== Real-time display ===
β Combined logs from all services
β Color-coded by service type
β Auto-refresh every few seconds
β Filter by error level
# Service management
polygon-restart # Restart all services if neededIf polygon-status shows "command not found" immediately after installation:
# Refresh your shell's command cache
hash -r
# Or start a new shell session
exec bash
# Then try again
polygon-statusThis is a common shell caching issue when new executables are added to PATH directories. The installation script places commands in /usr/local/bin/ which is in your PATH, but your shell may not immediately recognize the new commands until the cache is refreshed.
Problem: Node stuck at "Replay last block using real app" Solution: Added external Ethereum RPC endpoint for checkpoint validation
Problem: --eth-rpc-url flag not recognized
Solution: Use correct flags with underscores: --eth_rpc_url, --bor_rpc_url
Problem: Heimdall and Bor competing for port 3131 Solution: Separate gRPC ports - Heimdall: 3132, Bor: 3133
Problem: heimdallcli rest-server command doesn't exist
Solution: Use built-in REST with Heimdall's --rest-server flag
Problem: Heimdall config file format errors Solution: Remove invalid config file, use command-line flags only
# Everything should be working now:
ssh -i polygon-key ec2-user@<PUBLIC_IP>
# Check status (should show all green)
polygon-status
# Verify Heimdall sync (blocks should be advancing)
curl -s localhost:26657/status | jq '.result.sync_info.latest_block_height'
# Verify Bor RPC (should return version info)
curl -s -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}' \
http://localhost:8545
# Check built-in REST API (should return node info)
curl -s localhost:1317/node_info | jq '.node_info.moniker'β
What We've Built - DATA NODE:
βββ Syncs all blockchain data (Heimdall + Bor)
βββ Provides RPC endpoints for applications
βββ Validates incoming blocks but doesn't create them
βββ Supports network decentralization
βββ No economic stake or voting power
βββ Provides data services to ecosystem
Additional Requirements for VALIDATOR:
βββ Stake minimum POL tokens (~10,000+ POL)
βββ Apply to validator set (limited to 105 slots)
βββ Get accepted by governance/existing validators
βββ Maintain 99%+ uptime requirements
βββ Participate in block production rotation
- Production-Ready Infrastructure: AWS + Terraform automation
- Complete Blockchain Node: Both consensus and execution layers
- Data Services: RPC endpoints for dApps, wallets, and protocols
- Monitoring & Operations: Full observability and management tools
- Troubleshooting Skills: Root cause analysis and problem resolution
- Validator-Ready Infrastructure: Add staking to become validator
- Full sync time: ~42 days (73+ million blocks remaining)
- AWS costs:
$35/day Γ 42 days = **$1,470 for full sync** - Recommended: Use snapshots for faster sync (hours vs. weeks)
- Learning value: Infrastructure setup and troubleshooting completed β
- Snapshot sync: Reduces sync time to hours instead of weeks
- Smaller instances: Use t3.small for learning (reduce costs)
- Selective testing: Deploy for specific learning goals, then destroy
- Heimdall RPC Requirements Issue - Source of the external RPC solution
This project is licensed under the MIT License - see the LICENSE file for details.
π SUCCESS SUMMARY: This project demonstrates fully working Polygon data node infrastructure with automated fixes for all major sync issues. The complete solution includes Infrastructure as Code, proper RPC configuration, port conflict resolution, and comprehensive monitoring tools. The infrastructure is validator-ready - just add economic staking to participate in block production. Perfect for learning blockchain infrastructure management!