← Back to Projects

Managed SQL as Code, Safely

Renames, one-way settings, firewall-blocked auth and decommissioning, each with the check that kept it safe

Platform: Azure SQL MI + SQL on VMs
IaC: Terraform + GitHub Actions
Network: Private endpoints
Role: Platform engineer

Overview

Database changes are where a Terraform mistake hurts most: replacements are slow, some settings can't be undone, and one wrong plan can destroy data. These four changes each came with a specific check that kept them safe.

Architecture

App subnetSQL MIdelegated subnetPrivate endpoint+ DNS recordHub firewall0.0.0.0/0 egress
Spoke VNet layout. App-to-database traffic inside one VNet never touches the firewall.

The Four Changes

ChangeWhat I didThe check that mattered
Instance renameDestroy/recreate under new names, with new private endpoints and DNS records. Push runs plan only, and apply runs on manual dispatchRecovered partial applies after CI token expiry by importing or deleting orphans
Update policyReleased a module version that exposes the policy, and confirmed a no-change plan before opting inFlagged that the target policy is one-way and asked the requester to confirm it was needed
Entra auth for SQL VMsUsed firewall logs to show the hub firewall was denying graph.microsoft.comProposed one scoped FQDN rule instead of a broad allow
Decommission (one env)count / for_each gated on environment, plus moved blocksThe plan showed a handful of destroys. A run with the pipeline's "enable destroy" option planned dozens, so that option was never used
remove from one environment only (illustrative)
locals {
  copy_enabled = var.environment != "uat"
}

resource "azurerm_storage_account" "copy" {
  count = local.copy_enabled ? 1 : 0
  # ...
}

moved {
  from = azurerm_storage_account.copy
  to   = azurerm_storage_account.copy[0]
}

Reviewing the Request, Not Just the Code

One request asked for new IP groups and a firewall rule between an app and its database. Checking it against the real network showed:

I raised all three with the requester before opening any networking PRs.

Key Outcomes

Lessons Learned

Conclusion

Safe database infrastructure isn't about avoiding change. It's about knowing exactly what each change will do, and stopping to ask when the answer can't be undone.

Technologies Used

Azure SQL Managed InstanceSQL Server on Azure VMsTerraformGitHub ActionsAzure FirewallPrivate EndpointsPrivate DNSIP GroupsRoute TablesEntra ID

About this case study: this write-up is drawn from my hands-on platform engineering experience. Organisation names, system names, figures and timelines have been changed or generalised, and all code, configuration and queries are illustrative examples written for this page.

← Moving Central Logging to a New RegionAI-Assisted Platform Operations →
← Back to Projects Get in Touch