Reputation: 2062
I am running into an issue while trying to upgrade from terraform 11 to terraform 12. I was previously using the following syntax to retrieve the 3rd element from a list of ids from a module. The module output is like so:
# Subnets
output "private_subnets" {
description = "List of IDs of private subnets"
value = ["${aws_subnet.private.*.id}"]
}
Previously, this worked with terraform 11
subnet_id = "${element(module.network.private_subnets,3)}"
I thought that I could use the index of 2 to get the same results, but I get the following error:
Error: Incorrect attribute value type
on terraformfile.tf line 65, in resource "aws_instance" "myinstance":
65: subnet_id = module.network.private_subnets[2]
|----------------
| module.network.private_subnets[2] is tuple with 3 elements
Any help with this would be greatly appreciated.
Upvotes: 3
Views: 7115
Reputation: 11
I had same issue , flatten HELPED !! .
the configuration file looked like this :
resource "aws_db_subnet_group" "for-database" {
name = "for-database"
description = "private subnets in different AZs"
subnet_ids = module.vpc.private_subnets
}
got this error :
│ Error: Unsupported attribute │ │ 39: value = module.vpc.private_subnets.subnet_count │ ├──────────────── │ │ module.vpc.private_subnets is tuple with 2 elements │ │ This value does not have any attributes.
solution:
resource "aws_db_subnet_group" "for-database" {
name = "for-database"
description = "private subnets in different AZs"
subnet_ids = flatten([module.vpc.private_subnets])
}
Upvotes: 1
Reputation: 3606
it was quite difficult for me but i handled it via flatten
function i took tuple and pass it to flatten function
/* Subnets group for DBs */
resource "aws_db_subnet_group" "default" {
name = "main"
subnet_ids = flatten([aws_subnet.PrivateSubnets.*.id])
tags = {
Name = "Private Subnet group"
}
}
Upvotes: -1
Reputation: 732
The answer from @Marcin holds good but I hit a very similar error in a slightly different situation and I took a different approach to resolve it.
Lets say you have a aws_security_group_rule
rule and each of the data -sourced item in the list below i.e data.aws_subnet.app1_subnets.*.cidr_block
and data.aws_subnet.app2_subnets.*.cidr_block
are a tuple with lets say X elements - You might hit an error -
Error: Incorrect attribute value type
on stack.tf line 44, in resource "aws_security_group_rule" "ds_security_group_ingress_rule":
44: cidr_blocks = [
45: data.aws_subnet.app1_subnets.*.cidr_block,
46: data.aws_subnet.app2_subnets.*.cidr_block
47: ]
|----------------
| data.aws_subnet.app1_subnets.*.cidr_block is tuple with 3 elements
| data.aws_subnet.app2_subnets.*.cidr_block is tuple with 3 elements
Inappropriate value for attribute "cidr_blocks": element 0: string required.
I had to use the flatten
function to resolve the issue which quite literally flattens the content..
Change the below:
cidr_blocks = [
data.aws_subnet.app1_subnets.*.cidr_block,
data.aws_subnet.app2_subnets.*.cidr_block
]
as
cidr_blocks = flatten([
data.aws_subnet.app1_subnets.*.cidr_block,
data.aws_subnet.app2_subnets.*.cidr_block
])
Upvotes: 3
Reputation: 238957
The currently used value:
value = ["${aws_subnet.private.*.id}"]
produces a list of lists. For example,
[
[
"subnet-0f5b759e80ffcf305",
"subnet-0500c8c2a40e5b381",
],
]
If you want to keep using this in that form, later, when you use element
you have to do following:
subnet_id = element(module.network.private_subnets[0], 3)
Alternatively, redefine private_subnets
to be:
value = aws_subnet.private.*.id
Upvotes: 2