Hi @jollyranger! It sounds like you already found a working solution so my reply here is just to share another possible way to do it. I donāt think either of these is necessarily better than the other but this way is just the way I would approach it.
I tend to like to approach problems like this by breaking them down into smaller steps that are easier to express as a hopefully-intelligible smaller expression. In this case I see three potential smaller steps:
- Project the āAzure projectsā so that they are in a map data structure with the sequence numbers as keys.
- Project the āAzure contributorsā so that they are in a map data structure with the sequence numbers as keys.
- Zip the two maps together by those common keys to produce a single data structure.
Iām assuming from your example that for the āAzure projectsā either the āoriginalā and āproject nameā will always have the same sequence number or the āproject nameā's sequence number is the important one; Iām going to implement with that assumption in mind but hopefully you can see how to adapt this if that isnāt a correct assumption.
locals {
projects_by_seq = tomap({
for proj in local.azure_projects :
regex("SEQ\\d{5,}", proj.project_name) => proj
})
contributors_by_seq = tomap({
for name in local.azure_contributors :
regex("SEQ\\d{5,}", name) => {
name = name
}
})
}
The above completes the first two steps, giving data structures like this:
projects_by_seq = tomap({
"SEQ00480" = {
original = "MY-SUB-EX-P-SEQ00480-PRD-PUB-LCFS-DEF"
project_name = "AS-EX-P-SEQ00480-PRD-PUB-LCFS-DEF"
}
"SEQ00482" = {
original = "MY-SUB-EX-P-SEQ00482-PRD-PUB-PAMP-TA1"
project_name = "AS-EX-P-SEQ00482-PRD-PUB-PAMP-TA1"
}
"SEQ00484" = {
original = "MY-SUB-EX-P-SEQ00484-SEE-DP-Fundamentals"
project_name = "AS-EX-P-SEQ00484-SEE-DP-Fundamentals"
}
})
contributors_by_seq = tomap({
"SEQ00480" = {
name = "MY-GRP-EX-P-SEQ00480-Contributor"
}
"SEQ00481" = {
name = "MY-GRP-EX-P-SEQ00481-Contributor"
}
"SEQ00482" = {
name = "MY-GRP-EX-P-SEQ00482-Contributor"
}
"SEQ00483" = {
name = "MY-GRP-EX-P-SEQ00483-Contributor"
}
"SEQ00484" = {
name = "MY-GRP-EX-P-SEQ00484-Contributor"
}
})
Another assumption Iāve made from your example is that we should ignore any contributors whose sequence key does not appear in any project, and that if a project has no contributor then we should set the contributor name to null
. With those assumptions in mind, hereās step 3:
locals {
project_contributors = toset([
for k, proj in local.projects_by_seq : {
project_name = proj.project_name
contributor = try(local.contributors_by_seq[k].name, null)
}
])
}
I expect that this would produce a data structure like the one you showed in your example:
project_contributors = toset([
{
contributor = "MY-GRP-EX-P-SEQ00480-Contributor"
project_name = "AS-EX-P-SEQ00480-PRD-PUB-LCFS-DEF"
},
{
contributor = "MY-GRP-EX-P-SEQ00482-Contributor"
project_name = "AS-EX-P-SEQ00482-PRD-PUB-PAMP-TA1"
},
{
contributor = "MY-GRP-EX-P-SEQ00484-Contributor"
project_name = "AS-EX-P-SEQ00484-SEE-DP-Fundamentals"
},
])
A lot of solutions in Terraform come down to choosing the most appropriate data structure for the work you want to do, projecting the data into that structure, and then using the intermediate data structure to get the final result. I chose to use maps for the intermediate data structures here because your requirement was to group things together by strings and that seems like a āmap-type problemā.
Continuing the theme of selecting the most appropriate data type, I also made the final data structure be a set of objects rather than a list as you illustrated, because this process of first grouping by sequence key and then zipping together has effectively lost the original order of projects, and a set data type communicates that these items are not in any particular order, whereas a list implies that the order is meaningful in some way. (If you did use a list here then theyād be ordered by the map keys, meaning that theyād be ordered by the sequence key. If thatās a suitable order then you could use tolist
instead of toset
to get that result.)