Skip to content

Commit

Permalink
fix(blocks): retain data field from config on Update (#248)
Browse files Browse the repository at this point in the history
When calling Update on a block, we call Get to retrieve the latest copy of the block object from the API. This response does not include the $ref expression if it was originally provided. This was causing "inconsistent result after apply" errors.

So for now, we'll use the user-defined data field when updating the state instead of the (incomplete) data field from the Get request.

Closes #240

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
mitchnielsen and github-actions[bot] authored Aug 23, 2024
1 parent d6d8355 commit 0a82c91
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 7 deletions.
Binary file added docs/images/block-type-inspect-ref-key.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions docs/resources/block.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,42 @@ resource "prefect_block" "gcp_credentials_key" {
"service_account_info" = jsondecode(base64decode(google_service_account_key.test_bot.private_key))
})
}
# example:
# some resources need to be referenced using a "$ref" key
resource "prefect_block" "my_dbt_cli_profile" {
name = "my-dbt-cli-profile"
type_slug = "dbt-cli-profile"
data = jsonencode({
"name" = "mine"
"target" = "prefect-dbt-profile"
})
}
resource "prefect_block" "my_dbt_run_operation_block" {
name = "my-dbt-operations"
type_slug = "dbt-core-operation"
# note the "$ref" key wrapping the "block_document_id" reference
data = jsonencode({
"commands" = ["dbt deps", "dbt seed", "dbt run"]
"dbt_cli_profile" = { "$ref" : { "block_document_id" : prefect_block.my_dbt_cli_profile.id } }
})
}
```

One of the examples above mentions the special syntax needed when referencing
other Terraform resources from within the `data` attribute. You can use `prefect
block type inspect` to confirm when this field is required.

For example, the following screenshot shows the output of `prefect block type inspect
dbt-core-operation`. It mentions the `$ref` key that the API expects.

<img src="https://raw.githubusercontent.com/PrefectHQ/terraform-provider-prefect/main/docs/images/block-type-inspect-ref-key.png" alt="Block type inspect ref key" align="center" width="400">

For more information on the `$ref` syntax definition, see the
[dollarref's specification in the JSON schema](https://json-schema.org/understanding-json-schema/structuring#dollarref).

<!-- schema generated by tfplugindocs -->
## Schema

Expand Down
22 changes: 22 additions & 0 deletions examples/resources/prefect_block/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,25 @@ resource "prefect_block" "gcp_credentials_key" {
"service_account_info" = jsondecode(base64decode(google_service_account_key.test_bot.private_key))
})
}

# example:
# some resources need to be referenced using a "$ref" key
resource "prefect_block" "my_dbt_cli_profile" {
name = "my-dbt-cli-profile"
type_slug = "dbt-cli-profile"

data = jsonencode({
"name" = "mine"
"target" = "prefect-dbt-profile"
})
}
resource "prefect_block" "my_dbt_run_operation_block" {
name = "my-dbt-operations"
type_slug = "dbt-core-operation"

# note the "$ref" key wrapping the "block_document_id" reference
data = jsonencode({
"commands" = ["dbt deps", "dbt seed", "dbt run"]
"dbt_cli_profile" = { "$ref" : { "block_document_id" : prefect_block.my_dbt_cli_profile.id } }
})
}
14 changes: 7 additions & 7 deletions internal/provider/resources/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,13 +418,13 @@ func (r *BlockResource) Update(ctx context.Context, req resource.UpdateRequest,
return
}

byteSlice, err := json.Marshal(block.Data)
if err != nil {
resp.Diagnostics.Append(helpers.SerializeDataErrorDiagnostic("data", "Block Data", err))

return
}
plan.Data = jsontypes.NewNormalizedValue(string(byteSlice))
// Normally, we would also copy the retrieved Block's Data field into the
// plan object before setting the current state.
//
// However, the API's GET method does not return the `$ref` expression if it
// was specified in the Data field on the Block resource. This leads to
// "inconsistent result after apply" errors. For now, we'll skip copying the
// retrieved Block's Data field and use what was specified in the plan.

diags = resp.State.Set(ctx, &plan)
resp.Diagnostics.Append(diags...)
Expand Down
Binary file added templates/images/block-type-inspect-ref-key.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions templates/resources/block.md.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}"
subcategory: ""
description: |-
{{ .Description | plainmarkdown | trimspace | prefixlines " " }}
---

# {{.Name}} ({{.Type}})

{{.Description}}

## Example Usage

{{tffile .ExampleFile}}

One of the examples above mentions the special syntax needed when referencing
other Terraform resources from within the `data` attribute. You can use `prefect
block type inspect` to confirm when this field is required.

For example, the following screenshot shows the output of `prefect block type inspect
dbt-core-operation`. It mentions the `$ref` key that the API expects.

<img src="https://raw.githubusercontent.com/PrefectHQ/terraform-provider-prefect/main/docs/images/block-type-inspect-ref-key.png" alt="Block type inspect ref key" align="center" width="400">

For more information on the `$ref` syntax definition, see the
[dollarref's specification in the JSON schema](https://json-schema.org/understanding-json-schema/structuring#dollarref).

{{.SchemaMarkdown | trimspace}}

## Import

Import is supported using the following syntax:

{{codefile "shell" .ImportFile}}

0 comments on commit 0a82c91

Please sign in to comment.