data "aws_s3_bucket" "logging_bucket_lb" {
  bucket = "${var.environment}-orcd-lb-logs"
}

data "aws_s3_bucket" "logging_bucket_waf" {
  bucket = "aws-waf-logs-${var.environment}-orcd"
}

module "chef_server_storage" {
  source   = "git@github.com:theorchard/terraform-efs.git//?ref=4.1.0"
  for_each = var.chef_server_persistent_directories

  providers = {
    aws.dns = aws.networking
  }

  environment              = var.environment
  service_name             = "${var.service_name}-${each.key}"
  application_family       = var.application_family
  vpc_id                   = module.vpc_info.vpc_id
  subnet_ids               = module.vpc_info.default_private_subnet_ids
  owner_gid                = "0"
  owner_uid                = "0"
  access_point_permissions = "755"
  efs_throughput_mode      = "elastic"

  efs_ingress_additional_cidr_blocks = [
    "192.168.32.0/24",
  ]
}

resource "aws_security_group_rule" "allow_chef_server_to_access_efs" {
  for_each = var.chef_server_persistent_directories

  from_port                = 2049
  to_port                  = 2049
  protocol                 = "tcp"
  security_group_id        = module.chef_server_storage[each.key].efs_security_group_id_output
  source_security_group_id = module.fargate_environment.fargate_security_group_id
  type                     = "ingress"
}

module "custom_waf" {
  source            = "git@github.com:theorchard/terraform-aws-waf.git//?ref=2.0.2"
  environment       = var.environment
  service_name      = var.service_name
  aws_region        = var.aws_region
  count_waf_enabled = false
  block_waf_enabled = true
  excluded_rules = [
    "GenericLFI_BODY",
    "SizeRestrictions_BODY",
  ]
}

resource "aws_wafv2_web_acl_logging_configuration" "waf_block_web_acl_logging_configuration" {
  log_destination_configs = [data.aws_s3_bucket.logging_bucket_waf.arn]
  resource_arn            = module.custom_waf.waf_blocking_arn_output

  redacted_fields {
    single_header {
      name = "authorization"
    }
  }

  redacted_fields {
    single_header {
      name = "session"
    }
  }

  redacted_fields {
    single_header {
      name = "cookie"
    }
  }
}

module "fargate_environment" {
  source = "git@github.com:theorchard/terraform-fargate.git//?ref=5.8.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                       = 1
  task_cpu                                 = 4096
  task_memory                              = 8192
  load_balancer_access_logs_s3_bucket_name = data.aws_s3_bucket.logging_bucket_lb.id
  load_balancer_subnets                    = module.vpc_info.default_private_subnet_ids
  fargate_service_subnets                  = module.vpc_info.default_private_subnet_ids
  health_check_path                        = "/"
  vpc_id                                   = module.vpc_info.vpc_id
  route53_zone_id                          = data.aws_route53_zone.route53_zone.zone_id
  autoscaling_cpu_policy_enabled           = false
  minimum_capacity                         = 1
  maximum_capacity                         = 1
  container_port                           = "80"
  health_check_grace_period_seconds        = 480
  non_ecr_image                            = "086679231553.dkr.ecr.us-east-1.amazonaws.com/chef-server:latest"
  custom_waf_arn                           = module.custom_waf.waf_blocking_arn_output

  iam_managed_policy_attachments = concat(
    [for k, v in var.chef_server_persistent_directories : module.chef_server_storage[k].efs_iam_policy_arn_output],
    [
      aws_iam_policy.s3_secrets_read_write_policy.arn,
    ]
  )

  docker_volumes = [for k, v in var.chef_server_persistent_directories :
    {
      name            = "${var.environment}-${var.service_name}-${k}"
      file_system_id  = module.chef_server_storage[k].efs_file_system_id_output
      access_point_id = module.chef_server_storage[k].efs_access_point_id_output
    }
  ]

  docker_volume_mount_points = [for k, v in var.chef_server_persistent_directories :
    {
      source_volume  = "${var.environment}-${var.service_name}-${k}"
      container_path = v.dir
    }
  ]

  environment_variables = [
    {
      Environment = var.environment
    },
    {
      CHEF_SERVER_NAME = "${var.environment}-${var.service_name}"
    },
    {
      COOKBOOK_STORAGE_BUCKET = module.cookbook_storage_bucket.s3_bucket_name_output
    },
    {
      COOKBOOK_STORAGE_BUCKET_REGION = var.aws_region
    },
    {
      FQDN = var.fqdn
    },
    {
      OPENSEARCH_URL = "https://${module.opensearch.aws_elasticsearch_endpoint_output}"
    },
    {
      OPENSEARCH_USER = "chef_server"
    },
    {
      POSTGRES_HOST = module.rds.rds_cluster_endpoint
    },
    {
      POSTGRES_PORT = module.rds.rds_cluster_port
    },
    {
      POSTGRES_USER = "chef_server"
    },
    {
      SECRETS_BUCKET = module.secrets_bucket.s3_bucket_name_output
    },
  ]

  secrets = [for secret in var.secrets_manager_secret_names : {
    (secret) = "${var.environment}/${var.service_name}/${secret}"
  }]
}

resource "aws_lb_listener_certificate" "additional_certificate" {
  listener_arn    = module.fargate_environment.fargate_load_balancer_https_listener_arn
  certificate_arn = data.aws_acm_certificate.theorchard_io_certificate.arn
}

# 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
}

# Allow access from prefix lists to LB
resource "aws_security_group_rule" "allow_inbound_access_to_lb" {
  type              = "ingress"
  from_port         = 443
  to_port           = 443
  protocol          = "TCP"
  prefix_list_ids   = [for list in data.aws_ec2_managed_prefix_list.prefix_lists : list.id]
  security_group_id = module.fargate_environment.fargate_load_balancer_security_group_id
}

resource "aws_route53_record" "theorchard_io_chef" {
  provider = aws.networking
  name     = var.fqdn
  type     = "CNAME"
  zone_id  = data.aws_route53_zone.route53_zone_networking.zone_id
  ttl      = 300
  records  = [module.fargate_environment.non_prod_fargate_service_route53_record_fqdn_output]
}
