Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Change count for for_each on ram_principal_association due resource recreation #95

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
locals {
# Store the list of principals and convert to set
ram_principals = var.create_tgw && var.share_tgw ? toset(var.ram_principals) : []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simply moving this logic to a local does not correct its flaws

again, lets look at the conditional where its generally of the format conditional ? true case : false case

  • When the conditional is true, the type is of toset()
  • When the conditional is false, the type is of list since its just empty brackets

This is an issue because the types are now mis-matched (toset() vs list).

In addition, because you are using toset() on a list, any of the values in that list cannot be computed or else you will face the well known issue of not being able to use for_each on a value that is not yet known.

Lastly, changing from count to for_each is a breaking change

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess what @bryantbiggs is trying to say is since the left side of the conditional is a set you need the right one to be set too, i.e. toset([]) instead of [] which is of type list.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simply moving this logic to a local does not correct its flaws

again, lets look at the conditional where its generally of the format conditional ? true case : false case

  • When the conditional is true, the type is of toset()
  • When the conditional is false, the type is of list since its just empty brackets

This is an issue because the types are now mis-matched (toset() vs list).

In addition, because you are using toset() on a list, any of the values in that list cannot be computed or else you will face the well known issue of not being able to use for_each on a value that is not yet known.

Lastly, changing from count to for_each is a breaking change

Sorry, Bryan!

I thought you were asking to use tolist() function insted toset() 😅

There was a misunderstanding on my part and now I got it!

Indeed, for_each cannot predict these values (when computed) while using toset() function , neather iterate over a list.

I agree with u, it’s a breaking change and maybe it’s better keep this code as is, right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess what @bryantbiggs is trying to say is since the left side of the conditional is a set you need the right one to be set too, i.e. toset([]) instead of [] which is of type list.

Exactly, Igor! Thanks 🙇

However, even solving this part (making the sides equal) we will face that for_each known issue mentioned by Bryan... 😢

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was take a looking on main.tf again and currently it uses count on length(var.ram_principals) here:

count = var.create_tgw && var.share_tgw ? length(var.ram_principals) : 0

How count will know the length of the list for computed values? In this case we wil face the same problem (unknown value), right?


# List of maps with key and route values
vpc_attachments_with_routes = chunklist(flatten([
for k, v in var.vpc_attachments : setproduct([{ key = k }], v.tgw_routes) if var.create_tgw && can(v.tgw_routes)
Expand Down Expand Up @@ -161,9 +164,9 @@ resource "aws_ram_resource_association" "this" {
}

resource "aws_ram_principal_association" "this" {
count = var.create_tgw && var.share_tgw ? length(var.ram_principals) : 0
for_each = local.ram_principals

principal = var.ram_principals[count.index]
principal = each.value
resource_share_arn = aws_ram_resource_share.this[0].arn
}

Expand Down
2 changes: 1 addition & 1 deletion outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,5 @@ output "ram_resource_share_id" {

output "ram_principal_association_id" {
description = "The Amazon Resource Name (ARN) of the Resource Share and the principal, separated by a comma"
value = try(aws_ram_principal_association.this[0].id, "")
value = [for k, v in aws_ram_principal_association.this : v.id]
}