Each.value context error when attempting to create multiple resources based on for_each on a map of objects

Hello,

I am trying create a number of resources using for_each and a map of objects.
However when I apply terraform I get an invalid context errror for each.value.

Steps:
1- read the content of repos.json file and run jsondecode on it
2- extract the json object containing data and assign to reposmap variable
3- call the module that generates the repositories and pass to it reposmap variable

repos.json

{
“repos”: {
“test_repo1”: {
“key”: “test_repo1”,
“name”: “test_repo1”,
“package_type”: “docker”
},
“test_repo2”: {
“key”: “test_repo2”,
“name”: “test_repo2”,
“package_type”: “docker”
}
}
}

main.tf

locals {
reposdata = jsondecode(file("${path.module}/repos.json"))
}

module “artifactory” {
source = “./test”
reposmap = local.reposdata.repos

module artifactory

artifactory/variable.tf

variable “reposmap” {
type = map(object({
key = string
name = string
package_type = string
}))
}

Here is where defining multiple instances of repo using for_each
resource “artifactory_local_repository” “createrepos” {
for_each = var.reposmap
key = each.value.key
name = each.value.name
package_type = each.value.package_type
}

Error: each.value cannot be used in this context
on artifactory/test_repo.tf line 48, in resource “artifactory_local_repository” “createrepos”:
48: key = each.value.key
A reference to “each.value” has been used in a context in which it
unavailable, such as when the configuration no longer contains the value in
its “for_each” expression. Remove this reference to each.value in your
configuration to work around this error.
Error: each.value cannot be used in this context

Any input on this appreciated.

Something’s strange here, but first I think the repos.json could be made simpler:

{
  "repos": {
    "test_repo1": {
      "package_type": "docker"
    },
    "test_repo2": {
      "package_type": "docker"
    }
  }
}

Unless repos.json is the output from some other program, or you have another compelling reason to construct it as you do, I would recommend paring it down to what’s actually needed. I don’t think the map key should be a map value.

I don’t have the artificatory provider installed - and if I did install it I wouldn’t have anything to run it against - so I just used local_file for testing the syntax

main.tf

locals {
  reposdata = jsondecode(file("./repos.json"))
}

module "artifactory" {
  source = "./test"
  reposmap = local.reposdata.repos
}
output "reposdata" {
  value = local.reposdata
}

And ./test/main.tf

variable "reposmap" {
  type = map(object({
    package_type = string
  }))
}

resource local_file createrepos {
  for_each = var.reposmap
  filename = "/tmp/${each.key}"
  content = each.value.package_type
}

This works as intended, two files are created with the right names and content

I noticed when copying/pasting from the posting here to my local filesystem that all the quotes had to be replaced, maybe it’s just something that was converted when you pasted or maybe there’s something odd with your texteditor.

Thanks for your detailed reply. The issue I had was the “name” was not one of the attributes of the resource; however the “key” attribute is required. I had another typo somewhere and this fixed it. It is more or less identical to what you had included. Thanks again.