I have the following and I want to know what I am doing wrong, as I am sure I shouldn't have to double my code just because of a condition.
So I want to do:
variable "https" { value = true }
resource "aws_security_group" "http_instance_sg" {
count = "${var.https ? 0 : 1}"
......
}
resource "aws_security_group" "https_instance_sg" {
count = "${var.https ? 1 : 0}"
......
}
resource "aws_elb" "fe_elb" {
security_groups = ["${var.https ? aws_aws_security_group.https_instance_sg.id : aws_aws_security_group.http_instance_sg.id}"]
.....
}
But when I do this terraform complains that http_instance_sg
cant be found, which I get it hasn't be built, but surely I dont have to double up on all the code and have:
resource "aws_elb" "http_fe_elb" {
count = "${var.https ? 0 : 1}"
security_groups = ["${aws_aws_security_group.http_instance_sg.id}"]
.....
}
resource "aws_elb" "https_fe_elb" {
count = "${var.https ? 1 : 0}"
security_groups = ["${aws_aws_security_group.https_instance_sg.id}"]
.....
}
You can use count block with Conditional Expressions (condition ? true_val : false_val) to create a resource based on variable value. description = "default condition value is true."
Terraform doesn't support if-statements, so this code won't work. However, you can accomplish the same thing by using the count parameter and taking advantage of two properties: If you set count to 1 on a resource, you get one copy of that resource; if you set count to 0, that resource is not created at all.
As you (probably) know, Terraform doesn't support if statements.
Using the count meta-argument The count meta-argument is the simplest of the looping constructs within Terraform. By either directly assigning a whole number or using the length function on a list or map variable, Terraform creates this number of resources based on the resource block it is assigned to.
The way you are currently defining the code with a count means that the response of the resource is a list. This means you will need to access the values differently
resource "aws_elb" "fe_elb" {
security_groups = ["${var.https ? element(aws_security_group.https_instance_sg.*.id,0) : element(aws_security_group.http_instance_sg.*.id,0)}"]
.....
}
It's worth noting that you will get an error if you try to access a list that is empty using this method.
This means you will need to concat an empty value to each to ensure the response of element doesn't throw.
Example using concat
"${var.https ? element(concat(aws_security_group.https_instance_sg.*.id, list("")), 0) : element(concat(aws_security_group.http_instance_sg.*.id, list("")), 0)
Different approach
Without seeing the code I might ask here if there is an easier way to achieve what you are trying to do using a security_group_rule
variable "https" { value = true }
resource "aws_security_group" "instance_sg" {
# notice we no longer have a count here
}
resource "aws_elb" "fe_elb" {
security_groups = ["${aws_security_group.instance_sg.id}"]
.....
}
resource "aws_security_group_rule" "http" {
count = "${var.https ? 0 : 1}"
.... http definitions
security_group_id = "${aws_security_group.instance_sg.id}"
}
resource "aws_security_group_rule" "https" {
count = "${var.https ? 0 : 1}"
.... https definitions
security_group_id = "${aws_security_group.instance_sg.id}"
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With