magodo / terraform-provider-restful

Terraform provider to manage RESTful resources
https://registry.terraform.io/providers/magodo/restful
Mozilla Public License 2.0
15 stars 5 forks source link

Specify query for read #115

Closed IamMushroom closed 2 months ago

IamMushroom commented 2 months ago

Hi everyone! I tried to use this provider to manage HAProxy via Data Plane API ( HAProxy Data Plane API | HAProxy Documentation ).

With the Data Plane API, I need to create a transaction and use its ID as a query parameter every time I want to create or modify a resource. After modifying the resource, I need to commit that transaction.

My problem is that the query attribute is used for any method, including GET. This means that when TF writes the ID of the old transaction to tfstate, I can't make a terraform plan.

So my question is as follows. Is there any way to specify a read request?

My code:

resource "null_resource" "always_run" {
  triggers = { timestamp = "${timestamp()}" }
}

data "restful_resource" "version_test01" {
  id       = local.path.version
  provider = restful.test01
}

resource "restful_operation" "create_transaction_test01" {
  provider   = restful.test01
  id_builder = "$(body.id)"
  path       = local.path.transactions
  method     = "POST"
  query = {
    version = ["${data.restful_resource.version_test01.output}"]
  }
  lifecycle {
    replace_triggered_by = [null_resource.always_run]
  }
}

resource "restful_resource" "backend_test01" {
  provider = restful.test01
  path     = "${local.path.backends}"
  query = {
    transaction_id = [ restful_operation.create_transaction_test01.id ]
  }
  body = {
    name = var.backend_name
    balance = {
      algorithm = var.balance_type
    }
    type = var.backend_mode
  }
  read_path   = "${local.path.backends}/${var.backend_name}"
  update_path = "${local.path.backends}/${var.backend_name}"
  delete_path = "${local.path.backends}/${var.backend_name}"
}

resource "restful_operation" "commit_transaction_test01" {
  provider   = restful.test01
  path       = "${local.path.transactions}/${restful_operation.create_transaction_test01.id}"
  method     = "PUT"
  depends_on = [restful_resource.backend_test01]
  lifecycle {
    replace_triggered_by = [restful_operation.create_transaction_test01]
  }
}
magodo commented 2 months ago

@IamMushroom Could you please try out the main branch to see if that meets your requirement? If so, I'll make a new release then.

IamMushroom commented 2 months ago

@magodo

Hello! Thx, it seems that query splitting works, but I'm afraid, it not working in my case. I've got new error: The Terraform provider unexpectedly returned no resource state. It happened, because resource state reading right after creating happens with read_query path (without transaction). But until my transaction is committed, I can't read resource's state without transaction ID (yeah, it's complicated).

I think, that my case is very uncommon, so I can fork your provider, and try to fix my trouble by myself.

magodo commented 2 months ago

@IamMushroom I'm happy to provide a general solution for you as long as you can elaborate your use case.

IamMushroom commented 2 months ago

@magodo I think, that easiest way to solve my problem is using read_query and read_headers only on terraform plan step

magodo commented 2 months ago

@IamMushroom Unfortunately, that's not something we can control at the provider level. One thing might interests you is that you can skip the refresh (actually doing a read) step during a terraform plan/apply by using the -refresh=false option.

IamMushroom commented 2 months ago

@magodo Yeah, I know this solution, i hoped that I can go without ignoring manual changes, or something like that =)

Anyway, thanks for your help and for your work!