Can't Access nested property

Good Morning,
I have been trying to access an attribute but it is nested deep within the resource.
The TF documentation is here

firewall resource:

resource "aws_networkfirewall_firewall" "inspection_networkfirewall" {
  for_each            = toset(var.vpc_availability_zone_names)
  name                = "${var.additional_tags.environment}-${each.key}-network-firewall"
  firewall_policy_arn = aws_networkfirewall_firewall_policy.inspection_firewall_policy.arn
  vpc_id              = aws_vpc.inspection_vpc.id
  subnet_mapping {
    subnet_id = aws_subnet.inspection_firewall_subnet[each.key].id
  }

  tags = var.additional_tags
}

The vpc_endpoint_id is what I need to get access to.

 resource "aws_route" "tgw_to_firewall_endpoint_route" {
   for_each               = toset(var.vpc_availability_zone_names)
   route_table_id         = aws_route_table.inspection_tgw_subnet_rtb[each.key].id
   destination_cidr_block = "0.0.0.0/0"
   vpc_endpoint_id        = aws_networkfirewall_firewall.inspection_networkfirewall[each.key].firewall_status[0].sync_states.attachment[0].endpoint_id
 }

to troubleshoot I have put it to an output and I get the following

output "endpoint_id" {
  value = aws_networkfirewall_firewall.inspection_networkfirewall["us-west-2a"].firewall_status[0].sync_status.attachment[0].endpoint_id
}

I get the following error:

│ Error: Unsupported attribute
│ 
│   on ../../modules/new-tgw/inspection-vpc/inspection-vpc.tf line 164, in output "endpoint_id":
│  164:   value = aws_networkfirewall_firewall.inspection_networkfirewall["us-west-2a"].firewall_status[0].sync_states.attachment[0].endpoint_id
│ 
│ Can't access attributes on a set of objects. Did you mean to access an
│ attribute across all elements of the set?

I have been trying to understand the splat method and have tried a number of iterations with the * but not sure I understand it enough to know if I am putting in the right location.

Any help and direction as to how to properly access these nested attributes would be really helpful. Thanks

I have absolutely no knowledge of this part of AWS, but in the documentation you linked to, sync_states is described as a set - that would mean sync_states.attachment can’t possibly work, since what would accessing .attachment on a set mean?

If you’re adequately convinced that sync_states only ever contains one item, you might write sync_states[*].attachment which means "explore every item in sync_states and get the .attachment of each.

You might also consider changing some of your existing [0] parts to [*] to ensure you don’t accidentally throw away information if some of the other data structures that are lists, happen to contain multiple items.

If you get all this working, and there is just one value, wrapped in a list, you might be interested in the Terraform one function one - Functions - Configuration Language | Terraform | HashiCorp Developer - which exists to make it easy to get the single item from a list which should always have one item, and error if it ever has more.

Thanks maxb. I have tried using [*] to replace [0] but I get exactly the same message.
However if I try what you mentioned sync_states[*] I am able to get a little further.

If i set my output to the following:

output "endpoint_id" {
  value = aws_networkfirewall_firewall.inspection_networkfirewall["us-west-2a"].firewall_status[0].sync_states[*].attachment[0].endpoint_id
}

i get the following output

  + endpoint_id = [
      + "vpce-<obfuscated>",
    ]

This is definitely closer to what I am looking for but when I use it in the resource it tells me that I have a type mismatch

 Error: Incorrect attribute value type
│ 
│   on ../../modules/new-tgw/inspection-vpc/inspection-vpc.tf line 161, in resource "aws_route" "tgw_to_firewall_endpoint_route":
│  161:   vpc_endpoint_id        = aws_networkfirewall_firewall.inspection_networkfirewall[each.key].firewall_status[0].sync_states[*].attachment[0].endpoint_id
│     ├────────────────
│     │ aws_networkfirewall_firewall.inspection_networkfirewall is object with 3 attributes
│     │ each.key is "us-west-2b"
│ 
│ Inappropriate value for attribute "vpc_endpoint_id": string required.

not sure why it doesn’t like the string. Maybe because it thinks there is a possible other endpoint_id? There should only be one.

OK I just used what I had above but added the one() function that you mentioned. That seems to work!
So my resource now looks like this:

resource "aws_route" "tgw_to_firewall_endpoint_route" {
  for_each               = toset(var.vpc_availability_zone_names)
  route_table_id         = aws_route_table.inspection_tgw_subnet_rtb[each.key].id
  destination_cidr_block = "0.0.0.0/0"
  vpc_endpoint_id        = one(aws_networkfirewall_firewall.inspection_networkfirewall[each.key].firewall_status[0].sync_states[*].attachment[0].endpoint_id)
}

the above works now.

If i put that into the output statement I simply get the string, which is what I am looking for

output "endpoint_id" {
  value = one(aws_networkfirewall_firewall.inspection_networkfirewall["us-west-2a"].firewall_status[0].sync_states[*].attachment[0].endpoint_id)
}

output:

Changes to Outputs:
  + endpoint_id = "vpce-<obfuscated>"

Thank you @maxb! I appreciate the help!