What is the difference between a set and a list in terraform (if any)?
Also, I was looking to create and AWS security group where it has common ingress { }
rules for all lower and higher environments (my main.tf
is used to create our resources for all our nonprod/lower and prod/higher environments), and also a specific ingress rule created for only certain higher environments/ Terraform workspaces (specifically, preview
and prod
) using the AWS provider data "aws_security_group"
data source and also the resource "aws_security_group"
resource like so:
# data source SG, for *only* `prod` and `preview` environments
data "aws_security_group" "security_group_x" {
count = contains(["preview", "prod"], terraform.workspace) ? 1 : 0
name = "sg-x"
}
resource "aws_security_group" "allow_tls" {
name = "allow_tls"
description = "Allow TLS inbound traffic"
vpc_id = aws_vpc.main.id
# common ingress rule for all environments, like devtest, externaltest, etc, and preview and prod
ingress {
description = "TLS from VPC"
from_port = 443
to_port = 443
protocol = "tcp"
security_groups = [data.aws_security_group.sg_a.id]
}
dynamic "ingress" {
for_each = contains(["preview", "prod"], terraform.workspace) ? [terraform.workspace] : []
content {
description = "security group x"
from_port = 1234
to_port = 1234
protocol = "TCP"
security_groups = [data.aws_security_group.security_group_x.id]
}
}
...
It’s a bit confusing so far, since if I do the above as is, I get this error:
Error: Missing resource instance key
Because data.aws_security_group.default_sg has "count" set, its attributes must be accessed on specific instance.
For example, to correlate with indices of a referring resource, use:
data.aws_security_group.default_sg[count.index]
Then I try to add that [count.index]
to my code in the dynamic
block further above with this line:
security_groups = [data.aws_security_group.security_group_x[count.index].id]
and then I get this error:
Error: Reference to "count" in a non-counted context
The "count" object can only be used in "module", "resource", and "data" blocks, and only when the "count" argument is set.
But wasn’t my "count"
argument set to 1
by my expression in this part of my code mentioned at the top above?:
# data source SG, for *only* `prod` and `preview` environments
data "aws_security_group" "security_group_x" {
count = contains(["preview", "prod"], terraform.workspace) ? 1 : 0
name = "sg-x"
}
Seems I just need a small tweak and can be on the way, creating this single ingress rule just for prod
and preview
environments.