# -------------VPC-------------
resource "aws_vpc" "vpc" {
  cidr_block = var.vpc_cidr

  instance_tenancy     = "default"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = var.vpc_name
  }
}

# -------------public subnet------------- 
resource "aws_subnet" "public_subnet_a" {
  vpc_id     = aws_vpc.vpc.id
  cidr_block = var.public_subnet_a_cidr

  availability_zone       = "ap-northeast-2a"
  map_public_ip_on_launch = true

  tags = {
    Name = var.public_subnet_a_name
  }
}
resource "aws_subnet" "public_subnet_b" {
  vpc_id     = aws_vpc.vpc.id
  cidr_block = var.public_subnet_b_cidr

  availability_zone       = "ap-northeast-2b"
  map_public_ip_on_launch = true

  tags = {
    Name = var.public_subnet_b_name
  }
}

# -------------private subnet-------------
resource "aws_subnet" "private_subnet_a" {
  vpc_id     = aws_vpc.vpc.id
  cidr_block = var.private_subnet_a_cidr

  availability_zone = "ap-northeast-2a"

  tags = {
    Name = var.private_subnet_a_name
  }
}
resource "aws_subnet" "private_subnet_b" {
  vpc_id     = aws_vpc.vpc.id
  cidr_block = var.private_subnet_b_cidr

  availability_zone = "ap-northeast-2b"

  tags = {
    Name = var.private_subnet_b_name
  }
}

# -------------internet gateway-------------
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.vpc.id

  tags = {
    Name = var.igw_name
  }
}

# -------------nat gateway-------------
resource "aws_eip" "nat_a_eip" {
}
resource "aws_eip" "nat_b_eip" {
}

resource "aws_nat_gateway" "nat_a" {
  allocation_id = aws_eip.nat_a_eip.id
  subnet_id     = aws_subnet.public_subnet_a.id

  tags = {
    Name = var.nat_a_name
  }

  depends_on = [aws_eip.nat_a_eip]
}
resource "aws_nat_gateway" "nat_b" {
  allocation_id = aws_eip.nat_b_eip.id
  subnet_id     = aws_subnet.public_subnet_b.id

  tags = {
    Name = var.nat_b_name
  }

  depends_on = [aws_eip.nat_b_eip]
}

# -------------public route table-------------
resource "aws_route_table" "public_rt" {
  vpc_id = aws_vpc.vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }

  tags = {
    Name = var.public_rt_name
  }
}

# -------------private route table-------------
resource "aws_route_table" "private_a_rt" {
  vpc_id = aws_vpc.vpc.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat_a.id
  }

  tags = {
    Name = var.private_a_rt_name
  }
}
resource "aws_route_table" "private_b_rt" {
  vpc_id = aws_vpc.vpc.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat_b.id
  }

  tags = {
    Name = var.private_b_rt_name
  }
}

# ---route table association---
resource "aws_route_table_association" "public_a_association" {
  subnet_id      = aws_subnet.public_subnet_a.id
  route_table_id = aws_route_table.public_rt.id
}
resource "aws_route_table_association" "public_b_association" {
  subnet_id      = aws_subnet.public_subnet_b.id
  route_table_id = aws_route_table.public_rt.id
}
resource "aws_route_table_association" "private_a_association" {
  subnet_id      = aws_subnet.private_subnet_a.id
  route_table_id = aws_route_table.private_a_rt.id
}
resource "aws_route_table_association" "private_b_association" {
  subnet_id      = aws_subnet.private_subnet_b.id
  route_table_id = aws_route_table.private_b_rt.id
}

# ---Bastion Server---
resource "tls_private_key" "rsa" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "aws_key_pair" "keypair" {
  key_name   = "wsi"
  public_key = tls_private_key.rsa.public_key_openssh
}

resource "local_file" "keypair" {
  content  = tls_private_key.rsa.private_key_pem
  filename = "./wsi.pem"
}

resource "aws_iam_role" "bastion_role" {
  name = var.bastion_role_name

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "bastion_role_attachment" {
  role = aws_iam_role.bastion_role.name
  policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}

resource "aws_iam_instance_profile" "bastion-profile" {
  name = var.bastion_profile_name
  role = aws_iam_role.bastion_role.name
}

resource "aws_instance" "bastion" {
  ami                         = "ami-062cddb9d94dcf95d"
  subnet_id                   = aws_subnet.public_subnet_a.id
  instance_type               = var.bastion_instance_type
  key_name                    = aws_key_pair.keypair.key_name
  vpc_security_group_ids      = [aws_security_group.bastion.id]
  associate_public_ip_address = true
  iam_instance_profile        = aws_iam_instance_profile.bastion-profile.name
  user_data = "${file("./src/userdata.sh")}"

  tags = {
    Name = var.bastion_name
  }
}

resource "aws_security_group" "bastion" {
  name   = var.bastion_sg_name
  description = var.bastion_sg_name
  vpc_id = aws_vpc.vpc.id

  ingress {
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 22
    to_port     = 22
  }

  egress {
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
    from_port = "0"
    to_port = "0"
  }

  tags = {
    Name = var.bastion_sg_name
  }
}