Smoothing over practitioner-facing breaking changes

Suppose I release a provider with a resource like this:

resource "ice_cream_order" "example" {
  pickup_person = "Ben Cohen"
  cones         = [ "vanilla", "chocolate" ]
}

Pretty soon I realize the schema is all wrong, so an updated provider uses this schema:

resource "ice_cream_order" "example" {
  pickup_person = "Ben Cohen"
  cones = [
    {
      flavor      = "vanilla"
      scoop_count = 1
      sprinkles   = true
    },
    {
      flavor      = "chocolate"
      scoop_count = 1
      sprinkles.  = false
    },
  ]
}

The practitioner experience of upgrading to the new provider is awful. Even if they update their configurations to align with the new schema, the new provider’s Read() will fail right out of the gate when it calls req.State.Get(ctx, &newSchemaObj) because the data in the Terraform state (old schema) can’t be unpacked onto the struct the provider is using (new schema).

Would it be reasonable to “upgrade” the state in the new provider release by detecting failures of req.State.Get(ctx, &newSchemaObj) and then attempting req.State.Get(ctx, &oldSchemaObj)? I’d follow up by converting the oldSchemaObj to a newSchemaObj using some reasonable defaults.

I think I’d only need to take this approach with req.State.Get() in Read(). Would it be relevant anywhere else?

What dark corners await me if I attempt such a scheme?

If there’s a better way to handle this mess, please nudge me in that direction :slight_smile:

Hey @hQnVyLRx

It sounds like what you’re poking at here is a state upgrade in framework (or state migration in Plugin SDKv2 land). Having caused a few breaking type changes myself in providers, state upgrades are your best friend here. The tutorials I linked should help you add one for the schema changes made and Terraform should take care of the rest!

I hope this is what you were after, let me know if you require any further guidance.

@stephybun

Yep! That’s exactly what I was looking for. I had no idea that the resource.ResourceWithUpgradeState interface was a thing.

Thank you!

1 Like