How to generate the dynamic block with template data

I am trying to create datadog dashboards for different services. I would like to generate the widget block dynamically for the resource.
The goal is we would like to store RDS, SQS, Redis widget code in files and read the whole content inside resource. Say, if one service needs RDS and SQS and other service need SQS and Redis only. We would like to create these dynamically with terraform.
Is adding the entire content from file possible with dynamic blocks?

Hope it will help, I just start terraform yesterday and I generate a CodePipeline with dynamic block and template.

I made an example of how I made it: Terraform 12.x CodePipeline Dynamic Stages and Actions

If someone see issues or have suggestion thanks to tell me!

Hi @isukapalli, I am trying to do something similar for datadog dashboards but using a map type. The example given by @KerberosMorphy is fairly straight forward but it seems using a further nested block with the required widget definition does not appear to work.

Below example fails with:

Error: Argument or block definition required

on …/modules/datadog_monitor/dashboard-example.tf line 38, in resource “datadog_dashboard” “ordered_dashboard”:
38: widget.key {

An argument or block definition is required here. To set an argument, use the
equals sign “=” to introduce the argument value.

Example:

variable "widgets" {
  description = "describe your widget"
  default = {
    "alert_graph_definition" = {
      title    = "CPU utilization",
      alert_id = "161273",
      viz_type = "timeseries"
    }
  }
}


resource "datadog_dashboard" "ordered_dashboard" {
  title        = "Ordered Layout Dashboard"
  description  = "Created using the Datadog provider in Terraform"
  layout_type  = "ordered"
  is_read_only = true

  widget {
    alert_graph_definition {
      alert_id = "161273"
      viz_type = "timeseries"
      title    = "Widget Title"
      time = {
        live_span = "1h"
      }
    }
  }

  dynamic widget {
    for_each = var.widgets
    content {
      widget.key { 
        alert_id = widget.value["alert_id"]
        title    = widget.value["title"]
        viz_type = widget.value["viz_type"]
        time = {
          live_span = "1h"
        }
      }
    }
  }
}

Overall it might be related to https://github.com/hashicorp/terraform/issues/25025

But maybe @apparentlymart has an idea how to tackle sourcing a template file or solving above in nested blocks? :blush:

Hi @ps-xaf I try and succeed to generate AWS Lambdas from a json, I assign a complete object for variables, don’t know if it’s what you search to do.

locals {
  lambda_functions     = fileexists("${var.base_path}/lambdas/lambda_functions.json") ? jsondecode(templatefile("${var.base_path}/lambdas/lambda_functions.json", { client = var.client, stage = var.stage, random = random_id.lambda.b64_url, kwargs = var.lambda_functions_kwargs })) : null
}

resource "aws_lambda_function" "lambdas" {
  for_each      = local.lambda_functions
  function_name = "${each.value.function_name}-${random_id.lambda.b64_url}"
  filename      = "${path.module}/lambdas/${each.value.function_name}/${each.value.function_name}-${random_id.lambda.b64_url}.zip"
  handler       = "${each.value.function_name}-${random_id.lambda.b64_url}.lambda_handler"
  role          = aws_iam_role.lambdas[each.key].arn
  runtime       = "python3.8"
  timeout       = 60
  lifecycle {
    ignore_changes = [filename, last_modified]
  }
  environment {
    variables = each.value.environment
  }
}

But next things I want to try its Python-Terrascript. I didn’t try yet, but seems nice.
I’m more comfortable to use Python to generate terraform script in a high customisable way.
I plan to create function that could generate all the ressource need for, per example, an AWS Lambda Function (IAM role, policies, function, archive, etc…).
So maybe it could help you.