Hi there,
I'm trying to use coalesce as a mean to provide a "default" value if _something_ doesn't exist. See the following code:
variable "dummy" { default = "asdf" }
resource "aws_alb_target_group" "target_group" {
name = "${var.alb_target_group_name}"
port = "${var.container_port}"
protocol = "${var.container_protocol}"
vpc_id = "${var.vpc}"
count = "0"
}
resource "aws_alb_listener_rule" "rule" {
listener_arn = "${var.alb_listener_arn}"
priority = "${var.alb_listener_priority + count.index}"
action {
type = "forward"
target_group_arn = "${coalesce(aws_alb_target_group.target_group.arn, var.dummy)}"
}
condition {
field = "path-pattern"
values = [ "${element(split(",", var.alb_listener_paths), count.index)}" ]
}
count = "${coalesce(length(split(",", var.alb_listener_paths)), var.zero)}"
}
In this case, if the count in the aws_alb_target_group.target_group resource is 0, the aws_alb_listener_rule.rule fails saying aws_alb_target_group.target_group group doesn't have attribute arn, which is true - as it doesn't exist.
My hope was for the coalesce function, to return first non-empty value and if it hits non-existing resource, it'd simply skip over it.
Having coalesce skipping non-existing resources would make creating some conditions much easier / possible with terraform.
Sorry - being silly about the use of count here...
I actually have a case for this, I’m trying to write a module to deploy Sensu on AWS, the plan was to use elasticache for Redis but now I’m facing an edge case. Some of our VPCs have tenancy set to dedicated and we can’t use elasticache there(http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/AmazonVPC.EC.html), I thought I could work around this by conditionally using elasticache or deploying a redis cluster in a ASG. I’ve written the code and used:
count = "${replace(replace(var.vpc_instance_tenancy,"/.*dedicated.*/","0"),"/(.*default.*|^$)/","1")}"
to decide if I should create the elasticahe cluster or the ASG, the problem is that I need to pass a hostname or IP address to the Sensu servers and api nodes so that they can connect to Redis, was planning to use:
redis_host = "${coalesce(aws_elasticache_cluster.redis_cluster.cache_nodes.0.address,aws_elb.redis_lb.dns_name)}"
but this always fails because one of the resources never gets created and I can’t reference it in the coalesce function.
@bart613 can you reopen this issue?
@luisdavim if you have a resource that sometimes has count = 0 then you must reference it using the "splat variable" syntax: aws_elasticache_cluster.redis_cluster.*.cache_nodes.0.address. This will produce an empty list if count = 0 and a one-element list if count = 1.
Here's one way to write your redis_host expression to exploit that behavior for conditional operation:
redis_host = "${element(concat(aws_elasticache_cluster.redis_cluster.*.cache_nodes.0.address, list(aws_elb.redis_lb.dns_name)), 0)}"
This produces a list with the zero-or-one redis cluster addresses followed by the one ELB dns name, and then takes the first element of that list.
Thanks. But what about the elb resource? I'm creating one or the other.
The same trick can be done for both of them:
redis_host = "${element(concat(aws_elasticache_cluster.redis_cluster.*.cache_nodes.0.address, aws_elb.redis_lb.*.dns_name), 0)}"
Interesting, I'll give it a try. Thanks
it worked, thanks a milion :)
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.
Most helpful comment
@luisdavim if you have a resource that sometimes has
count = 0then you must reference it using the "splat variable" syntax:aws_elasticache_cluster.redis_cluster.*.cache_nodes.0.address. This will produce an empty list ifcount = 0and a one-element list ifcount = 1.Here's one way to write your
redis_hostexpression to exploit that behavior for conditional operation:This produces a list with the zero-or-one redis cluster addresses followed by the one ELB dns name, and then takes the first element of that list.