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

provider "aws" {
  region = "us-east-1"

  default_tags {
    tags = module.default_tags.tags
  }
}

terraform {
  backend "s3" {
    bucket  = "shared-orcd-terraform-state"
    key     = "shared/us_east_1_vpc/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

data "aws_s3_bucket" "flow_logs_bucket" {
  bucket = "${var.environment}-orcd-vpc-logs"
}

data "aws_ec2_transit_gateway" "transit_gateway" {
  filter {
    name   = "options.amazon-side-asn"
    values = ["64513"]
  }
}

data "aws_ec2_managed_prefix_lists" "required_routes" {
  filter {
    name   = "prefix-list-name"
    values = var.vpc_routing_destination_prefix_lists
  }
}

data "aws_route53_resolver_firewall_rule_group" "dns_firewall_rule_group" {
  firewall_rule_group_id = "rslvr-frg-1764658298884585" # sony_ioc_rule_group
}

locals {
  default_private_subnets = [
    { availability_zone = "us-east-1a", cidr_block = "10.213.0.0/24", name = "shared_private_subnet_0" },
    { availability_zone = "us-east-1b", cidr_block = "10.213.1.0/24", name = "shared_private_subnet_1" },
    { availability_zone = "us-east-1c", cidr_block = "10.213.2.0/24", name = "shared_private_subnet_2" }
  ]

  service_specific_private_subnets = {
    scheduler-jenkins = [
      { availability_zone = "us-east-1a", cidr_block = "10.213.3.0/28", name = "shared_scheduler_jenkins_subnet_us_east_1a" },
      { availability_zone = "us-east-1b", cidr_block = "10.213.3.16/28", name = "shared_scheduler_jenkins_subnet_us_east_1b" },
      { availability_zone = "us-east-1c", cidr_block = "10.213.3.32/28", name = "shared_scheduler_jenkins_subnet_us_east_1c" }
    ]
    pipeline-jenkins = [
      { availability_zone = "us-east-1a", cidr_block = "10.213.3.48/28", name = "shared_pipeline_jenkins_subnet_us_east_1a" },
      { availability_zone = "us-east-1b", cidr_block = "10.213.3.64/28", name = "shared_pipeline_jenkins_subnet_us_east_1b" },
      { availability_zone = "us-east-1c", cidr_block = "10.213.3.80/28", name = "shared_pipeline_jenkins_subnet_us_east_1c" }
    ]
    dev-box = [
      { availability_zone = "us-east-1a", cidr_block = "10.213.4.0/26", name = "shared_dev_box_subnet_us_east_1a" },
      { availability_zone = "us-east-1b", cidr_block = "10.213.4.64/26", name = "shared_dev_box_subnet_us_east_1b" },
      { availability_zone = "us-east-1c", cidr_block = "10.213.4.128/26", name = "shared_dev_box_subnet_us_east_1c" }
    ]
    jump-box = [
      { availability_zone = "us-east-1a", cidr_block = "10.213.4.192/28", name = "shared_jump_box_subnet_us_east_1a" },
      { availability_zone = "us-east-1b", cidr_block = "10.213.4.208/28", name = "shared_jump_box_subnet_us_east_1b" },
    ]
    atlantis = [
      { availability_zone = "us-east-1a", cidr_block = "10.213.5.0/28", name = "shared_atlantis_subnet_us_east_1a" },
      { availability_zone = "us-east-1b", cidr_block = "10.213.5.16/28", name = "shared_atlantis_subnet_us_east_1b" },
      { availability_zone = "us-east-1c", cidr_block = "10.213.5.32/28", name = "shared_atlantis_subnet_us_east_1c" }
    ]
    rds-backup = [
      { availability_zone = "us-east-1a", cidr_block = "10.213.5.48/28", name = "shared_rds_backup_subnet_us_east_1a" },
      { availability_zone = "us-east-1b", cidr_block = "10.213.5.64/28", name = "shared_rds_backup_subnet_us_east_1b" },
    ]
  }

  default_private_subnet_cidr_blocks = [for subnet in local.default_private_subnets : subnet["cidr_block"]]
  default_private_subnet_ids = [
    for subnet in module.vpc.private_subnets : subnet.id
    if contains(local.default_private_subnet_cidr_blocks, subnet.cidr_block)
  ]
}

module "vpc" {
  source = "git@github.com:theorchard/terraform-vpc.git//modules/vpc?ref=4.1.1"

  env                        = var.environment
  account_group              = var.account_group
  vpc_cidr                   = "10.213.0.0/20"
  dns_firewall_rule_group_id = data.aws_route53_resolver_firewall_rule_group.dns_firewall_rule_group.id

  vpc_public_subnets = [
    { availability_zone = "us-east-1a", cidr_block = "10.213.15.0/26", name = "shared_public_subnet_0" },
    { availability_zone = "us-east-1b", cidr_block = "10.213.15.64/26", name = "shared_public_subnet_1" },
    { availability_zone = "us-east-1c", cidr_block = "10.213.15.128/26", name = "shared_public_subnet_2" },
  ]

  vpc_private_subnets = concat(local.default_private_subnets,
  [for service, subnets in local.service_specific_private_subnets : subnets]...)

  vpc_flow_logs = {
    gsirt = {
      log_destination      = data.aws_s3_bucket.flow_logs_bucket.arn
      log_destination_type = "s3"
      traffic_type         = "REJECT"
    }
  }
}

resource "aws_ec2_transit_gateway_vpc_attachment" "transit_gateway_attachment" {
  vpc_id             = module.vpc.vpc_id
  subnet_ids         = local.default_private_subnet_ids
  transit_gateway_id = data.aws_ec2_transit_gateway.transit_gateway.id
}

# Add routes for Orchard private networks to all private route tables
resource "aws_route" "private_internal_routes" {
  for_each = {
    for internal_route in local.internal_routes : "${internal_route.route_table_id}.${internal_route.prefix_list_id}" => internal_route
  }

  route_table_id             = each.value.route_table_id
  transit_gateway_id         = data.aws_ec2_transit_gateway.transit_gateway.id
  destination_prefix_list_id = each.value.prefix_list_id
}

resource "aws_route53_zone_association" "main" {
  for_each = toset(var.associated_route53_zone_ids)

  zone_id = each.value
  vpc_id  = module.vpc.vpc_id
}
