In our previous post, we explored how to enhance storage resiliency by attaching EFS volumes to multiple EC2 instances.
Now, let's delve into AWS networking concepts, starting with the pivotal role of Bastion hosts. We'll employ Terraform to create modular components, ensuring a seamless and reproducible setup.
A bastion host is a server whose purpose is to provide access to a private network from an external network, such as the Internet. Because of its exposure to potential attack, a bastion host must minimize the chances of penetration. For example, you can use a bastion host to mitigate the risk of allowing SSH connections from an external network to the Linux instances launched in a private subnet of your Amazon Virtual Private Cloud (VPC).
Architecture Overview:
Before diving into implementation, let's understand the architecture we'll be building:
Step 1: Creating the VPC and Network Components
Create VPC with IGW, 1 Public and 1 private subnet with route table associations. Please refer to my github repo in resources section below.
Step 2: Deploying a Bastion Host in the Public Subnet and a Private Host in the Private Subnet
Deploy Linux EC2 instances one in each subnet.
####################################################
# Create EC2 Server Instances
####################################################
module "vpc_a_bastion_host" {
source = "./modules/web"
instance_type = var.instance_type
instance_key = var.instance_key
subnet_id = module.vpc_a.public_subnets[0]
vpc_id = module.vpc_a.vpc_id
ec2_name = "Bastion Host A"
sg_ingress_ports = var.sg_ingress_public
common_tags = local.common_tags
naming_prefix = local.naming_prefix
}
module "vpc_a_private_host" {
source = "./modules/web"
instance_type = var.instance_type
instance_key = var.instance_key
subnet_id = module.vpc_a.private_subnets[0]
vpc_id = module.vpc_a.vpc_id
ec2_name = "Private Host A"
sg_ingress_ports = var.sg_ingress_private
common_tags = local.common_tags
naming_prefix = local.naming_prefix
}
Step 3: Implementing Access Restriction using Security Groups
Amend private subnet security group to allow traffic only from public subnet.
####################################################
# Amend Private Host SG to allow traffic from Bastion Host SG
####################################################
resource "aws_security_group_rule" "public_in_ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
security_group_id = module.vpc_a_private_host.security_group_id
source_security_group_id = module.vpc_a_bastion_host.security_group_id
}
Steps to Run Terraform
Follow these steps to execute the Terraform configuration:
terraform init
terraform plan
terraform apply -auto-approve
Upon successful completion, Terraform will provide relevant outputs.
Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
Testing the outcome
Bastion Host with Public IP in Public Subnet:
Private Host without Public IP in Private Subnet:
Private Host Security group with only inbound from Bastion Host Security Group:
Connecting to Private Host from Bastion Host.
You will need to create key pair with correct permissions on bastion host before connecting to Private Host
chmod 0400 WorkshopKeyPair.pem
ssh ec2-user@10.1.2.71 -i WorkshopKeyPair.pem
Cleanup:
Remember to stop AWS components to avoid large bills.
terraform destroy -auto-approve
With the Bastion host setup accomplished, our next module will delve deeper into AWS networking. We'll explore setting up peer-to-peer VPC connections to further enhance our network architecture.
Resources:
Github Link: https://github.com/chinmayto/terraform-aws-networking-bastion-host
Bastion Host Concept: https://www.knowledgehut.com/tutorials/aws/aws-bastion-host
Top comments (0)