Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Value Conversion Error with dynamic location blocks #152

Open
praveenprem opened this issue Dec 23, 2024 · 0 comments
Open

Value Conversion Error with dynamic location blocks #152

praveenprem opened this issue Dec 23, 2024 · 0 comments

Comments

@praveenprem
Copy link

First of all, thank you for creating this fantastic provider. It has come in handy for managing proxy configurations for my homelab.

However, I've recently ran into an issue with location object when using dynamic blocks

╷
│ Error: Value Conversion Error
│
│   with nginxproxymanager_proxy_host.record,
│   on main.tf line 30, in resource "nginxproxymanager_proxy_host" "record":
│   30: resource "nginxproxymanager_proxy_host" "record" {
│
│ An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:
│
│ Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.
│
│ Path: location
│ Target Type: []*models.ProxyHostLocation
│ Suggested Type: basetypes.ListValue
╵

main.tf

variable "records" {
  type = list(object({
    names       = list(string)
    host        = string
    scheme      = string
    port        = number
    ssl_cert_id = number
    config      = optional(string)

    enable = object({
      caching        = bool
      websocket      = bool
      block_exploits = bool
    })

    locations = map(object({
      path   = string
      scheme = string
      port   = number
      config = string
    }))
  }))
}

terraform {
  required_providers {
    nginxproxymanager = {
      source = "Sander0542/nginxproxymanager"
      version = "0.0.36"
    }
  }
}

provider "nginxproxymanager" {
  # Configuration options
  host = ""
}

# Manage a proxy host
resource "nginxproxymanager_proxy_host" "record" {
  for_each     = {for record in var.records : record.host => record}
  domain_names = each.value.names

  forward_scheme = each.value.scheme
  forward_host   = each.value.host
  forward_port   = each.value.port

  caching_enabled         = each.value.enable.caching
  allow_websocket_upgrade = each.value.enable.websocket
  block_exploits          = each.value.enable.block_exploits

  access_list_id = 0 # Publicly Accessible

  dynamic "location" {
    for_each = each.value.locations
    content {
      path           = location.value.path
      forward_scheme = location.value.scheme
      forward_host   = location.key
      forward_port   = location.value.port

      advanced_config = location.value.config
    }
  }

  certificate_id  = each.value.ssl_cert_id
  ssl_forced      = false
  hsts_enabled    = false
  hsts_subdomains = false
  http2_support   = false

  advanced_config = each.value.config
}

terraform.tfvars

records = [
  {
    names       = ["unifi.example.com"]
    host        = "ui-controller.example.com"
    scheme      = "https"
    port        = 8443
    ssl_cert_id = 3

    enable = {
      websocket      = true
      caching        = false
      block_exploits = false
    }

    locations = {
      "test.local" : {
        path   = "/"
        scheme = "https"
        port   = 8443
        config = ""
      }
    }
  }
]

Oddly, this seems to be only an issue if I use the reference from the resources for_each loop. If I were to hardcode the map directly at the for_each within the dynamic block; it works as expected.

  dynamic "location" {
    for_each = {
      "test.local" : {
        path   = "/"
        scheme = "https"
        port   = 8443
        config = ""
      }
    }
    content {
      path           = location.value.path
      forward_scheme = location.value.scheme
      forward_host   = location.key
      forward_port   = location.value.port

      advanced_config = location.value.config
    }
  }

Output

Terraform will perform the following actions:

  # nginxproxymanager_proxy_host.record["ui-controller.example.com"] will be created
  + resource "nginxproxymanager_proxy_host" "record" {
      + access_list_id          = 0
      + allow_websocket_upgrade = true
      + block_exploits          = false
      + caching_enabled         = false
      + certificate_id          = "3"
      + created_on              = (known after apply)
      + domain_names            = [
          + "unifi.example.com",
        ]
      + enabled                 = (known after apply)
      + forward_host            = "ui-controller.example.com"
      + forward_port            = 8443
      + forward_scheme          = "https"
      + hsts_enabled            = false
      + hsts_subdomains         = false
      + http2_support           = false
      + id                      = (known after apply)
      + meta                    = (known after apply)
      + modified_on             = (known after apply)
      + owner_user_id           = (known after apply)
      + ssl_forced              = false
        # (1 unchanged attribute hidden)

      + location {
          + forward_host    = "test.local"
          + forward_port    = 8443
          + forward_scheme  = "https"
          + path            = "/"
            # (1 unchanged attribute hidden)
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant