AWS: Creating a Bastion Host
This document is intended to explain the steps in creating a bastion host. It assumes no prior knowledge of the process.
Step 1: Understand the Requirements
A great option for EC2 instances:
- Instance type: An AMI with at least 8 vCPU and 32 GB RAM (preferred: AL2023 AMI - t3.large)
- Storage type: An option with at least storage with 100 GB (preferred: gp3)
Step 2: Create or Select Your VPC and Subnets
-
Should contain:
- At least three public subnet (for Bastion)
- At least three private subnets (where your internal instances live)
- Attached Internet Gateway (so your Bastion has outbound internet)
Bastion lives in the public subnet
Step 3: Create or Select your IAM Role
-
Should contain:
- A Trusted entity: EC2
- The required IAM policies
- Attach this role to your Bastion EC2 during launch.
Step 4: Launch the EC2 Bastion Host
-
Navigate to EC2 > Instances > Launch Instance
-
Name:
Bastion-Host
—> Replace with your desired Bastion name -
AMI:
AL2023
(Choose from Amazon Marketplace AMIs) -
Instance Type:
t3.large
or better -
Key Pair: Create new or use an existing SSH key
-
Network Settings:
- Choose your VPC
- Select the public subnet attached to your VPC
- Auto-assign Public IP: Yes
-
Storage:
- Root volume: gp3
- Size: 100 GB
-
IAM Role: Attach the
BastionHostRole
—> Replace with the name of your IAM Role -
User Data (next step): Paste the install script below
- In the Advanced > User Data section during EC2 launch, paste this script:
Make sure to replace the placeholder installation versions in the script with the appropriate version numbers.
#!/bin/bash
# Update OS
yum update -y
# Install AWS CLI v2
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Install Terraform
TERRAFORM_VERSION="<REFER TO THE LATEST STABLE TERRAFORM RELEASE: https://github.com/hashicorp/terraform/releases>"
curl -O https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip
unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip
mv terraform /usr/local/bin/
# Install Terragrunt
TERRAGRUNT_VERSION="<REFER TO THE LATEST STABLE TERRAGRUNG RELEASE: https://github.com/gruntwork-io/terragrunt/releases>"
curl -L https://github.com/gruntwork-io/terragrunt/releases/download/v${TERRAGRUNT_VERSION}/terragrunt_linux_amd64 -o /usr/local/bin/terragrunt
chmod +x /usr/local/bin/terragrunt
# Install Zarf
ZARF_VERSION="<REFER TO THE LATEST SMOOTHGLUE RELEASE: https://gitlab.com/structsure/jigsaw/structsure-enterprise/-/releases>"
curl -LO https://github.com/defenseunicorns/zarf/releases/download/v${ZARF_VERSION}/zarf_v${ZARF_VERSION}_Linux_amd64
mv zarf_v${ZARF_VERSION}_Linux_amd64 /usr/local/bin/zarf
chmod +x /usr/local/bin/zarf
# Confirm installs
terraform -version
terragrunt -version
zarf version
aws --version
-
Security Group:
- Allow SSH (port 22) from your IP
- (Optional) Allow other ports if needed (like 80)
-
Launch Instance
Step 5: Access and Test
- Use your SSH key to connect:
ssh -i your-key.pem ec2-user@<Bastion-Public-IP>
- Test tools:
terraform -version
terragrunt -version
zarf version
aws --version
Optional: Accessing Private Instances via Bastion
If you have resources in private subnets that allow SSH access, and you'd like to connect to them, follow these steps:
-
Security Group Setup:
- Ensure the Bastion host's security group can reach the private EC2 instances on port 22 (SSH).
- Ensure the private instances' security group allows inbound SSH access from the Bastion’s security group.
-
SSH from Bastion Host: From your Bastion host, connect using:
ssh -i your-key.pem ec2-user@<Private-IP>