Cloudflare Hyperdrive → AWS Private Database
Two supported paths. Both use Cloudflare Tunnel (cloudflared) running inside your AWS VPC to bridge Hyperdrive to a private RDS / Aurora / self-managed database. Both are currently in Beta.
1. Workers VPC — Recommended
This is the newer, simpler path. It does not require Cloudflare Access applications, service tokens, or a public hostname. You create a TCP VPC Service that routes through your tunnel, then point Hyperdrive at the service ID.
Step 1 — Run cloudflared in your VPC
Deploy cloudflared on any host that can reach your database and egress to Cloudflare: a small EC2 instance, an ECS Fargate task, or an EKS pod. Create the tunnel in the Workers VPC dashboard and save the tunnel ID.
Step 2 — Create a TCP VPC Service
npx wrangler vpc service create my-rds \ --type tcp \ --tcp-port 5432 \ --app-protocol postgresql \ --tunnel-id <TUNNEL_ID> \ --ipv4 <RDS_PRIVATE_IP>
Use --hostname instead of --ipv4 if you prefer a DNS name. For MySQL, set --tcp-port 3306 --app-protocol mysql.
Step 3 — Create Hyperdrive via the service ID
npx wrangler hyperdrive create my-hd-config \ --service-id <VPC_SERVICE_ID> \ --database <DB_NAME> \ --user <DB_USER> \ --password <DB_PASS> \ --scheme postgresql
verify_full. RDS uses publicly trusted certificates, so this works without extra flags. If you ever use a self-signed cert, add --cert-verification-mode verify_ca or disabled (dev only).
2. Tunnel + Cloudflare Access
The original Beta path. It secures the tunnel with a Cloudflare Access application and a non-expiring Service Auth token. More moving parts, but fully supported if your org already uses Access.
Step 1 — Create a tunnel and assign a public hostname
In the Cloudflare dashboard (Zero Trust → Networks → Connectors → Tunnels), create a tunnel, run cloudflared in your VPC, then add a public hostname that routes TCP to your RDS endpoint:
Type: TCP URL: my-rds.xxx.us-east-1.rds.amazonaws.com:5432
Step 2 — Secure the tunnel with Access
Create a Self-hosted and private Access application for the hostname. Add a Service Auth policy and generate a non-expiring Service Token. Copy the Client ID and Client Secret.
Step 3 — Create Hyperdrive with Access credentials
npx wrangler hyperdrive create my-hd-config \ --host=rds.yourdomain.com \ --user <DB_USER> --password <DB_PASS> \ --database <DB_NAME> \ --access-client-id <ID> \ --access-client-secret <SECRET>
You must omit --port. Hyperdrive routes database messages to the tunnel’s public hostname; the tunnel’s service config handles port routing internally.
Comparison
| Dimension | Workers VPC | Tunnel + Access |
|---|---|---|
| Access application needed | No | Yes |
| Service token needed | No | Yes (non-expiring) |
| Public hostname needed | No | Yes |
| Dashboard steps | Minimal | Multiple (Tunnel + Access + Token) |
| TLS verification default | verify_full | Does not verify origin cert by default |
| Recommended for | New setups, clean IaC | Orgs already using Cloudflare Access |
AWS-Specific Practical Notes
- Where to run cloudflared: Any subnet with egress to Cloudflare and ingress to RDS. A t3.micro EC2 in a private subnet with a NAT gateway, or an ECS Fargate task, is typical. No public IP needed on the database.
- Security group: The RDS security group must allow the DB port (5432 for PostgreSQL, 3306 for MySQL) from the
cloudflaredhost’s security group or IP. - TLS required: Hyperdrive requires TLS on the origin. Enable it on RDS (default for most engines). RDS certificates are publicly trusted, so Workers VPC’s
verify_fullworks without custom CA flags. - No public IP needed: Neither path requires your RDS to have a public IP or sit in a public subnet. The tunnel creates an outbound-only connection to Cloudflare.
- Wrangler version: Ensure wrangler v3.65+ for full Hyperdrive private-database support.
websocket: bad handshake.
Sources: Connect to a private database using Workers VPC · Connect to a private database using Tunnel