How to fix the "count" object can only be used in "module", "resource", and "data" blocks, and only when the "count" argument

Viewed 852

Objective: I am trying to create azure resources with Terraform

Code I used in main.tf:

resource "azurerm_subnet" "clientdata_snet" {
  count                = var.clientdata_subnet_address_space != null ? 1 : 0
  name                 = "ClientDataSubnet"
  resource_group_name  = var.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["${var.clientdata_subnet_address_space}"]
  service_endpoints    = var.service_endpoints
}

and now subsequently want to use client_snet.id for creating storage endpoint

resource "azurerm_private_endpoint" "sa_pe_blob" {
  name                = "pe-stdlorpcbcntldevwe-blob-${random_string.postfix.result}"
  location            = var.location
  resource_group_name = var.resource_group_name
  subnet_id           = azurerm_subnet.clientdata_snet.id

Error I get is:

 Error: Missing resource instance key
    │ 
    │   on main.tf line 470, in resource "azurerm_private_endpoint" "sa_pe_blob":
    │  470:   subnet_id           = azurerm_subnet.clientdata_snet.id
    │ 
    │ Because azurerm_subnet.clientdata_snet has "count" set, its attributes must be accessed on specific instances.
    │ 
    │ For example, to correlate with indices of a referring resource, use:
    │     azurerm_subnet.clientdata_snet[count.index]

Then I referred to some posts here.. where I need to use like below:

  subnet_id           = azurerm_subnet.clientdata_snet[count.index].id

then its giving me this error:

Error: Reference to "count" in non-counted context
    │ 
    │   on main.tf line 470, in resource "azurerm_private_endpoint" "sa_pe_blob":
    │  470:   subnet_id           = azurerm_subnet.clientdata_snet[count.index].id
│ 
│ The "count" object can only be used in "module", "resource", and "data" blocks, and only when the "count" argument is set.

Really confused, both ways its giving me error. I have only root module, I dont have any other modules.Can someone suggest what is correct way to do it ?

1 Answers

If you are using count meta-argument, you have to use either the right index or use the same way of creating the second resource, by referencing the same variable to decide what the count will be. So the options are:

resource "azurerm_private_endpoint" "sa_pe_blob" {
  name                = "pe-stdlorpcbcntldevwe-blob-${random_string.postfix.result}"
  location            = var.location
  resource_group_name = var.resource_group_name
  subnet_id           = azurerm_subnet.clientdata_snet[0].id # exact index
}

As you can see, the subnet_id is now referencing a previously created resource with index of 0. To understand how references to instances work when count is used, look in [1].

The second way you could do it is like this:

resource "azurerm_private_endpoint" "sa_pe_blob" {
  count               = var.clientdata_subnet_address_space != null ? 1 : 0
  name                = "pe-stdlorpcbcntldevwe-blob-${random_string.postfix.result}"
  location            = var.location
  resource_group_name = var.resource_group_name
  subnet_id           = azurerm_subnet.clientdata_snet[count.index].id # using count.index
}

This way you will create a dependency between the subnet and the endpoint resources.

As you can see here, the resources created with count can be referenced either by specifying the exact index which is fine when there is only one resource, but much harder when there are more and the code would have to be repeated. The other way is to use the same variable with the count meta-argument.

I strongly suggest going through the documentation to understand the count meta-argument better.


[1] https://www.terraform.io/language/meta-arguments/count#referring-to-instances

Related