Making Infrastructure Safe for Agents with Kelsey Hightower 3.18.26
Register Here!It Doesn't Have to be This Hard: A DevOps Journey
Using common DevOps tooling shouldn't be this hard.
All I wanted to do was optimize my Terraformā¦
The Problem
Upgrading Azure Postgres Flexible Server in Azure can be a bit of a pain. Sure, the console takes care of the process for you with 2 clicks (although sometimes that process fails). But who uses click-ops? I want to upgrade my Postgres version using Terraform. How hard could it be?
The Journey
Ok, so I need to upgrade my Postgres version. Iām using Terraform, so Iāll just update my [.c-highlighted]azurerm_postgresql_flexible_server[.c-highlighted] resource and run terraform plan to verify. Easy peasy.
resource "azurerm_postgresql_flexible_server" "main" {
name = var.name
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
version = "13" -> "15"
}
ā
And then...
# azurerm_postgresql_flexible_server.main must be replaced
-/+ resource "azurerm_postgresql_flexible_server" "main" {
~ version = "13" -> "15" # forces replacement
ā
Ugh, ok, letās find out how to upgrade the version of a Postgres server in Azure without destroying and recreating the resource. Looks like I can use [.c-highlighted]create_mode = "Update"[.c-highlighted] to update the resource instead of destroying and recreating it.
ā
Howeverā¦
Without affecting my production Postgres server, Iāll spin up a dev server. Iāll set [.c-highlighted]create_mode = "Default"[.c-highlighted] and deploy.
resource "azurerm_postgresql_flexible_server" "main" {
name = var.name
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
version = "13"
create_mode = "Default"
}
ā
Great, that deployed. Iāll update the resource to [.c-highlighted]create_mode = "Update"[.c-highlighted], update the version, and deploy again.
resource "azurerm_postgresql_flexible_server" "main" {
name = var.name
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
version = "15"
create_mode = "Update"
}
ā
Success! That seems to update the version of the Postgres server without destroying and recreating it. So, what do I do with [.c-highlighted]create_mode[.c-highlighted]? What if I set it back to [.c-highlighted]"Default"[.c-highlighted]?
resource "azurerm_postgresql_flexible_server" "main" {
name = var.name
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
version = "15"
create_mode = "Default"
}
ā
Nope, that deletes the resource. Ok, so Iāll just leave it as [.c-highlighted]"Update"[.c-highlighted] I guess. Before adding this into my production server, Iāll deploy a Postgres server identical to production and test the update process. I add the field for [.c-highlighted]create_mode = "Update"[.c-highlighted] and run a [.c-highlighted]terraform plan[.c-highlighted].
# azurerm_postgresql_flexible_server.main must be replaced
-/+ resource "azurerm_postgresql_flexible_server" "main" {
+ create_mode = "Update" # forces replacement
ā
So, I canāt add in [.c-highlighted]create_mode = "Update"[.c-highlighted] without destroying and recreating the resource. But I canāt update the version without adding in [.c-highlighted]create_mode = "Update"[.c-highlighted]. What do I do? Iāll just add in [.c-highlighted]create_mode = "Default"[.c-highlighted] and see what happens.
# azurerm_postgresql_flexible_server.main must be replaced
-/+ resource "azurerm_postgresql_flexible_server" "main" {
+ create_mode = "Default" # forces replacement
ā
I need to break this down a bitā¦
- I need to update the version of my Postgres server without destroying and recreating it
- I canāt update the version without adding in create_mode = "Update"
- I canāt add in create_mode = "Update without destroying and recreating the resource
- I canāt add in create_mode at all without destroying and recreating the resource
The only thing I can do at this point, which is not a great experience, is to create/deploy a new Postgres server with [.c-highlighted]create_mode = "PointInTimeRestore"[.c-highlighted] to migrate my data from my production Postgres server to the new server with the updated version. Iāll have to update my application to point to the new Postgres server, and then destroy the old Postgres server. This is not ideal, but itās the only way I can update the version of my Postgres server without destroying and recreating it. Iām not sure if this is a limitation of Terraform or Azure, but itās not a great experience and will cause downtime.
ā
The Painful Reality
In the DevOps landscape, we often face a paradox where tools and practices intended to streamline operations inadvertently add complexity. This complexity isnāt just about technical configurations; itās about the burden it places on teams. Each update or change, rather than simplifying, often feels like navigating a maze, with the real cost being sidelined innovation and agility.
The industryās push towards DevOps has sometimes resulted in oversimplifications, overlooking the intricate realities of technology and team dynamics. This leads to a scenario where āyou build it, you run itā becomes more of a burden than empowerment. Teams find themselves caught in a cycle of managing both development and operational demands, detracting from their core work of creating value.
As we pursue the DevOps ideal, itās vital to focus not just on deploying and managing infrastructure but on enabling meaningful, value-driven work. This means building robust internal platforms that evolve with team and business needs, while empowering the team to self-serve. The goal should be smarter, empathetic engineering that eases the complexities of DevOps, fostering an environment where teams can do their best work with minimal friction.
ā


