Skip to content

The database was fine. The cloud around it wasn't.

Posted in Azure, Postgresql, Networking, Cloud

By Dušan Dželebdžić

Photo by Steve A Johnson on Unsplash
Photo by Steve A Johnson on Unsplash

I deployed an application against Azure Database for PostgreSQL Flexible Server recently, and the database itself was never the problem. PostgreSQL was up, healthy, and happily accepting connections the entire time. The cloud wrapped around it was another story, and it cost me the better part of a day.

Every provider makes the same promise: "it's managed." What the promise quietly leaves out is the networking, the DNS, the TLS defaults, the firewall rules, and the three different portal blades you'll need to understand before your app gets to say hello to its own database.

The usual checklist ran out fast

The app kept failing to connect. Nothing exotic, just a timeout. The connection string looked fine: host, user, dbname, password, all correct. So I ran through the standard suspects. Firewall rules? Fine. Credentials? Correct. Is the server actually running? Yes, Azure swears it is.

That's normally where this kind of story ends. Someone fat-fingered a password, you fix it, you move on. Not this time. The checklist ran out and the timeout stayed.

The hostname that didn't exist

The server was configured for private access, which sounds like the simple option. It isn't. Azure doesn't just hand your database a private IP and call it a day. It expects you to understand Azure Private DNS Zones, because the server's hostname only resolves through a zone like privatelink.postgres.database.azure.com, and that zone has to be explicitly linked to your virtual network.

If the link is missing, the hostname doesn't resolve to a wrong address or a public one. It simply doesn't exist:

could not translate host name

At that point you're not debugging PostgreSQL anymore. You're debugging Azure's networking model, from inside an application that can only tell you "cannot connect to database." The fix was linking the Private DNS Zone to the VNet the app actually runs in. One checkbox, buried two portals away from anything labeled "PostgreSQL."

Thirty minutes for one line

With DNS sorted, the connection still failed, because Azure requires TLS and my client wasn't offering it. This is where PostgreSQL client libraries get to have opinions. Some try SSL first and fall back. Some don't try at all. Some negotiate, some fail on the spot. The server isn't broken and the client isn't broken; their defaults just don't agree.

The entire fix was one parameter:

sslmode=require

One line. Thirty minutes of investigation. That ratio is the signature of cloud debugging.

"Managed" means the complexity moved

Here's the part I actually find interesting. People assume a managed service means less complexity. It usually means the complexity relocated. Run PostgreSQL yourself and you own backups, upgrades, replication, and storage. Hand it to Azure and those genuinely disappear from your plate, which is great. But now you own VNets, private endpoints, DNS zones, firewall rules, and managed identities instead. The database becomes the easy part.

And this isn't an Azure problem. AWS does the same thing, Google Cloud does the same thing. Cloud providers are very good at hiding infrastructure. They're much less good at hiding distributed systems, and eventually every abstraction leaks: a DNS zone here, a security group there, a certificate that was supposed to be someone else's job.

The tradeoff is still often worth making. I'd rather debug a DNS zone link once than babysit replication forever. But pretending the complexity evaporated helps nobody, least of all the person staring at a connection timeout.

Takeaway

The SQL worked, the schema worked, authentication worked. Every single issue lived outside PostgreSQL, in services I didn't know I was operating until they failed. So now, whenever someone tells me "don't worry, it's managed," my next question is: "which part isn't?" That's where the next four hours usually go. The next time a managed service refuses to work, don't assume your application is broken. The bug may be sitting in a DNS zone you didn't know existed.


Fighting a cloud setup that refuses to connect? Send me the details and I'll take a look.