phillbaker / terraform-provider-elasticsearch

An elasticsearch provider for terraform
https://registry.terraform.io/providers/phillbaker/elasticsearch
Mozilla Public License 2.0
303 stars 133 forks source link

empty tenant_permissions block in elasticsearch_opensearch_role triggers Go panic #326

Closed iul1an closed 1 year ago

iul1an commented 1 year ago

The following configuration produces an empty tenant_permissions block when tenant_permissions["tenant_patterns"] and tenant_permissions["allowed_actions"] are empty lists. The empty tennant_permissions makes the plugin crash.

locals {
  roles = {
    zzz = {
        cluster_permissions = [
          "cluster_monitor",
          "cluster_composite_ops",
          "indices:admin/template/get",
          "indices:admin/template/put",
          "cluster:admin/ingest/pipeline/put",
          "cluster:admin/ingest/pipeline/get"
        ]
        index_permissions = {
          index_patterns  = ["zzz-*"]
          allowed_actions = ["crud", "create_index"]
        }
    }
  }
}
resource "elasticsearch_opensearch_role" "this" {
  for_each    = local.roles
  role_name   = each.key
  description = try(local.roles[each.key]["description"], null)

  cluster_permissions = try(local.roles[each.key]["cluster_permissions"], [])

  index_permissions {
    index_patterns  = try(local.roles[each.key]["index_permissions"]["index_patterns"], [])
    allowed_actions = try(local.roles[each.key]["index_permissions"]["allowed_actions"], [])
  }

  tenant_permissions {
    tenant_patterns = try(local.roles[each.key]["tenant_permissions"]["tenant_patterns"], [])
    allowed_actions = try(local.roles[each.key]["tenant_permissions"]["allowed_actions"], [])
  }

  depends_on = [aws_elasticsearch_domain.opensearch]
}

terraform plan output:

  # elasticsearch_opensearch_role.this["zzz"] will be updated in-place
  ~ resource "elasticsearch_opensearch_role" "this" {
        id                  = "zzz"
        # (2 unchanged attributes hidden)

      + tenant_permissions {}

        # (1 unchanged block hidden)
    }

Error message:

Stack trace from the terraform-provider-elasticsearch_v2.0.7 plugin:

panic: interface conversion: interface {} is nil, not map[string]interface {}

goroutine 197 [running]:
github.com/phillbaker/terraform-provider-elasticsearch/es.tenantPermissionsHash({0x0?, 0x0?})
    github.com/phillbaker/terraform-provider-elasticsearch/es/util.go:604 +0x44a
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Set).hash(0x44ea49?, {0x0?, 0x0?})
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/set.go:218 +0x2c
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Set).add(0xc00007b860, {0x0?, 0x0}, 0x0)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/set.go:198 +0x96
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*ConfigFieldReader).readSet(0xc00057c1e0, {0xc0000ba8e0, 0x1, 0x1}, 0x0?)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/field_reader_config.go:284 +0x4b3
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*ConfigFieldReader).readField(0xc00057c1e0, {0xc0000ba8e0?, 0x1, 0x1}, 0x0)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/field_reader_config.go:107 +0x566
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*ConfigFieldReader).ReadField(0x1013860?, {0xc0000ba8e0?, 0x1180648?, 0x6?})
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/field_reader_config.go:29 +0xbc
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*MultiLevelFieldReader).ReadFieldExact(0xc0000ba8d0?, {0xc0000ba8e0, 0x1, 0x1}, {0x1180648, 0x6})
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/field_reader_multi.go:31 +0xa8
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*ResourceData).get(0xc00070bc80, {0xc0000ba8e0, 0x1, 0x1}, 0x0?)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/resource_data.go:548 +0x145
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*ResourceData).getChange(0xc0002c14a0?, {0x118ce22?, 0x12?}, 0xe0?, 0x1?)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/resource_data.go:524 +0x1b8
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*ResourceData).diffChange(0xf901e0?, {0x118ce22?, 0xf901e0?})
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/resource_data.go:501 +0x76
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.schemaMap.diffSet(0x0?, {0x118ce22, 0x12}, 0xc000899cc0, 0xc0005fd368, {0x143fbf8?, 0xc00070bc80?}, 0x0)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/schema.go:1241 +0x82
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.schemaMap.diff(0xc0005fd640?, {0x118ce22, 0x12}, 0xc000899cc0, 0xc00070bc00, {0x143fbf8?, 0xc00070bc80}, 0x0)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/schema.go:966 +0x21f
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.schemaMap.Diff(0xc0007151a0, {0x143e8c8, 0xc0000d0e00}, 0xc0001f3520, 0xc000715ce0, 0x0, {0x0, 0x0}, 0x0)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/schema.go:525 +0x325
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.diffFromValues({0x143e8c8, 0xc0000d0e00}, {{{0x143f0e0?, 0xc00074e5f8?}}, {0x1014be0?, 0xc000640de0?}}, {{{0x143f0e0, 0xc00074e638}}, {0x1014be0, 0xc000641c50}}, ...)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/shims.go:43 +0x251
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.DiffFromValues(...)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/shims.go:20
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc0002109a8, {0x143e8c8, 0xc0000d0e00}, 0xc0005d4370)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.10.0/helper/schema/grpc_provider.go:917 +0x6aa
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).ApplyResourceChange(0xc000243200, {0x143e970?, 0xc0004fd9b0?}, 0xc0000cf9d0)
    github.com/hashicorp/terraform-plugin-go@v0.5.0/tfprotov5/tf5server/server.go:603 +0x2ad
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ApplyResourceChange_Handler({0x1105000?, 0xc000243200}, {0x143e970, 0xc0004fd9b0}, 0xc0000b4840, 0x0)
    github.com/hashicorp/terraform-plugin-go@v0.5.0/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:380 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc00022e8c0, {0x1441608, 0xc0001ea000}, 0xc0001fc400, 0xc0005179b0, 0x1bbdd40, 0x0)
    google.golang.org/grpc@v1.33.2/server.go:1210 +0xc8f
google.golang.org/grpc.(*Server).handleStream(0xc00022e8c0, {0x1441608, 0xc0001ea000}, 0xc0001fc400, 0x0)
    google.golang.org/grpc@v1.33.2/server.go:1533 +0xa1b
google.golang.org/grpc.(*Server).serveStreams.func1.2()
    google.golang.org/grpc@v1.33.2/server.go:871 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
    google.golang.org/grpc@v1.33.2/server.go:869 +0x28a

Error: The terraform-provider-elasticsearch_v2.0.7 plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue.

Terraform version: v1.2.9 phillbaker/elasticsearch provider version: v2.0.7 elasticsearch_version: 8.5

I worked around this issue by using a dynamic block:

resource "elasticsearch_opensearch_role" "this" {
  for_each    = local.roles
  role_name   = each.key
  description = try(local.roles[each.key]["description"], null)

  cluster_permissions = try(local.roles[each.key]["cluster_permissions"], [])

  index_permissions {
    index_patterns  = try(local.roles[each.key]["index_permissions"]["index_patterns"], [])
    allowed_actions = try(local.roles[each.key]["index_permissions"]["allowed_actions"], [])
  }

  # workaround for provider bug
  dynamic "tenant_permissions" {
    for_each = can(local.roles[each.key]["tenant_permissions"]) ? ["1"] : []
    content {
      tenant_patterns = try(local.roles[each.key]["tenant_permissions"]["tenant_patterns"], [])
      allowed_actions = try(local.roles[each.key]["tenant_permissions"]["allowed_actions"], [])
    }
  }

  depends_on = [aws_elasticsearch_domain.opensearch]
}