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

provider "aws" {
  region = "us-west-2"
  alias  = "us_west_2"

  default_tags {
    tags = module.default_tags.tags
  }
}

provider "aws" {
  region = "eu-central-1"
  alias  = "eu_central_1"

  default_tags {
    tags = module.default_tags.tags
  }
}

# Terraform backends cannot contain interpolations
terraform {
  backend "s3" {
    bucket  = "networking-orcd-terraform-state"
    key     = "networking/transit-gateway-vpn-attachments/us-east-1/ny/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

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

data "aws_ec2_transit_gateway_vpc_attachment" "vpc_attachment" {
  for_each = var.vpc_routes
  filter {
    name   = "tag:vpc_name"
    values = [each.value]
  }
}

data "aws_ec2_transit_gateway_peering_attachment" "inter_region_attachment" {
  for_each = toset(values(var.inter_region_routes))
  filter {
    name   = "tag:peer_region"
    values = [each.value]
  }
}

resource "aws_customer_gateway" "customer_gateway" {
  bgp_asn    = 65000
  ip_address = var.customer_gateway_ip_address
  type       = "ipsec.1"

  tags = {
    Name         = "${var.environment}-customer-gateway-ny"
    environment  = var.environment
    service_name = "vpn"
    terraformed  = "true"
  }
}

resource "aws_cloudwatch_log_group" "vpn_logs" {
  name = "${var.environment}-vpn-logs-ny"

  tags = {
    environment  = var.environment
    service_name = "vpn"
    terraformed  = "true"
  }
}

resource "aws_vpn_connection" "vpn_connection" {
  transit_gateway_id  = data.aws_ec2_transit_gateway.transit_gateway.id
  customer_gateway_id = aws_customer_gateway.customer_gateway.id
  type                = "ipsec.1"
  static_routes_only  = true

  tunnel1_ike_versions                 = ["ikev2"]
  tunnel1_phase1_dh_group_numbers      = [20, 21, 22, 23, 24]
  tunnel1_phase1_encryption_algorithms = ["AES256"]
  tunnel1_phase1_integrity_algorithms  = ["SHA2-512"]
  tunnel1_phase2_dh_group_numbers      = [20, 21, 22, 23, 24]
  tunnel1_phase2_encryption_algorithms = ["AES256"]
  tunnel1_phase2_integrity_algorithms  = ["SHA2-512"]
  tunnel1_log_options {
    cloudwatch_log_options {
      log_enabled       = true
      log_group_arn     = aws_cloudwatch_log_group.vpn_logs.arn
      log_output_format = "json"
    }
  }

  tunnel2_ike_versions                 = ["ikev2"]
  tunnel2_phase1_dh_group_numbers      = [20, 21, 22, 23, 24]
  tunnel2_phase1_encryption_algorithms = ["AES256"]
  tunnel2_phase1_integrity_algorithms  = ["SHA2-512"]
  tunnel2_phase2_dh_group_numbers      = [20, 21, 22, 23, 24]
  tunnel2_phase2_encryption_algorithms = ["AES256"]
  tunnel2_phase2_integrity_algorithms  = ["SHA2-512"]
  tunnel2_log_options {
    cloudwatch_log_options {
      log_enabled       = true
      log_group_arn     = aws_cloudwatch_log_group.vpn_logs.arn
      log_output_format = "json"
    }
  }

  tags = {
    Name         = "${var.environment}-vpn-connection-ny"
    environment  = var.environment
    service_name = "vpn"
    terraformed  = "true"
  }
}

# Manage tags for the transit gateway attachment which is automatically created by the VPN connection.
resource "aws_ec2_tag" "vpn_connection_attachment_name_tag" {
  resource_id = aws_vpn_connection.vpn_connection.transit_gateway_attachment_id
  key         = "Name"
  value       = "${var.environment}-transit-gateway-vpn-attachment-ny"
}

resource "aws_ec2_tag" "vpn_connection_attachment_vpn_name_tag" {
  resource_id = aws_vpn_connection.vpn_connection.transit_gateway_attachment_id
  key         = "vpn_name"
  value       = "ny"
}

# Route table for the VPN attachment
resource "aws_ec2_transit_gateway_route_table" "vpn_route_table" {
  transit_gateway_id = data.aws_ec2_transit_gateway.transit_gateway.id

  tags = {
    Name         = "${var.environment}-transit-gateway-route-table-vpn-ny"
    environment  = var.environment
    service_name = "transit-gateway"
    terraformed  = "true"
  }
}

# Association between the VPN transit gateway attachment and the route table
resource "aws_ec2_transit_gateway_route_table_association" "vpn_route_table_association" {
  transit_gateway_attachment_id  = aws_vpn_connection.vpn_connection.transit_gateway_attachment_id
  transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.vpn_route_table.id
}

# Add VPN routes to the default propagation route table
resource "aws_ec2_transit_gateway_prefix_list_reference" "default_route_table_vpn_reference" {
  prefix_list_id                 = aws_ec2_managed_prefix_list.vpn_managed_prefix_list_us_east_1.id
  transit_gateway_route_table_id = data.aws_ec2_transit_gateway.transit_gateway.propagation_default_route_table_id
  transit_gateway_attachment_id  = aws_vpn_connection.vpn_connection.transit_gateway_attachment_id
}

resource "aws_ec2_transit_gateway_route" "vpc_routes" {
  for_each = var.vpc_routes

  destination_cidr_block         = each.key
  transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.vpn_route_table.id
  transit_gateway_attachment_id  = data.aws_ec2_transit_gateway_vpc_attachment.vpc_attachment[each.key].id
}

resource "aws_ec2_transit_gateway_route" "inter_region_routes" {
  for_each = var.inter_region_routes

  destination_cidr_block         = each.key
  transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.vpn_route_table.id
  transit_gateway_attachment_id  = data.aws_ec2_transit_gateway_peering_attachment.inter_region_attachment[each.value].id
}
