Trying to zipmap with a list of non-unqiue strings

Hello, we’re doing something kind of strange right now for testing out our Kubernetes cluster and trying to make Route 53 zones that all point to a test node. Eventually each Route 53 zone will get its own unique IP address that points to the correct Kubernetes node.

I’m using a local to make a zipmap of the Kubernentes node IP and the corresponding Route 53 zone, but since (for now) the set of machine IPs is the same it’s not matching up. Just wondering if there’s something that will keep the set have the same 4 IP addresses so my zipmap will work. Thanks.

var.tf:

locals {
    zone_machine = zipmap(tolist(var.zone), tolist(var.machine))
}

variable "machine" {
  type    = set(string)
  default = ["10.235.185.89", "10.235.185.89", "10.235.185.89", "10.235.185.89"]
}

variable "zone" {
  type    = set(string)
  default = ["denodo101.denodo8.xxxx.com", "denodo102.denodo8.xxxx.com", "denodo103.denodo8.xxxx.com", "denodo110.denodo8.xxxx.com"]
}

main.tf

resource "aws_route53_zone" "denodo-machines" {
  for_each = var.zone

  name          = each.value
  comment       = "For machine ${each.value}"
  force_destroy = true

  vpc {
    vpc_id = var.vpc
  }

  tags = {
    Name        = each.value
    Service     = var.service
    Contact     = var.contact
    Environment = var.environment
    OrgID       = var.orgid
    Capacity    = var.capacity
    Terraform   = "true"
  }
}

resource "aws_route53_record" "denodo-machines" {
  for_each = local.zone_machine

  zone_id = aws_route53_zone.denodo-machines[each.key].zone_id
  name    = each.key
  type    = "A"
  records = [each.value]
}

Error:

Error: Error in function call

  on var.tf line 2, in locals:
   2:     zone_machine = zipmap(tolist(var.zone), tolist(var.machine))
    |----------------
    | var.machine is set of string with 1 element
    | var.zone is set of string with 4 elements

Call to function "zipmap" failed: number of keys (4) does not match number of
values (1).

Could you change your zone variable to a list(string) instead of a set(string)? Sets in Terraform will remove duplicates. I don’t see anything with zipmap requiring them to be sets.

variable "machine" {
  type    = list(string)
  default = ["10.235.185.89", "10.235.185.89", "10.235.185.89", "10.235.185.89"]
}

This was going to be my suggestion too. It doesn’t really make sense to use sets with zipmap because that function relies on the ordering of the key list and the value list in order to correlate keys with values by index.

Another design I’d consider, which might make the data model clearer to the calling module, would be to have a single variable that packs all of the necessary information about your “zones”:

variable "zones" {
  type = map(object({
    kubernetes_host = string
    # and anything else you need to configure
    # on a per-zone basis.
  }))
}

locals {
  zone_machine = {
    for name, zone in local.zones :
    name => zone.kubernetes_host
  }
}