Skip to content

Instantly share code, notes, and snippets.

@msuzoagu
Forked from reegnz/README.md
Created July 9, 2023 21:40
Show Gist options
  • Select an option

  • Save msuzoagu/5db1940347aaa118babf7b2bfe6dcaab to your computer and use it in GitHub Desktop.

Select an option

Save msuzoagu/5db1940347aaa118babf7b2bfe6dcaab to your computer and use it in GitHub Desktop.

Revisions

  1. @reegnz reegnz revised this gist Nov 24, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -27,7 +27,7 @@ BUT!!!

    You CAN do group_by with terraform!

    This is how you do a group by employee to get projects per employee:
    This is how you do a group by project to get employees of a project:

    ```hcl
    output project_employees {
  2. @reegnz reegnz revised this gist Nov 24, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -30,10 +30,10 @@ You CAN do group_by with terraform!
    This is how you do a group by employee to get projects per employee:

    ```hcl
    output employee_projects {
    output project_employees {
    value = {
    for item in local.input :
    item.employee => item.project...
    item.project => item.employee...
    }
    }
    ```
  3. @reegnz reegnz revised this gist Nov 24, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -27,7 +27,7 @@ BUT!!!

    You CAN do group_by with terraform!

    This is how you do a group by project:
    This is how you do a group by employee to get projects per employee:

    ```hcl
    output employee_projects {
  4. @reegnz reegnz revised this gist Nov 24, 2020. 2 changed files with 80 additions and 52 deletions.
    80 changes: 80 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@
    # The Terraform group_by you've been missing

    I'm playing around a lot nowadays with Terraform 0.13 and I found a really interesting feature and that's the `...` symbol (also called an ellipsis) to be used with `for` expressions.

    The operator can be used for group_by operations.

    ## Example

    We have a list of entries. The list contains employee/manager/project triplets.

    ```hcl
    locals {
    input = [
    { employee = "Pete", manager = "Joe", project = "DEF" },
    { employee = "Paul", manager = "Joe", project = "ABC" },
    { employee = "Paul", manager = "Joe", project = "DEF" },
    { employee = "Pam", manager = "Jim", project = "ABC" },
    ]
    }
    ```

    The goal is to group the list by either one of the attributes.

    First you'd try to go check terraform built-in function for group_by, but after an hour of groking the terraform documentation you realize that terraform doesn't have a built-in group-by function for a list of maps/objects. You start to give up.

    BUT!!!

    You CAN do group_by with terraform!

    This is how you do a group by project:

    ```hcl
    output employee_projects {
    value = {
    for item in local.input :
    item.employee => item.project...
    }
    }
    ```

    And given the above input, you'd get this output:
    ```hcl
    {
    "ABC" = [
    "Paul",
    "Pam",
    ]
    "DEF" = [
    "Pete",
    "Paul",
    ]
    }
    ```


    The crucial part is the `...`. This feature is hidden deep in the documentation of the [`for` expression](https://www.terraform.io/docs/configuration/expressions.html#for-expressions) with only a single example to grab onto:

    > Finally, if the result type is an object (using `{` and `}` delimiters) then the value result expression can be followed by the `...` symbol to group together results that have a common key:
    ```hcl
    {for s in var.list : substr(s, 0, 1) => s... if s != ""}
    ```

    There was also a [blog post introducing TF 0.12 `for` and `for_each`](https://www.hashicorp.com/blog/hashicorp-terraform-0-12-preview-for-and-for-each) that mentions this feature:

    > Finally, the map form of a `for` expression has a grouping mode where the map key is used to group items together into a list for each distinct key. This mode is activated by placing an ellipsis (`...`) after the value expression:
    ```hcl
    # Configuration for Terraform 0.12
    output "instances_by_availability_zone" {
    # Result is a map from availability zone to instance ids, such as:
    # {"us-east-1a": ["i-1234", "i-5678"]}
    value = {
    for instance in aws_instance.example:
    instance.availability_zone => instance.id...
    }
    }
    ```
    > In the the example above we show that a resource with count set now also behaves as a list, allowing all of the instances of `aws_instance.example` to be iterated over to produce a grouping by availability zone.

    And that's how you group_by in Terraform!
    52 changes: 0 additions & 52 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,52 +0,0 @@
    # The Terraform group_by you've been missing

    I'm playing around a lot nowadays with Terraform 0.13 and I found a really interesting
    feature and that's the `...` operator for for expressions.

    The operator can be used for group_by operations.

    ## Example

    We have a list of entries. The list contains employee/manager/project triplets.

    ```hcl
    locals {
    input = [
    { employee = "Pete", manager = "Joe", project = "DEF" },
    { employee = "Paul", manager = "Joe", project = "ABC" },
    { employee = "Paul", manager = "Joe", project = "DEF" },
    { employee = "Pam", manager = "Jim", project = "ABC" },
    ]
    }
    ```

    The goal is to group the list by either one of the attributes.

    First you'd try to go check terraform built-in function for group_by, but after an hour of grokking
    the terraform documentation you realize that terraform doesn't have a built-in group-by function
    for a list of maps/objects. You start to give up.

    BUT!!!

    You CAN do group_by with terraform!

    This is how you do a group by project:

    ```hcl
    output employee_projects {
    value = {
    for item in local.input :
    item.employee => item.project...
    }
    }
    ```

    The crucial part is the `...`. This feature is hidden deep in the documentation of the
    [for expression](https://www.terraform.io/docs/configuration/expressions.html#for-expressions)

    > Finally, if the result type is an object (using { and } delimiters) then the value result expression can be followed by the ... symbol to group together results that have a common key:

    {for s in var.list : substr(s, 0, 1) => s... if s != ""}


    And that's how you group_by in Terraform!
  5. @reegnz reegnz created this gist Nov 24, 2020.
    52 changes: 52 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    # The Terraform group_by you've been missing

    I'm playing around a lot nowadays with Terraform 0.13 and I found a really interesting
    feature and that's the `...` operator for for expressions.

    The operator can be used for group_by operations.

    ## Example

    We have a list of entries. The list contains employee/manager/project triplets.

    ```hcl
    locals {
    input = [
    { employee = "Pete", manager = "Joe", project = "DEF" },
    { employee = "Paul", manager = "Joe", project = "ABC" },
    { employee = "Paul", manager = "Joe", project = "DEF" },
    { employee = "Pam", manager = "Jim", project = "ABC" },
    ]
    }
    ```

    The goal is to group the list by either one of the attributes.

    First you'd try to go check terraform built-in function for group_by, but after an hour of grokking
    the terraform documentation you realize that terraform doesn't have a built-in group-by function
    for a list of maps/objects. You start to give up.

    BUT!!!

    You CAN do group_by with terraform!

    This is how you do a group by project:

    ```hcl
    output employee_projects {
    value = {
    for item in local.input :
    item.employee => item.project...
    }
    }
    ```

    The crucial part is the `...`. This feature is hidden deep in the documentation of the
    [for expression](https://www.terraform.io/docs/configuration/expressions.html#for-expressions)

    > Finally, if the result type is an object (using { and } delimiters) then the value result expression can be followed by the ... symbol to group together results that have a common key:

    {for s in var.list : substr(s, 0, 1) => s... if s != ""}


    And that's how you group_by in Terraform!
    29 changes: 29 additions & 0 deletions main.tf
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,29 @@
    locals {
    input = [
    { employee = "Pete", manager = "Joe", project = "DEF" },
    { employee = "Paul", manager = "Joe", project = "ABC" },
    { employee = "Paul", manager = "Joe", project = "DEF" },
    { employee = "Pam", manager = "Jim", project = "ABC" },
    ]
    }

    output project_employees {
    value = {
    for item in local.input :
    item.project => item.employee...
    }
    }

    output employee_projects {
    value = {
    for item in local.input :
    item.employee => item.project...
    }
    }

    output manager_employees {
    value = {
    for item in local.input :
    item.manager => item.employee...
    }
    }