Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Value of count cannot be computed when using a map containing a reference to a resource #15471

Closed
betabandido opened this issue Jul 4, 2017 · 8 comments

Comments

@betabandido
Copy link

Terraform Version

Terraform v0.9.11

Problem description

We are creating a module to set up AWS cloudwatch alarms. The module accepts a map containing the configuration for each of the alarms that users want to configure (var.alarms). Then we instantiate multiple aws_cloudwatch_metric_alarm resources using count.

Everything works fine until var.alarms contains a reference to another resource. In the example, we use the ARN for an SNS topic, but we have tried other resources such as the deployment ARN and it fails as well.

The error message is:

module.api_cloudwatch_alarms.aws_cloudwatch_metric_alarm.alarm: aws_cloudwatch_metric_alarm.alarm: value of 'count' cannot be computed

Terraform Configuration Files

main.tf

variable "profile" {
  default = ""
}

variable "region" {
  default = ""
}

provider "aws" {
  profile    = "${var.profile}"
  region     = "${var.region}"
}

resource "aws_api_gateway_rest_api" "api" {
  name = "api"
}

resource "aws_api_gateway_deployment" "deployment" {
  rest_api_id = "${aws_api_gateway_rest_api.api.id}"
  stage_name  = "test"
}

module "api_cloudwatch_alarms" {
  source = "./api_cloudwatch_monitors"

  api_name   = "${aws_api_gateway_rest_api.api.name}"
  stage_name = "test"
  alarms = {
    "4XXError" = {
      actions = "${aws_sns_topic.topic.arn}"
      threshold = 10
    }
  }
}

resource "aws_sns_topic" "topic" {
  name = "topic"
}

api_cloudwatch_monitors/main.tf

variable "api_name" {}

variable "stage_name" {}

variable "alarms" {
  type = "map"
  default = {}
}

resource "aws_cloudwatch_metric_alarm" "alarm" {
  count = "${length(var.alarms)}"
  alarm_name = "${format("%s-%s-%s",
                  var.api_name,
                  var.stage_name,
                  element(keys(var.alarms), count.index))}"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods = 2
  metric_name = "${element(keys(var.alarms), count.index)}"
  namespace = "AWS/ApiGateway"
  period = 100
  threshold = 100

  alarm_actions = ["${split(",", lookup(
                    var.alarms[element(keys(var.alarms), count.index)],
                    "actions",
                    ""
                  ))}"]
}

Debug Output

https://gist.github.com/betabandido/e4fe821a5d08b1a291e508c7a163c4eb

betabandido added a commit to vistaprint/TerraformModules that referenced this issue Jul 4, 2017
@Puneeth-n
Copy link
Contributor

Puneeth-n commented Jul 4, 2017

@betabandido this is expected because since the value of "${aws_sns_topic.topic.arn}" is not know during the plan/apply phase, terraform assumes the whole map as an un-computed resource.

main.tf

variable "region" {
    default = "us-east-1"
}

provider "aws" {
    region = "${var.region}"
}

resource "aws_sns_topic" "topic" {
  name = "topic"
}

module "foo" {
    source = "./module/"

    alarms = {
        "4XXError" = {
            actions = "${aws_sns_topic.topic.arn}" does not work
            # actions = "foo" works
            # actions = "arn:aws:sns:<region>:<account>:<topic_name>" works!
            threshold = 10
        }
    }
}

module/main.tf

variable "alarms" {
  type = "map"
  default = {}
}

resource null_resource "foo" {
    count = "${length(keys(var.alarms))}"
    provisioner "local-exec" {
        command = "echo ${count.index}"
    }
}

@apparentlymart gave me a good explanation a while ago. Here you go!

@betabandido by building the sns topic you don't need to use the extra variable you used here

@betabandido
Copy link
Author

Isn't it possible to use some sort of lazy evaluation? As the keys in the map are plain strings, their number does not depend on the potential contents of the map values. Therefore, length(keys(var.alarms)) could easily work.

If this is just impossible, I suppose an alternative is to first create the SNS topic using -target. Is that correct?

@Puneeth-n
Copy link
Contributor

@betabandido yep using -target to create the SNS first and then the alarms should work. Since our CI server performs the terraforming, it is inconvenient for us to add -target everywhere and so I build the arn wherever possible.

@catsby catsby added the core label Jul 7, 2017
@aegixx
Copy link

aegixx commented Jul 28, 2017

I'm hitting the same error following the sample in the documentation - is this not valid? https://www.terraform.io/docs/configuration/interpolation.html#using-templates-with-count

@ChineduUzoka
Copy link

ChineduUzoka commented Sep 1, 2017

This appears to be a massive limitation - "count" appears to be a necessity in reducing the amount of code/text written which helps to keep the code maintainable as it reduces having to duplicate code unnecessarily. I have use of count only to prevent resources in modules from being "run" but "count cannot compute" comes up and scuppers what i wrote.

Using target in a wrapper script once is fine but more than once is often a headache and error prone especially when trying to write "sane" non-complex DRY terraform

This is a Big limitiation

@DmitryLobanov
Copy link

Hitting the same issue. Would be glad to see it fixed.

@jbardin
Copy link
Member

jbardin commented Mar 31, 2021

Hello All,

The behavior here is specific to a very old version of terraform, so I'm going to close this out. The arguments to count must be known during planning, but we now have for_each which can utilize maps with unknown values for similar use cases.

We use GitHub issues for tracking bugs and enhancements, rather than for questions. While we can sometimes help with certain simple problems here, it's better to use the community forum where there are more people ready to help.

@jbardin jbardin closed this as completed Mar 31, 2021
@ghost
Copy link

ghost commented May 1, 2021

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked as resolved and limited conversation to collaborators May 1, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants