module "fargate_environment" {
  source = "git@github.com:theorchard/terraform-fargate.git//?ref=6.6.0"

  providers = {
    aws.dns = aws
  }

  environment                    = var.environment
  service_name                   = var.service_name
  application_family             = var.application_family
  aws_region                     = var.aws_region
  ows_machine_to_machine_enabled = false
  splitio_enabled                = false
  desired_task_count             = 2
  task_cpu                       = 1024
  task_memory                    = 2048
  task_type                      = "worker"
  container_port                 = 8888
  additional_ports = [
    {
      host_port      = 5160
      container_port = 5160
      protocol       = "udp"
    }
  ]
  additional_lb_target_group_arns = [aws_lb_target_group.fluentd_http.arn]

  additional_lb_target_groups = [
    {
      container_name   = var.service_name
      container_port   = 5160
      target_group_arn = aws_lb_target_group.fluentd_udp.arn
    }
  ]

  fargate_service_subnets        = module.vpc_info.default_private_subnet_ids
  health_check_command           = "curl -f http://localhost:8888/ || exit 1"
  health_check_path              = "/"
  vpc_id                         = module.vpc_info.vpc_id
  override_route53_zone_id       = data.aws_route53_zone.route53_zone.zone_id
  autoscaling_cpu_policy_enabled = false
  minimum_capacity               = 1
  maximum_capacity               = 1
  non_ecr_image                  = "086679231553.dkr.ecr.us-east-1.amazonaws.com/orchard-fluentd-agent:latest"

  environment_variables = [
    {
      Environment = var.environment
    },
  ]
}

resource "aws_lb" "fluentd" {
  # checkov:skip=CKV_AWS_91:logging for internal fluentd forwarder is not needed
  name                             = "${var.environment}-${var.service_name}-lb"
  internal                         = true
  enable_cross_zone_load_balancing = true
  load_balancer_type               = "network"
  security_groups                  = [
    aws_security_group.nlb.id,
    aws_security_group.nlb_vpn.id,
  ]
  subnets                          = module.vpc_info.default_private_subnet_ids

  tags_all = module.default_tags.tags
}

resource "aws_lb_listener" "fluentd_https" {
  load_balancer_arn = aws_lb.fluentd.arn
  port              = 8888
  protocol          = "TLS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-0-2021-06"
  certificate_arn   = data.aws_acm_certificate.theorchard_io_certificate.arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.fluentd_http.arn
  }

  tags_all = module.default_tags.tags
}

resource "aws_lb_target_group" "fluentd_http" {
  name        = "${var.environment}-${var.service_name}-http-tg"
  port        = 8888
  protocol    = "TCP"
  target_type = "ip"
  vpc_id      = module.vpc_info.vpc_id

  health_check {
    enabled             = true
    healthy_threshold   = 3
    interval            = 10
    matcher             = "200-299,301"
    path                = "/"
    port                = "traffic-port"
    protocol            = "HTTP"
    timeout             = 5
    unhealthy_threshold = 5
  }

  tags_all = module.default_tags.tags
}

resource "aws_lb_listener" "fluentd_udp" {
  load_balancer_arn = aws_lb.fluentd.arn
  port              = 5160
  protocol          = "UDP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.fluentd_udp.arn
  }

  tags_all = module.default_tags.tags
}

resource "aws_lb_target_group" "fluentd_udp" {
  name        = "${var.environment}-${var.service_name}-udp-tg"
  port        = 5160
  protocol    = "UDP"
  target_type = "ip"
  vpc_id      = module.vpc_info.vpc_id

  health_check {
    enabled             = true
    healthy_threshold   = 3
    interval            = 10
    matcher             = "200-299,301"
    path                = "/"
    port                = 8888
    protocol            = "HTTP"
    timeout             = 5
    unhealthy_threshold = 5
  }

  tags_all = module.default_tags.tags
}

# Get the ec2 prefix lists to allow access
data "aws_ec2_managed_prefix_list" "prefix_lists" {
  for_each = var.prefix_lists_to_allow_ingress_to_lb
  name     = each.value
}

data "aws_ec2_managed_prefix_list" "vpn_prefix_lists" {
  for_each = var.vpn_prefix_lists_to_allow_ingress_to_lb
  name     = each.value
}

# Allow access from prefix lists to LB
resource "aws_security_group_rule" "allow_http" {
  type      = "ingress"
  from_port = 8888
  to_port   = 8888
  protocol  = "TCP"
  prefix_list_ids = [
    for list in data.aws_ec2_managed_prefix_list.prefix_lists : list.id
  ]
  security_group_id = aws_security_group.nlb_vpn.id
}

resource "aws_security_group_rule" "allow_udp" {
  type      = "ingress"
  from_port = 5160
  to_port   = 5160
  protocol  = "UDP"
  prefix_list_ids = [
    for list in data.aws_ec2_managed_prefix_list.prefix_lists : list.id
  ]
  security_group_id = aws_security_group.nlb_vpn.id
}

# Allow access from VPN prefix lists to LB
resource "aws_security_group_rule" "allow_http_from_vpn" {
  type      = "ingress"
  from_port = 8888
  to_port   = 8888
  protocol  = "TCP"
  prefix_list_ids = [
    for list in data.aws_ec2_managed_prefix_list.vpn_prefix_lists : list.id
  ]
  security_group_id = aws_security_group.nlb_vpn.id
}

resource "aws_security_group_rule" "allow_udp_from_vpn" {
  type      = "ingress"
  from_port = 5160
  to_port   = 5160
  protocol  = "UDP"
  prefix_list_ids = [
    for list in data.aws_ec2_managed_prefix_list.vpn_prefix_lists : list.id
  ]
  security_group_id = aws_security_group.nlb_vpn.id
}

resource "aws_security_group_rule" "nlb_egress_udp" {
  type                     = "egress"
  from_port                = 5160
  to_port                  = 5160
  protocol                 = "UDP"
  security_group_id        = aws_security_group.nlb.id
  source_security_group_id = module.fargate_environment.fargate_security_group_id
}

resource "aws_security_group_rule" "nlb_egress_tcp" {
  type                     = "egress"
  from_port                = 8888
  to_port                  = 8888
  protocol                 = "TCP"
  security_group_id        = aws_security_group.nlb.id
  source_security_group_id = module.fargate_environment.fargate_security_group_id
}

resource "aws_security_group_rule" "lb_task_http" {
  from_port                = 8888
  protocol                 = "TCP"
  security_group_id        = module.fargate_environment.fargate_security_group_id
  source_security_group_id = aws_security_group.nlb.id
  to_port                  = 8888
  type                     = "ingress"
}

resource "aws_security_group_rule" "lb_task_udp" {
  from_port                = 5160
  protocol                 = "UDP"
  security_group_id        = module.fargate_environment.fargate_security_group_id
  source_security_group_id = aws_security_group.nlb.id
  to_port                  = 5160
  type                     = "ingress"
}

resource "aws_security_group" "nlb" {
  name   = "${var.environment}-${var.service_name}-nlb-sg"
  vpc_id = module.vpc_info.vpc_id

  tags_all = module.default_tags.tags
}

resource "aws_security_group" "nlb_vpn" {
  name   = "${var.environment}-${var.service_name}-nlb-vpn-sg"
  vpc_id = module.vpc_info.vpc_id

  tags_all = module.default_tags.tags
}
