Extracting list of subnets result in error - is tuple with 1 element

Viewed 2519

I have a module that creates a VPC with public and private subnets

module "vpc" {
  count              = var.vpc_enabled ? 1 : 0
  source             = "./vpc"
}

and as an output of that module I'm extracting the private subnets

output "private_subnets" {
  value = aws_subnet.private.*.id
}

Then I want to use that subnets list as an input of another module:

module "eks" {
  source          = "./eks"
  name            = var.name
  private_subnets = var.vpc_enabled ? module.vpc.private_subnets : var.private_subnets_id
}

basically what I'm trying to achieve is that the user can choose if he want to create a new VPC or use as an input a list of subnets of their existing VPC.

The problem that I've right now is that I'm getting the following error in terraform plan:

  on main.tf line 32, in module "eks":
  32:   private_subnets = var.vpc_enabled ? module.vpc.private_subnets : var.private_subnets_id
    |----------------
    | module.vpc is tuple with 1 element

This value does not have any attributes.

Does anyone knows how to fix this?

2 Answers

You are defining your vpc module with count. Thus you need to refer to individual instances of the module, even if you have only 1.

private_subnets = var.vpc_enabled ? module.vpc[0].private_subnets : var.private_subnets_id

Just to add Marcin's answer

I had a similar issue when working with dynamic blocks and locals in Terraform.

I had a locals block like this:

locals {
  subnet_suffix = "dev-subnet"
  delegation_settings = [{
    subnet_delegation_name         = "app-service-delegation"
    subnet_service_delegation_name = "Microsoft.Web/serverFarms"
  }]
}

And I was referencing the attributes this way:

module "subnet_public_1" {
  source = "../../../modules/azure/subnet"

  subnet_name                                    = "${var.subnet_name}-public-1-${local.subnet_suffix}"
  resource_group_name                            = data.azurerm_resource_group.main.name
  virtual_network_name                           = data.azurerm_virtual_network.main.name
  subnet_address_prefixes                        = var.subnet_address_prefixes.public_1
  enforce_private_link_endpoint_network_policies = var.enforce_private_link_endpoint_network_policies.public_1
  delegation_settings = [
    {
      subnet_delegation_name         = local.delegation_settings.subnet_delegation_name
      subnet_service_delegation_name = local.delegation_settings.subnet_service_delegation_name
    }
  ]
  tag_environment = var.tag_environment
}

And when I run terraform plan I get the error below:

│ Error: Unsupported attribute
│ 
│   on main.tf line 68, in module "subnet_public_1":
│   68:       subnet_delegation_name                      = local.delegation_settings.subnet_delegation_name
│     ├────────────────
│     │ local.delegation_settings is tuple with 1 element
│ 
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│ 
│   on main.tf line 69, in module "subnet_public_1":
│   69:       subnet_service_delegation_name              = local.delegation_settings.subnet_service_delegation_name
│     ├────────────────
│     │ local.delegation_settings is tuple with 1 element
│ 
│ This value does not have any attributes.

Here's how I solved it:

All I had to do was to add the index to the attributes, in this case it was 0:

module "subnet_public_1" {
  source = "../../../modules/azure/subnet"

  subnet_name                                    = "${var.subnet_name}-public-1-${local.subnet_suffix}"
  resource_group_name                            = data.azurerm_resource_group.main.name
  virtual_network_name                           = data.azurerm_virtual_network.main.name
  subnet_address_prefixes                        = var.subnet_address_prefixes.public_1
  enforce_private_link_endpoint_network_policies = var.enforce_private_link_endpoint_network_policies.public_1
  delegation_settings = [
    {
      subnet_delegation_name         = local.delegation_settings[0].subnet_delegation_name
      subnet_service_delegation_name = local.delegation_settings[0].subnet_service_delegation_name
    }
  ]
  tag_environment = var.tag_environment
}

That's all

Related