hashicorp / hashicorp/terraform-plugin-framework
Performance issue when run Terraform Plan with many Block Sets or NestedAttribute Sets
- Dominant language
- Go
- Stars
- 384
- Forks
- 107
- Avg merge
- 3m
- Merged PRs (30d)
- 1
Description
### Module version
```
v1.2.0 & v1.3.1
```
### Description
After migrating resources of my provider [jeremmfr/junos](https://github.com/jeremmfr/terraform-provider-junos) from SDK plugin to this framework plugin, the time to run a `terraform plan` with a config that have many block sets has been increased very significantly.
For 1000 items of block set, a `terraform plan` (with empty state) with provider including module `sdk/v2` take ~1.3 seconds and take ~ **70 seconds** with provider including `plugin-framework`.
A user of my provider has a time of **19 minutes** to run terraform plan with the new version of the provider including `plugin-framework` instead of 52 seconds with the previous version of the provider including module `sdk/v2`
### Tests
I tested to remove all `PlanModifiers` and `Validators` fields on each attribute, and `ValidateConfig` function for resources, using the latest version of this module (v1.3.1) but there's no change.
The problem disappears if replace `schema.SetNestedBlock` with `schema.ListNestedBlock`: 70 seconds to 1 second.
I reproduce the problem with provider `hashicups` and `hashicups_order` resources.
I tested 1000 blocks`items` on a resource `hashicups_order` with different modifications of `items` block.
[hashicorp/terraform-provider-hashicups](https://github.com/hashicorp/terraform-provider-hashicups) schema.TypeSet : 3.8 - 4 seconds
[hashicorp/terraform-provider-hashicups](https://github.com/hashicorp/terraform-provider-hashicups) schema.TypeList : 0.5 - 0.8 seconds
[hashicorp/terraform-provider-hashicups-pf](https://github.com/hashicorp/terraform-provider-hashicups-pf) schema.SetNestedBlock : **49.1 - 49.7** seconds
[hashicorp/terraform-provider-hashicups-pf](https://github.com/hashicorp/terraform-provider-hashicups-pf) schema.ListNestedBlock : 0.8 - 1.1 seconds
[hashicorp/terraform-provider-hashicups-pf](https://github.com/hashicorp/terraform-provider-hashicups-pf) schema.SetNestedAttribute : **49.0 - 49.4** seconds
[hashicorp/terraform-provider-hashicups-pf](https://github.com/hashicorp/terraform-provider-hashicups-pf) schema.ListNestedAttribute : 0.7 - 0.9 seconds
### Relevant provider source code
To test with block sets, clone [hashicorp/terraform-provider-hashicups-pf](https://github.com/hashicorp/terraform-provider-hashicups-pf) and apply this patch :
```diff
diff --git a/internal/provider/order_resource.go b/internal/provider/order_resource.go
index 4fe16cc..67203cd 100644
--- a/internal/provider/order_resource.go
+++ b/internal/provider/order_resource.go
@@ -76,10 +76,12 @@ func (r *orderResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
Description: "Timestamp of the last Terraform update of the order.",
Computed: true,
},
- "items": schema.ListNestedAttribute{
+ },
+ Blocks: map[string]schema.Block{
+ "items": schema.SetNestedBlock{
Description: "List of items in the order.",
- Required: true,
- NestedObject: schema.NestedAttributeObject{
+ // Required: true,
+ NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{
"quantity": schema.Int64Attribute{
Description: "Count of this item in the order.",
@@ -87,7 +89,7 @@ func (r *orderResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
},
"coffee": schema.SingleNestedAttribute{
Description: "Coffee item in the order.",
- Required: true,
+ Optional: true,
Attributes: map[string]schema.Attribute{
"id": schema.Int64Attribute{
Description: "Numeric identifier of the coffee.",
```
& disable `hashicups.NewClient` code in provider configure function
To test with nested atttribute sets, clone [hashicorp/terraform-provider-hashicups-pf](https://github.com/hashicorp/terraform-provider-hashicups-pf) and apply this patch :
```diff
diff --git a/internal/provider/order_resource.go b/internal/provider/order_resource.go
index 4fe16cc..ea229a7 100644
--- a/internal/provider/order_resource.go
+++ b/internal/provider/order_resource.go
@@ -76,7 +76,7 @@ func (r *orderResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
Description: "Timestamp of the last Terraform update of the order.",
Computed: true,
},
- "items": schema.ListNestedAttribute{
+ "items": schema.SetNestedAttribute{
Description: "List of items in the order.",
Required: true,
NestedObject: schema.NestedAttributeObject{
@@ -87,7 +87,7 @@ func (r *orderResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
},
"coffee": schema.SingleNestedAttribute{
Description: "Coffee item in the order.",
- Required: true,
+ Optional: true,
Attributes: map[string]schema.Attribute{
"id": schema.Int64Attribute{
Description: "Numeric identifier of the coffee.",
```
& disable `hashicups.NewClient` code in provider configure function
### Terraform Configuration Files
To test with block sets:
```hcl
resource "hashicups_order" "example" {
dynamic "items" {
for_each = range(1, 1000)
content {
quantity = items.value
}
}
}
```
To test with nested attribute sets:
```hcl
resource "hashicups_order" "example2" {
items = [
for e in range(1, 1000) : {
quantity = e
}
]
}
```
### Expected Behavior
The `terraform plan` command takes a reasonable time to run when there are many block sets.
### Actual Behavior
The `terraform plan` command takes a very long time to run when there are many block sets.
### Steps to Reproduce
1. build hashicups provider
1. `terraform init`
1. `terraform plan`
### References
jeremmfr/terraform-provider-junos#498
Contributor guide
Assessment
This issue has not been assessed yet.