Mastercard / terraform-provider-restapi

A terraform provider to manage objects in a RESTful API
Other
808 stars 217 forks source link

Updating a resource with id in the payload #230

Open seblatre opened 1 year ago

seblatre commented 1 year ago

Hello ! I'm trying to make use of the Dremio Role API with this great restapi provider.

I managed perfectly the Create and Delete lifecycle but I cannot make the Update part work. The specificity of this API is that id is required both in the URL and in the JSON payload. I tried several ways and read many things but couldn't make it.

Do you have any idea/hint to tackle this? Thanks in advance !

Provider configuration:

provider "restapi" {
  uri                  = "https://dremio.xxx.com/api/v3"
  debug                = true
  write_returns_object = true
  create_method        = "POST"
  update_method        = "PUT"

  headers = {
    "Content-Type"  = "application/json"
    "Authorization" = "Bearer ..."
  }
}

Created like this:

resource "restapi_object" "poc" {
  path         = "/role"
  id_attribute = "id"
  data         = <<-EOT
  {
    "name": "test"
  }
  EOT
}

Would like to update it by changing the name to "test_2" but gives error from API as update body is missing the "id":

│ Error: unexpected response code '400': {"errorMessage":"Id in the url path is not the same as the id in the request.","context":[],"moreInfo":""}
│
│   with module.dremio.restapi_object.poc,
│   on modules\dremio\main.tf line 333, in resource "restapi_object" "poc":
│  333: resource "restapi_object" "poc" {
amvapor commented 1 year ago

I'm running into a similar situation, with the API I am interacting with, I can POST /people to create a user object, and I can refresh the data with GET /people/{id} But the interface does updates with a POST /people the same as create, but when an ID is included in the data payload, it's considered an update. I'd love to be able to do something like the following with {id} being rewritten to the actual ID value on the update call.


resource "restapi_object" "users" {
  path = "/people"

  data = jsonencode({
    firstName          = "John"
    lastName           = "Doe"
  })
  update_data = jsonencode({
    id                        = "{id}"
    firstName          = "John"
    lastName           = "Doe"
  })
}
ivank commented 7 months ago

Actually just discovered that copy_keys provides functionality for exactly this purpose!

so the fix would be:

provider "restapi" {
  uri                  = "https://dremio.xxx.com/api/v3"
  debug                = true
  write_returns_object = true
  create_method        = "POST"
  update_method        = "PUT"
  copy_keys            = ["id"]

  headers = {
    "Content-Type"  = "application/json"
    "Authorization" = "Bearer ..."
  }
}
iam-take commented 5 months ago

@ivank I am having the same request but I am really struggling with this option do you perhaps have piece of example code to see how this would work?

seblatre commented 5 months ago

Thanks @ivank, your post saved my life with this use case. Works perfectly for another use case as well with AzureDevops release/definitions's REST API. I personnaly used the following configuration in the restapi provider

copy_keys = ["id", "revision"]