Using variables calling arn to amazon inside a list

I would like to use a variable to create a code that i can reuse by changing some of the values. I found a problem when I try to create my alarms in cloudwatch. When i specify the dimensions of the instance i would like to do something like this:

dimensions = {
InstanceId = "aws_instance.${var.ec2_name}.id"
}

And when I try to specify the actions of the alarm I find myself lost because I can’t use that method either. Here is my example:

variable "sns" {
default = "test"
}
resource "aws_cloudwatch_metric_alarm" "this" {
.
.
.
alarm_actions = ["aws_sns_topic.${var.sns}.arn"] ------> I can't do that

dimensions = {
InstanceId = "aws_instance.${var.ec2_name}.id" ------> I can't do that
}
}

The result of using this is that in alarm_actions i get the string “aws_sns_topic.test.arn” instead of the arn itself.

If it is any workoround that please let me know.

Hi @sgonzalez-at-wiris,

Indeed, this isn’t possible because references between resources in Terraform are static.

However, you can get a similar effect by creating a map value which includes all of the instances relevant to whatever you’re trying to achieve:

locals {
  interesting_instances = {
    a = aws_instance.a
    b = aws_instance.b
  }
}

You can then write an expression like local.interesting_instances[var.ec2_name] to dynamically look up the appropriate single instance.

Notice that this local value depends on both instances, so any reference to local.interesting_instances also depends on both instances, transitively. This is why what you tried originally can’t work: Terraform needs to be able to understand which objects depend on which other objects in order to correctly calculate the appropriate order to evaluate each object.

I don’t understand how I could implement this in my code. I would like to use the same code to create a template for standard alarms, the problem is that I need the instance id and the sns arn to be changing every time I execute my code with a different .tfvars file. Something like:

InstanceId = "aws_instance.${var.ec2_name}.id"

And then every time I do an execution using different variables my template creates alarms of a machine that I specify in the .tfvars file.

I could give the id and arn directly but i would like to make the call to amazon using attributes.