PrefectHQ / terraform-provider-prefect

Terraform Provider for Prefect Cloud
https://registry.terraform.io/providers/PrefectHQ/prefect/latest/docs
Apache License 2.0
29 stars 13 forks source link

feat(blocks): add update resource operation #198

Closed mitchnielsen closed 3 weeks ago

mitchnielsen commented 3 weeks ago

Summary

Closes #182.

Testing (click to expand) ## Testing - OSS ### Setup First, run `docker-compose up -d` to start a local Prefect instance. Next, create a block resource to use with the local instance, and enable the provider: ```diff diff --git a/examples/provider-install-verification/main.tf b/examples/provider-install-verification/main.tf index 7799578..f1119ee 100644 --- a/examples/provider-install-verification/main.tf +++ b/examples/provider-install-verification/main.tf @@ -10,9 +10,14 @@ provider "prefect" { endpoint = "http://localhost:4200/api" } -resource "prefect_work_pool" "example" { - name = "my-work-pool" - type = "kubernetes" - description = "example work pool" - paused = true +resource "prefect_block" "secret" { + name = "foo" + type_slug = "secret" + + data = jsonencode({ + "value" : "bar" + }) + + # set the workpace_id attribute on the provider OR the resource + # workspace_id = "" } diff --git a/internal/provider/provider.go b/internal/provider/provider.go index f7f4ef4..5f95b51 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -242,6 +242,6 @@ func (p *PrefectProvider) Resources(_ context.Context) []func() resource.Resourc resources.NewWorkspaceAccessResource, resources.NewWorkspaceResource, resources.NewWorkspaceRoleResource, - // resources.NewBlockResource, + resources.NewBlockResource, } } ``` Apply it with Terraform: ``` Terraform will perform the following actions: # prefect_block.secret will be created + resource "prefect_block" "secret" { + created = (known after apply) + data = jsonencode( { + value = "bar" } ) + id = (known after apply) + name = "foo" + type_slug = "secret" + updated = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes prefect_block.secret: Creating... prefect_block.secret: Creation complete after 0s [id=5e1f535d-ff3c-4164-9117-e1ecba53a122] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. ``` Now that it's created, try to read the value. We can use a quick Python script in `test.py`: ```python from prefect.blocks.system import Secret print(Secret.load("foo").get()) ``` ``` $ python test.py bar ``` Now let's change it so we can test `Update`. Change the value in `main.tf` to `baz`. Next, run `terraform plan`: ``` prefect_block.secret: Refreshing state... [id=5e1f535d-ff3c-4164-9117-e1ecba53a122] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: ~ update in-place Terraform will perform the following actions: # prefect_block.secret will be updated in-place ~ resource "prefect_block" "secret" { ~ created = "2024-06-06T21:05:27Z" -> (known after apply) ~ data = jsonencode( ~ { ~ value = "bar" -> "baz" } ) id = "5e1f535d-ff3c-4164-9117-e1ecba53a122" name = "foo" ~ updated = "2024-06-06T21:05:27Z" -> (known after apply) # (1 unchanged attribute hidden) } Plan: 0 to add, 1 to change, 0 to destroy. ``` Apply the change with `terraform apply` and then check the value again: ``` $ python test.py baz ``` The value was successfully updated. ## Testing - Cloud First, update the `main.tf` file to point to Staging and reset the block value to `bar`: ```diff diff --git a/examples/provider-install-verification/main.tf b/examples/provider-install-verification/main.tf index 7799578..55db778 100644 --- a/examples/provider-install-verification/main.tf +++ b/examples/provider-install-verification/main.tf @@ -7,12 +7,19 @@ terraform { } provider "prefect" { - endpoint = "http://localhost:4200/api" + endpoint = "https://api.prefect.cloud" + account_id = "" + workspace_id = "" } -resource "prefect_work_pool" "example" { - name = "my-work-pool" - type = "kubernetes" - description = "example work pool" - paused = true +resource "prefect_block" "secret" { + name = "foo" + type_slug = "secret" + + data = jsonencode({ + "value" : "bar" + }) + + # set the workpace_id attribute on the provider OR the resource + # workspace_id = "" } ``` Apply it with Terraform: ``` $ terraform plan ... Terraform will perform the following actions: # prefect_block.secret will be created + resource "prefect_block" "secret" { + created = (known after apply) + data = jsonencode( { + value = "bar" } ) + id = (known after apply) + name = "foo" + type_slug = "secret" + updated = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes prefect_block.secret: Creating... prefect_block.secret: Creation complete after 0s [id=d8ae1c60-1248-407b-9ad8-ddb412ac6b1a] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. ``` Let's test it with Python: ``` $ python test.py bar ``` And let's change it to `baz` in `main.tf` and apply it to confirm `Update`: ``` $ terraform apply ... Terraform will perform the following actions: # prefect_block.secret will be updated in-place ~ resource "prefect_block" "secret" { ~ created = "2024-06-06T21:40:55Z" -> (known after apply) ~ data = jsonencode( ~ { ~ value = "bar" -> "baz" } ) id = "4f308f8f-cb19-4823-aabc-bbd8debe4af1" name = "foo" ~ updated = "2024-06-06T21:40:55Z" -> (known after apply) # (1 unchanged attribute hidden) } Plan: 0 to add, 1 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes prefect_block.secret: Modifying... [id=4f308f8f-cb19-4823-aabc-bbd8debe4af1] prefect_block.secret: Modifications complete after 1s [id=4f308f8f-cb19-4823-aabc-bbd8debe4af1] Apply complete! Resources: 0 added, 1 changed, 0 destroyed. ``` And get the new value with Python: ``` $ python test.py baz ```
mitchnielsen commented 3 weeks ago

There's a fair amount of repetition in internal/provider/resources/block.go, but to keep these PRs simple I'll just put this one up for review and we can DRY things up separately.