Terraform `class resource` implementation

Hi team,

Considering following use case. Enabling bedrock logging with tf module. It is regional resource and I’m looking a way to implement some shared state across all instances of the same module. Basically I want the first module deployment to create a bucket and iam role and all other deployments would lookup for that.

I guess explicit var like seed_module = true would work but I’m just thinking if that can be further reduced.

Currently I’ve stuck that init deployment works but next doesn’t cause relying on the data resource and there again the chicken and and an egg question.

Code and error

data "aws_iam_role" "external_role" {
  count = var.cw_logging_enabled && var.logging_role_name != null ? 1 : 0
  name  = var.logging_role_name
}

data "aws_iam_roles" "this_module_roles" {
  count       = var.cw_logging_enabled && var.logging_role_name == null ? 1 : 0
  name_regex  = "${local.tf_module}.*"
  path_prefix = "/${var.namespace}/"
}

locals {
  ext_role_arn  = var.cw_logging_enabled && var.logging_role_name != null ? data.aws_iam_role.external_role[0].arn : null
  int_role_name = var.cw_logging_enabled && var.logging_role_name == null && length(data.aws_iam_roles.this_module_roles[0].names) == 1 ? tolist(data.aws_iam_roles.this_module_roles[0].names)[0] : null
  create_role = alltrue([var.cw_logging_enabled, local.ext_role_arn == null, local.int_role_name == local.name])
  effective_role_arn = coalesce(local.ext_role_arn, tolist(data.aws_iam_roles.this_module_roles[0].arns)[0])

}

resource "aws_iam_role" "log_cw_role" {
  count              = local.create_role ? 1 : 0
  name               = local.name
  assume_role_policy = data.aws_iam_policy_document.log_cw_role_trusted_entity.json
  path               = "/${var.namespace}/"
  tags               = local.effective_tags
}

Error:


╷
│ Error: Invalid count argument
│ 
│   on logging-cw.tf line 62, in resource "aws_iam_role" "log_cw_role":
│   62:   count              = local.create_role ? 1 : 0
│ 
│ The "count" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be
│ created. To work around this, use the -target argument to first apply only the resources that the count depends on.

Appreciate any feedback

This error message suggests that local.create_role’s value is derived from something Terraform can’t predict during the planning phase.

local.create_role is derived from all of the following (directly or indirectly):

  • var.cw_logging_enabled
  • local.name
  • var.logging_role_name
  • data.aws_iam_role.external_role[0].arn
  • The length of data.aws_iam_roles.this_module_roles[0].names
  • The first and only element of data.aws_iam_roles.this_module_roles[0].names, when present.

At least one of these values is unknown during the planning phase. To address this will require figuring out which of these is unknown and why it is unknown, and then you can try to think of a way to give Terraform more information during planning so that the decision does not depend on any unknown values.

With the information given I can’t predict which of these values might be unknown. You could potentially debug that by running terraform console -plan to let you evaluate arbitrary expressions against the plan. terraform console creating the plan will fail with the same error message as you already reported, but it should still let you type expressions at the prompt so you can inspect the values of symbols that were already visited before the error occurred, which should include all of the symbols I listed above.

Concretely, what I would suggest is to evaluate each of the items I listed above in the console to learn which of them have unknown values during the planning phase. That will hopefully produce a shorter list of problematic symbols and then you can use that to think about different ways to write the configuration so that either those values will be known during planning or you’d use a different set of rules to make the decision about whether to create the role.