How to handle this nested object which needs a value from data source?

Hello,

In my root module I call the following aks module where I have the node pools object which has many attributes. I do provide the values in tfvars, however certain attributes from that object I would like to be taken from a data source, namely subnet_id


# main.tf

module "aks" {
    name = var.name
    kubernetes_version = var.kubernetes_version
    node_pools = var.node_pools
} 

Variables would look like this:

# variables.tf 

variable "name" {
    type = string
}
variable "kubernetes_version" {
    type = string
}

variable "node_pools" {
  type = map(object({
    name                          = string
    node_count                    = optional(number)
    orchestrator_version         = optional(string)
    vnet_subnet_id               = optional(string)
  }))
  default     = {}
  description = "Additional nodepools to be created."
  nullable    = false
}

tfvars is as follows:

name = "my-cluster"
kubernetes_version = "1.25"

node_pools = {
  "worker" = {
    name                 = "worker"
    node_count      = 2
    vnet_subnet_id       = data.azurerm_subnet.aks.id # I would like to have the ID here provided from a datasource but is not possible, any workarounds?
    orchestrator_version = "1.25.5"

  }
}

Any workarounds to provide there the subnet id from a datasource?

Hi @CiucurDaniel,

If you want one of your values to be derived automatically using a data source instead of specified by the caller of your module then you would need to remove it from your input variable and then insert it using a separate expression inside your module to generate the data structure that your child module expects.

I’m not sure exactly what to suggest since I assume there is more to this requirement than just a single fixed subnet being inserted. What’s the rule for deciding which subnet each node pool should use?

1 Like

Currently any node pools we create share the same subnet. Basically for each env there is a subnet dedicated to AKS alone. Reason I would like the ID to be provided via data source is because in my case, on Azure, the ID is very long and also has some other things into it such as subscription id. And in the root module I do currently have the datasource which gets the subnet:

data "azurerm_subnet" "aks" {
  name                 = "project-aks-snet-${var.env}-gwc"
  virtual_network_name = "project-vnet-gwc"
  resource_group_name  = "project-share-gwc"
}

Or in the future if the subnet will be created in root (which might be the case) I can just take the id from the resource:

resource "azurerm_subnet" "aks {
    name = "aks-subnet"`
   address_range = ["10.0.0.0"]
}

I thought initially that maybe the merge function would help thought it might make things very weird for other people

# main.tf 

module "aks" {
    name = var.name
    kubernetes_version = var.kubernetes_version
    node_pools = merge(var.node_pools, {vnet_subnet_id = azurerm_subnet.aks.id}) # something similar
} 

Do you think this makes sense or I should look for other option?

@apparentlymart I solved the issue with this approach. I will see in the future if I will need another solution, but for the moment it does the job and I’m also out of ideas :slight_smile: .