chris3ware
chris3ware

Reputation: 65

Dynamic block with for_each inside a resource created with for_each syntax assitance

I am trying to find a way to conditionally populate the pages block of the github_repository resource, when the resource itself is created using for_each. The dynamic block seems to be the appropriate way to achieve this, but I am struggling with the syntax.

I've tried with the code below and it fails.

variables.tf:

variable "repositories" {
  description = "The repositories to create using terraform"
  type = list(object({
    name                 = string,
    description          = string,
    vulnerability_alerts = bool,
    pages_cname          = string
   }))
  }

terraform.tfvars.json:

{
  "repositories": [
    {
      "name": "repo-with-pages",
      "description": "Repository with pages enabled.",
      "vulnerability_alerts": true,
      "pages_cname": "www.example.com"
    },
    {
      "name": "repo-without-pages",
      "description": "Repository without pages enabled.",
      "vulnerability_alerts": true
    }
  ]
}

main.tf:

resource "github_repository" "this" {
  for_each               = { for repo in var.repositories : repo.name => repo }
  name                   = each.value.name
  description            = each.value.description
  vulnerability_alerts   = each.value.vulnerability_alerts

  dynamic "pages" {
    for_each = { for repo in var.repositories : repo.name => repo }
    content {
      source {
        branch = "main"
        path   = "/docs"
      }
      cname = each.value.pages_cname
      }
    }
  }
 

Result:

Error: Too many pages blocks

on main.tf line 43, in resource "github_repository" "this":
43:     content {

No more than 1 "pages" blocks are allowed

This makes perfect sense because the for expression within the dynamic block for_each returns two values (repo-with-pages and repo-without-pages) and only 1 page block is allowed. So, what needs to happen is the for_each / for expression combination needs to return 1 value - the name of the repository created - IF pages are enabled.

Been looking at this for a while and beginning to wonder if what I want to do is even possible or if I am over complicating things. Any help most welcome. Thanks.

Upvotes: 5

Views: 18062

Answers (1)

Marcin
Marcin

Reputation: 238867

To make pages_cname optional it should be:

variable "repositories" {
  description = "The repositories to create using terraform"
  type = list(any)

then

  dynamic "pages" {
    for_each = contains(keys(each.value), "pages_cname") ? [1] : []
    content {
      source {
        branch = "main"
        path   = "/docs"
      }
      cname = each.value.pages_cname
      }
    }
  }

Upvotes: 3

Related Questions