Bastion host to get access to private subnet instance shells.

Image for post
Image for post

Bastation Hosts:

Bastion hosts (also called “jump servers”) are often used as a best practice for accessing privately accessible hosts within a system environment. For example, our system might include an application host that is not intended to be publicly accessible. To access it for product updates or managing system patches, we typically log in to a bastion host and then access (or “jump to”) the application host from there.

We deployed a NaaS infrastructure on AWS for a public WordPress server with a private MySQL database instance but we realize since this database instance does not have access to the internet. So this instance will not be able to update Softwares in it or make changes or fix bugs or patches in it. This might prove to be a major security threat.

Link given below:

We shall continue from here.

  • We create a security group in the public subnet which will allow inbound ssh to bastion host.
resource "aws_security_group" "sg3" {depends_on = [ aws_vpc.myvpc ]name        = "sg1-public-bastion"description = "Allow inbound ssh traffic bastion host"vpc_id      = aws_vpc.myvpc.idingress {description = "allow ssh"from_port   = 22to_port     = 22protocol    = "tcp"cidr_blocks = [""]}egress {from_port   = 0to_port     = 0protocol    = "-1"cidr_blocks = [""]}tags = {Name = "sg1-public-bastion"}}

Create a security group in private subnet which will allow inbound ssh from bastion host to MySQL.

resource "aws_security_group" "sg4" {depends_on = [ aws_vpc.myvpc ]name        = "sg2-private-bastion"description = "Allow inbound ssh to mysql from bastion host sg"vpc_id      = aws_vpc.myvpc.idingress {description = "allow ssh"from_port   = 22to_port     = 22protocol    = "tcp"security_groups = ["${}"]}egress {from_port   = 0to_port     = 0protocol    = "-1"cidr_blocks = [""]}tags = {Name = "sg2-private-bastion"}}

Launch the bastion host instance in the public subnet.

resource "aws_instance" "bastion" {depends_on = [ aws_security_group.sg3,aws_subnet.subnet1a ]ami = "ami-08706cb5f68222d09"instance_type = "t2.micro"vpc_security_group_ids = [ ]subnet_id = aws_subnet.subnet1a.idassociate_public_ip_address = "true"key_name = "key4"tags = {Name = "bastion host"}}

We will need a NAT gateway in the public subnet so allow one way outbound traffic for MySQL.

resource "aws_eip" "bar" {vpc = truedepends_on = [ aws_internet_gateway.myigw ]}resource "aws_nat_gateway" "natgw" {allocation_id = = aws_subnet.subnet1a.idtags = {Name = "NAT GW"}}

Create a route table that redirects requests for the outside to the nat gateway and associate it with the private subnet.

resource "aws_route_table" "private-route-table" {depends_on = [ aws_internet_gateway.myigw, aws_nat_gateway.natgw ]vpc_id = aws_vpc.myvpc.idroute {cidr_block = ""gateway_id =}tags = {Name = "private-route-table"}}resource "aws_route_table_association" "private-route-table-association" {depends_on = [ aws_route_table.private-route-table ]subnet_id      = aws_subnet.subnet1b.idroute_table_id =}
  • Once these changes are applied, we can now ssh into the MySQL instance through the Bastion host and even make updates to it that need the internet.
  • Use WinSCP to store the key in the bastion host.
  • Use Putty to SSH into the bastion host.

Having gained access to the MySQL instances shell, you can perform your operation here. Be it changing code, fixing bugs, patches, updating Softwares, etc.

GitHub link of the task is given below:

Written by

I am a DevOps Enthusiast and recently taken to Cloud Computing. Learning Flutter App Development currently. In my free time I engage in competitive coding.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store