module "default_tags" {
  source             = "git@github.com:theorchard/terraform-default-tags.git//?ref=2.0.0"
  environment        = var.environment
  application_family = var.application_family
  service_name       = var.service_name
  team_name          = var.team_name
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = module.default_tags.tags
  }
}

provider "aws" {
  region  = var.aws_region
  alias   = "networking"
  profile = "networking"

  default_tags {
    tags = module.default_tags.tags
  }
}


# Terraform backends cannot contain interpolations
terraform {
  backend "s3" {
    bucket  = "orcd-terraform-state"
    key     = "prod/docker-ssh-proxies/fivetran-rds-proxy/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

data "aws_caller_identity" "current" {}

data "aws_route53_zone" "route53_zone_networking" {
  provider = aws.networking
  name     = "theorchard.io"
}

module "vpc_info" {
  source = "git@github.com:theorchard/terraform-vpc-info.git//?ref=3.1.0"

  environment = var.environment
}

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

  providers = {
    aws.dns = aws.networking
  }

  environment                     = var.environment
  service_name                    = var.service_name
  application_family              = var.application_family
  secrets_manager_service_name    = var.service_name
  non_ecr_image                   = "086679231553.dkr.ecr.${var.aws_region}.amazonaws.com/docker-ssh-proxy:latest"
  aws_region                      = var.aws_region
  commit_sha                      = "latest"
  container_port                  = "2222"
  task_type                       = "worker"
  health_check_command            = "echo 'orcd fivetran proxy'"
  desired_task_count              = 2
  task_cpu                        = 2048
  task_memory                     = 4096
  maximum_capacity                = 2
  minimum_capacity                = 2
  vpc_id                          = module.vpc_info.vpc_id
  additional_lb_target_group_arns = [aws_lb_target_group.fivetran_proxy_ecs_nlb_tg.arn]
  splitio_enabled                 = false
  ows_machine_to_machine_enabled  = false

  fargate_service_subnets = module.vpc_info.default_private_subnet_ids

  environment_variables = [
    {
      Environment = var.environment
    },
    {
      SERVICE_NAME = var.service_name
    },
    {
      PERMIT_DB_HOST = join(" ", var.rds_instances) # SSHD will only allow connections from these hosts. Each host should be separated by a space.
    },
    {
      PROXY_USER = "fivetran"
    },
  ]
}

resource "aws_security_group" "fivetran_proxy_ecs_nlb_sg" {
  name        = "${var.environment}-${var.service_name}-nlb-sg"
  description = "Security group for Fivetran Proxy ECS NLB"
  vpc_id      = module.vpc_info.vpc_id

  ingress {
    description = "Allow all inbound traffic from the VPC"
    from_port   = 2222
    to_port     = 2222
    protocol    = "tcp"
    cidr_blocks = [
      "35.234.176.144/29", # Fivetran CIDR Block
    ]
  }

  egress {
    description = "Allow all outbound traffic to the VPC"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = [
      "0.0.0.0/0",
    ]
  }

  tags = merge(local.tags, {
    eiso-exception = "aws.08.30"
  })
}

resource "aws_security_group_rule" "fivetran_proxy_task_allow_inbound_from_nlb" {
  type                     = "ingress"
  from_port                = 2222
  to_port                  = 2222
  protocol                 = "tcp"
  source_security_group_id = aws_security_group.fivetran_proxy_ecs_nlb_sg.id
  security_group_id        = module.fargate_environment.fargate_security_group_id
}

resource "aws_lb" "fivetran_proxy_ecs_nlb" {
  name               = "${var.environment}-${var.service_name}-nlb"
  internal           = false
  load_balancer_type = "network"
  security_groups    = [aws_security_group.fivetran_proxy_ecs_nlb_sg.id]
  subnets            = module.vpc_info.default_public_subnet_ids

  enable_cross_zone_load_balancing = true

  access_logs {
    enabled = true
    bucket  = "orch-elb-logs"
    prefix  = "${var.environment}-${var.service_name}-nlb"
  }

  tags = local.tags
}

resource "aws_route53_record" "fivetran_proxy_dns_networking_zone" {
  provider = aws.networking
  zone_id  = data.aws_route53_zone.route53_zone_networking.zone_id
  name     = "fivetran"
  type     = "CNAME"
  ttl      = 60

  records = [
    aws_lb.fivetran_proxy_ecs_nlb.dns_name,
  ]
}

resource "aws_lb_listener" "fivetran_proxy_ecs_nlb_listener" {
  load_balancer_arn = aws_lb.fivetran_proxy_ecs_nlb.arn
  port              = 2222
  protocol          = "TCP"

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

  tags = local.tags
}

resource "aws_lb_target_group" "fivetran_proxy_ecs_nlb_tg" {
  name        = "${var.environment}-${var.service_name}"
  port        = 2222
  protocol    = "TCP"
  vpc_id      = module.vpc_info.vpc_id
  target_type = "ip"

  health_check {
    healthy_threshold   = 3
    unhealthy_threshold = 3
    interval            = 10
    port                = "traffic-port"
    protocol            = "TCP"
  }

  deregistration_delay = "300"

  tags = local.tags
}

module "fargate_service_dashboard" {
  source                            = "git@github.com:theorchard/terraform-datadog.git//modules/service?ref=6.15.3"
  environment                       = var.environment
  environment_type                  = "fargate"
  service_name                      = var.service_name
  application_family                = var.application_family
  service_4xx_monitor_enabled       = false
  service_5xx_monitor_enabled       = false
  notification_endpoints            = "@slack-devops"
  escalation_notification_endpoints = "@slack-devops"
}

module "fivetran_proxy_secrets_manager" {
  source   = "git@github.com:theorchard/terraform-secrets-manager.git//?ref=1.5.1"
  for_each = toset(var.sshd_host_fingerprints_secret_names)

  application_family = var.application_family
  environment        = var.environment
  service_name       = var.service_name
  secret_name        = each.value
}
