locals {
  ingress-alb = [
    { from_port = 80, to_port = 80, source_sg_id = module.sg-alb.sg_id, description = "Allow inbound http from ALBs" },
    { from_port = 80, to_port = 80, source_sg_id = module.sg-win-ws.sg_id, description = "Allow inbound http from windows EC2" },
    { from_port = 80, to_port = 80, source_sg_id = module.sg-lin-ws.sg_id, description = "Allow inbound http from linux EC2" },
    { from_port = 80, to_port = 80, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound http from ECS containers" },
    { from_port = 80, to_port = 80, source_sg_id = module.sg-leveldb.sg_id, description = "Allow inbound http from leveldb" },
    { from_port = 443, to_port = 443, source_sg_id = module.sg-alb.sg_id, description = "Allow inbound https from ALBs" },
    { from_port = 443, to_port = 443, source_sg_id = module.sg-win-ws.sg_id, description = "Allow inbound https from windows EC2" },
    { from_port = 443, to_port = 443, source_sg_id = module.sg-lin-ws.sg_id, description = "Allow inbound https from linux EC2" },
    { from_port = 443, to_port = 443, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound https from ECS containers" },
    { from_port = 443, to_port = 443, source_sg_id = module.sg-leveldb.sg_id, description = "Allow inbound https from leveldb" }
  ]
  ingress-win-ws = [
    { from_port = 80, to_port = 80, source_sg_id = module.sg-alb.sg_id, description = "Allow inbound http from ALBs" },
    { from_port = 80, to_port = 80, source_sg_id = module.sg-win-ws.sg_id, description = "Allow inbound http from windows EC2" }
  ]
  ingress-lin-ws = [
    { from_port = 80, to_port = 80, source_sg_id = module.sg-alb.sg_id, description = "Allow inbound http from ALBs" },
    { from_port = 80, to_port = 80, source_sg_id = module.sg-lin-ws.sg_id, description = "Allow inbound http from linux EC2" }
  ]
  ingress-ecs = [
    { from_port = 8080, to_port = 8080, source_sg_id = module.sg-alb.sg_id, description = "Allow inbound http from ALBs" },
    { from_port = 8080, to_port = 8080, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound http from ECS" }
  ]
  ingress-aurora = [
    { from_port = 3306, to_port = 3306, source_sg_id = module.sg-win-ws.sg_id, description = "Allow inbound connections from windows EC2 web-servers" },
    { from_port = 3306, to_port = 3306, source_sg_id = module.sg-lin-ws.sg_id, description = "Allow inbound connections from linux EC2 web-servers" },
    { from_port = 3306, to_port = 3306, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound connections from ECS" },
    { from_port = 3306, to_port = 3306, source_sg_id = module.sg-win-batch.sg_id, description = "Allow inbound connections from windows EC2 utility" },
    { from_port = 3306, to_port = 3306, source_sg_id = module.sg-lin-batch.sg_id, description = "Allow inbound connections from linux EC2 utility" },
    { from_port = 3306, to_port = 3306, source_sg_id = module.sg-aws-batch.sg_id, description = "Allow inbound connections from AWS Batch" }
  ]
  ingress-leveldb = [
    { from_port = 8999, to_port = 8999, source_sg_id = module.sg-win-ws.sg_id, description = "Allow inbound connections from windows EC2 web-servers" },
    { from_port = 8999, to_port = 8999, source_sg_id = module.sg-lin-ws.sg_id, description = "Allow inbound connections from linux EC2 web-servers" },
    { from_port = 8999, to_port = 8999, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound connections from ECS" },
    { from_port = 8999, to_port = 8999, source_sg_id = module.sg-win-batch.sg_id, description = "Allow inbound connections from windows EC2 utility" },
    { from_port = 8999, to_port = 8999, source_sg_id = module.sg-lin-batch.sg_id, description = "Allow inbound connections from linux EC2 utility" },
    { from_port = 8999, to_port = 8999, source_sg_id = module.sg-aws-batch.sg_id, description = "Allow inbound connections from AWS Batch" },
    { from_port = 8999, to_port = 8999, source_sg_id = module.sg-alb.sg_id, description = "Allow inbound connections from ALB" },
    { from_port = 8999, to_port = 8999, source_sg_id = module.sg-leveldb.sg_id, description = "Allow inbound connections from leveldb" }
  ]
  ingress-win-batch = []
  ingress-lin-batch = []
  ingress-aws-batch = []
  ingress-redis = [
    { from_port = 6379, to_port = 6379, source_sg_id = module.sg-win-ws.sg_id, description = "Allow inbound connections from windows EC2 web-servers" },
    { from_port = 6379, to_port = 6379, source_sg_id = module.sg-lin-ws.sg_id, description = "Allow inbound connections from linux EC2 web-servers" },
    { from_port = 6379, to_port = 6379, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound connections from ECS" }
  ]
  ingress-couchbase = [
    { from_port = 8091, to_port = 8091, source_sg_id = module.sg-win-ws.sg_id, description = "Allow inbound connections from windows EC2 web-servers" },
    { from_port = 8091, to_port = 8091, source_sg_id = module.sg-win-batch.sg_id, description = "Allow inbound connections from windows EC2 utility" }
  ]
}

# Create security group for windows web servers
module "sg-win-ws" {
  source           = "../vpc/sg"
  sg_description   = "Allows HTTP connections to windows web servers"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-win-ws
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-win-ws", var.name_prefix)
    },
  )
}

# Create security group for load balancers
module "sg-alb" {
  source           = "../vpc/sg"
  sg_description   = "Allows HTTP connections to ALB"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-alb
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-alb", var.name_prefix)
    },
  )
}

# Create security group for linux web servers
module "sg-lin-ws" {
  source           = "../vpc/sg"
  sg_description   = "Allows HTTP connections to linux web servers"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-lin-ws
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-lin-ws", var.name_prefix)
    },
  )
}

