Terraform module output

Hi,

I have a module defined that reads from a YAML and uses restapi to create some resources like this,

module "acp_yaml" {
  source    = "../read_files"
  filepaths = ["../account_plans/*.yaml"]
}

resource "random_uuid" "acp_uuid" {
  for_each = module.acp_yaml.files
}

resource "restapi_object" "acp" {
  for_each = module.acp_yaml.files

  provider = restapi.restapi_oauth
  path     = "/account-plans"
  data = jsonencode({
    "uuid" : random_uuid.acp_uuid[each.key].id,
    "name" : module.acp_yaml.files[each.key].account_plan.name
    })
}

output "acp_uuids" {
  value = restapi_object.acp
}

Now the output looks like this,

"acp_uuids" = {
  "acp_gold" = {
    "api_data" = tomap({
      "name" = "Scripted Gold"
      "uuid" = "b06dd4f8-051f-12f1-2650-cd8e4bd06b0d"
    })
  }
  "acp_silver" = {
    "api_data" = tomap({
      "name" = "Scripted Silver"
      "uuid" = "cf80c035-2f18-dcca-332d-f963bbbbeae9"
    })
  }
}

I would like to output just the UUIDs of acp_gold and acp_silver, how to change output to achieve that?
I tried this,

output "acp_uuids" {
  value = restapi_object.acp[*].*.api_data.uuid
}

That’s giving an error like this,

│ Error: Unsupported attribute
│
│   on ..\..\modules\account_plans\outputs.tf line 2, in output "acp_uuids":
│    2:     value = restapi_object.acp[*].*.api_data.uuid
│
│ This object does not have an attribute named "api_data".

I tried this,

output "acp_uuids" {
  value = restapi_object.acp[*].acp_gold.api_data.uuid
}

That works, but like expected it only gives one uuid, I would like both to be output.

Any ideas of how to read the output using “module.acp_yaml.files” (for_each) from a different module will be helpful too.

Hi @arun-a-nayagam,

I think the following expression will achieve something like what you are describing:

  value = tomap({
    for name, obj in restapi_object.acp :
    name => obj.api_data["uuid"]
  })

This is a for expression, which is a more general version of the splat operator that can work with both mappings and sequences (whereas splat is only for sequences).

Hi @apparentlymart ,

Thank you, that’s exactly what I was looking for, now the output looks like this,

account_plans = {
  "acp_uuids" = tomap({
    "acp_gold" = "b06dd4f8-051f-12f1-2650-cd8e4bd06b0d"
    "acp_silver" = "cf80c035-2f18-dcca-332d-f963bbbbeae9"
  })
}

Now to read it from a different module, I am trying an expression like this,

“AccountPlanUuid” : module.account_plans.output.acp_uuids[each.key]

  1. That “module.account_plans” is not accessible from the other module, how do I make it accessible?
  2. Also, would like to know the correct expression to read from the above output.

Please ignore that question, I figured it out.

For anyone else in similar scenario,

  1. In the other module, pass module.account_plans like this, and create a local variable
module "orgs" {
  source = "../../modules/orgs"
  acp_uuids = module.account_plans.acp_uuids
}
  1. The correct expression to access will be like this,

“AccountPlanUuid” : var.acp_uuids[module.org_yaml.files[each.key].org.account_plan]