0

What would be a best-practice to pass the same attributes/parameters to multiple blocks? I find myself always duplicating code because of this:

  env              = var.env
  location         = var.location
  tags             = local.tags
  rg_name          = var.rg_name
  subscription_id  = var.subscription_id
  service_plan_id  = local.service_plan_id
  nodejs_version   = var.nodejs_version

Here is a sample of what I currently use:

// development front-end NUXT APP dev
module "nuxt-app" {
  source = "./nuxt-app"

  env              = var.env
  name             = "appweb-${var.env}-001"
  app_service_name = "appweb-${var.env}-001"
  location         = var.location
  tags             = local.tags
  rg_name          = var.rg_name
  subscription_id  = var.subscription_id
  service_plan_id  = local.service_plan_id
  nodejs_version   = var.nodejs_version
}

module "nuxt-app-slot" {
  source = "./nuxt-app-slot"

  //skip this resource for non-dev environments
  count = local.prod_only

  env              = var.env
  name             = "preview"
  app_service_name = "appweb-${var.env}-001"
  location         = var.location
  tags             = local.tags
  rg_name          = var.rg_name
  subscription_id  = var.subscription_id
  service_plan_id  = local.service_plan_id
  nodejs_version   = var.nodejs_version
}

My target would be:

// development front-end NUXT APP dev
module "nuxt-app" {
  source = "./nuxt-app"

  name             = "appweb-${var.env}-001"
  app_service_name = "appweb-${var.env}-001"

  ...add somehow attributes
}

module "nuxt-app-slot" {
  source = "./nuxt-app-slot"

  //skip this resource for non-dev environments
  count = local.prod_only

  name             = "preview"
  app_service_name = "appweb-${var.env}-001"
  
  ...add somehow attributes
}
klodoma
  • 4,181
  • 1
  • 31
  • 42
  • You can set default values for some of the input variables, but if not, I'm not sure if there is a better way. Unless you manage to come to a solution where you have one module and then use `for_each` for example. – Marko E Aug 30 '22 at 08:30
  • DRY isn't Terraform priority: https://github.com/hashicorp/terraform/issues/5480. – sidney Jan 02 '23 at 13:42

1 Answers1

1

Assuming you can edit all the modules you're using, you can abstract common properties into a "context object" like so

locals {
 context = {
  env              = var.env
  location         = var.location
  tags             = local.tags
  rg_name          = var.rg_name
  subscription_id  = var.subscription_id
  service_plan_id  = local.service_plan_id
  nodejs_version   = var.nodejs_version
 }
}

// development front-end NUXT APP dev
module "nuxt-app" {
  source = "./nuxt-app"

  context          = local.context
  name             = "appweb-${var.env}-001"
  app_service_name = "appweb-${var.env}-001"
}

module "nuxt-app-slot" {
  source = "./nuxt-app-slot"

  //skip this resource for non-dev environments
  count = local.prod_only

  context          = local.context
  name             = "preview"
  app_service_name = "appweb-${var.env}-001"
}

You can declare the variable on your modules like so

variable "context" {
  type = (object({
    env        = string,
    location   = string,
    ...
  }))

}

variable "billing_users" {
  description = "The list of users identified by their UPN that shall be granted billing access"
  type = list(object({
    email = string,
    upn   = string,
  }))
}

An alternative you could wish for is a spread operator, which is unfortunately not in terraform as of today, see e.g. Spread operator at terraform files

Johannes Rudolph
  • 35,298
  • 14
  • 114
  • 172