Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

terraform conditional resource

Tags:

terraform

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}"]
   .....
  }
like image 403
Phil Avatar asked Aug 12 '17 20:08

Phil


People also ask

How do I conditionally Terraform a resource?

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."

How do you write if condition in Terraform?

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.

Can we use if else in Terraform?

As you (probably) know, Terraform doesn't support if statements.

How do you write a loop in Terraform?

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.


1 Answers

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}"
}
like image 62
Stephen Avatar answered Sep 23 '22 01:09

Stephen