Terraform 13: `unsupported attribute` on output from modules whose `count` is set to possibly 0

Our terraform provisioning pipeline is multi-stage. For example, we provision our foundational infra services (like vault) first, then our control plane services like nomad and consul, followed by data infra services (kafka, zookeeper, cassandra, storm, databricks, etc), and eventually application iam roles whose access permissions are scoped to specific subset of infra services. We have a sandbox account where each SRE can deploy their own replica of the whole infra services and develop on it. This guarantees that SRE’s won’t step on each other’s toes. Then once the features are tested in sandbox, we do integration testing of all features in one release in our test account. As you can see, with a team of 8 SRE’s, we’ll have at most 8 complete replicas deployed in our sandbox account, which can be very wasteful since normally each SRE is really only touching a few services for their feature (for example, a feature in kafka will have nothing to do with databricks or cassandra).

In the past, we try to set the instance count of unused services to 0, which will not provision any EC2 instances for our databricks/cassandra clusters in the above example. This is not perfect but works fine. With terraform 13’s module count feature, I tried to set the count of the databricks module to 0 via a control flag in the calling module, which has all the application infra services (kafka, zookeeper, cassandra, storm, databricks), each as an individual module:

module "databricks" {
  source = "git@github.com:myorg/terraform-aws-databricks-pvc.git?ref=tf13"
  count = var.disable_databricks ? 0 : 1
  ...
}

The databricks module has an output parameter (as you can see, I try to include the disable_databricks flag for this output in case it is disabled):

output "databricks_core_iam_role_name" {
  value = var.disable_databricks ? "" : module.databricks.core_iam_role_name
}

However, I get the following error with terraform plan:

Error: Unsupported attribute

on .terraform/modules/cell_shared/output.tf line 62, in output "databricks_core_iam_role_name":
62:   value = var.disable_databricks_pvc ? "" : module.databrickspvc.core_iam_role_name
|----------------
| module.databrickspvc is tuple with 1 element

This value does not have any attributes.

Is there a way to resolve this error given our setup?

It looks like you have a syntax error.
The error message states that module.databrickspvc is a tuple (since you created it with count meta-argument, right?) but you refer to its output this way: module.databrickspvc.core_iam_role_name
However it should be
module.databrickspvc[*].core_iam_role_name

2 Likes

This does seem like the likely cause, though in this situation (where the module is conditionally enabled and thus has either zero or one items) it might be preferable to use [0] to select the first (and only) item, rather than returning a single-element list:

output "databricks_core_iam_role_name" {
  value = var.disable_databricks ? null : module.databricks[0].core_iam_role_name
}

In the above I also made it return null when the module is disabled, rather than "", because that will tend to produce better error messages downstream if a caller accidentally uses this output value when it’s disabled: many operations on a null will return an error, whereas some operations on an empty string will succeed but do something unexpected, causing a resulting error to be returned downstream somewhere that can be hard to connect back to the original problem. With that said, returning "" in that case will also work fine: the [0] index is the part that is important to fix the error we’re discussing here.