# Create security group for containers in ECS
module "sg-ecs" {
  source           = "../vpc/sg"
  sg_description   = "Allows HTTP connections to ECS"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-ecs
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-ecs", var.name_prefix)
    },
  )
}

# Create security group for db access
module "sg-aurora" {
  source           = "../vpc/sg"
  sg_description   = "Allows connections to Aurora db"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-aurora
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-aurora", var.name_prefix)
    },
  )
}

# Create security group for access to windows EC2 instances with batch jobs
module "sg-win-batch" {
  source           = "../vpc/sg"
  sg_description   = "Allows connections to windows utility servers"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-win-batch
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-win-batch", var.name_prefix)
    },
  )
}

# Create security group for access to linux EC2 instances with batch jobs
module "sg-lin-batch" {
  source           = "../vpc/sg"
  sg_description   = "Allows connections to linux utility servers"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-lin-batch
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-lin-batch", var.name_prefix)
    },
  )
}

# Create security group for access to AWS Batch compute resources with batch jobs
module "sg-aws-batch" {
  source           = "../vpc/sg"
  sg_description   = "Allows connections to AWS Batch compute environment"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-aws-batch
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-aws-batch", var.name_prefix)
    },
  )
}

# Create security group for access to leveldb
module "sg-leveldb" {
  source           = "../vpc/sg"
  sg_description   = "Allows access to leveldb"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-leveldb
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-leveldb", var.name_prefix)
    },
  )
}

# Create security group for access to redis
module "sg-redis" {
  source           = "../vpc/sg"
  sg_description   = "Allows access to redis"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-redis
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-leveldb", var.name_prefix)
    },
  )
}

module "sg-couchbase" {
  source           = "../vpc/sg"
  sg_description   = "Allows access to redis"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-couchbase
  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-couchbase", var.name_prefix)
    },
  )
}

resource "aws_security_group" "remote_management_access" {
  description = "Allow connections via RDP and SSH from specified addresses"
  vpc_id      = var.vpc_id
  # SSH
  dynamic "ingress" {
    for_each = var.offices_ip_addr
    content {
      description = ingress.value["description"]
      from_port   = 22
      to_port     = 22
      protocol    = "tcp"
      cidr_blocks = [ingress.value["cidr"]]
    }
  }

  # RDP
  dynamic "ingress" {
    for_each = var.offices_ip_addr
    content {
      description = ingress.value["description"]
      from_port   = 3389
      to_port     = 3389
      protocol    = "tcp"
      cidr_blocks = [ingress.value["cidr"]]
    }
  }

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

  tags = merge(
    var.common_tags,
    {
      "Name"           = format("%v-sg-remote-access", var.name_prefix),
      "eiso-exception" = "aws.08.30",
    },
  )
}

resource "aws_security_group" "debug_access" {
  description = "Allow connections custom ports from specified addresses"
  vpc_id      = var.vpc_id
  # http 80
  dynamic "ingress" {
    for_each = var.offices_ip_addr
    content {
      description = ingress.value["description"]
      from_port   = 80
      to_port     = 80
      protocol    = "tcp"
      cidr_blocks = [ingress.value["cidr"]]
    }
  }

  # http 8080
  dynamic "ingress" {
    for_each = var.offices_ip_addr
    content {
      description = ingress.value["description"]
      from_port   = 8080
      to_port     = 8080
      protocol    = "tcp"
      cidr_blocks = [ingress.value["cidr"]]
    }
  }
  # DB
  dynamic "ingress" {
    for_each = var.offices_ip_addr
    content {
      description = ingress.value["description"]
      from_port   = 3306
      to_port     = 3306
      protocol    = "tcp"
      cidr_blocks = [ingress.value["cidr"]]
    }
  }

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

  tags = merge(
    var.common_tags,
    {
      "Name"           = format("%v-sg-debug", var.name_prefix),
      "eiso-exception" = "aws.08.30",
    },
  )
}
