locals {
  first_vpc = var.vpcs[0]
  remaining_vpcs = [ for vpc in var.vpcs: vpc if vpc != local.first_vpc ]
}

# debug
#output remaining_vpcs {
#  value = local.remaining_vpcs
#}

# Create the private zones
resource "aws_route53_zone" "private" {
  name = var.dns_info["private"]["zone"]
  tags = merge(var.standard_tags, var.tags)

  vpc {
    vpc_id = local.first_vpc
  }

  # For the rationale here, see the notes at:
  # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone_association
  #
  # tldr; We can't create without an association, but we can't add associations without changing this record.
  # So we add one, and then we add it again and ignore any further changes.
  lifecycle {
    ignore_changes = [vpc]
  }
}

resource "aws_route53_record" "dnstest" {
  zone_id = aws_route53_zone.private.id
  name    = "dnstest"
  type    = "A"
  ttl     = "300"
  # Non-routable Test IP: https://tools.ietf.org/html/rfc5737
  records = [ "10.10.10.10" ]
}

resource "aws_route53_zone_association" "associations" {
  for_each = toset(local.remaining_vpcs)

  zone_id = aws_route53_zone.private.zone_id
  vpc_id  = each.value
}

# Create the private reverse zone
resource "aws_route53_zone" "reverse" {
  name = var.dns_info["reverse"]["zone"]
  tags = merge(var.standard_tags, var.tags)

  vpc {
    vpc_id = local.first_vpc
  }

  # For the rationale here, see the notes at:
  # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone_association
  #
  # tldr; We can't create without an association, but we can't add associations without changing this record.
  # So we add one, and then we add it again and ignore any further changes.
  lifecycle {
    ignore_changes = [vpc]
  }
}

resource "aws_route53_record" "dnstest_reverse" {
  zone_id = aws_route53_zone.reverse.id
  name    = "10.10.10"
  type    = "PTR"
  ttl     = "300"
  # Non-routable Test IP: https://tools.ietf.org/html/rfc5737
  records = [ "dnstest.${ var.dns_info["private"]["zone"] }" ]
}

resource "aws_route53_zone_association" "reverse_associations" {
  for_each = toset(local.remaining_vpcs)

  zone_id = aws_route53_zone.reverse.zone_id
  vpc_id  = each.value
}

###################################
# Resolver
resource "aws_route53_resolver_endpoint" "private_resolver" {
  name      = "xdr_private_dns_resolver"
  direction = "INBOUND"

  security_group_ids = [ aws_security_group.resolver_security_group.id ]

  dynamic "ip_address" {
    for_each = slice(var.subnets, 0, 2)

    content {
      subnet_id = ip_address.value
    }
  }

  tags = merge(var.standard_tags, var.tags)
}

resource "aws_security_group" "resolver_security_group" {
  name        = "route53_resolver"
  description = "Allow DNS inbound traffic"
  vpc_id      = local.first_vpc

  ingress {
    description = "DNS_UDP"
    from_port   = 53
    to_port     = 53
    protocol    = "udp"
    cidr_blocks = [ "10.0.0.0/8" ]
  }

  ingress {
    description = "DNS_TCP"
    from_port   = 53
    to_port     = 53
    protocol    = "tcp"
    cidr_blocks = [ "10.0.0.0/8" ]
  }

  egress {
    description = "DNS_UDP"
    from_port   = 53
    to_port     = 53
    protocol    = "udp"
    cidr_blocks = [ "10.0.0.0/8" ]
  }

  egress {
    description = "DNS_TCP"
    from_port   = 53
    to_port     = 53
    protocol    = "tcp"
    cidr_blocks = [ "10.0.0.0/8" ]
  }

  tags = merge(var.standard_tags, var.tags)
}
