Larry Ludden - Enterprise Java Developer - AWS Cloud Architect
Back to home
Bastion Hosts in AWS, Part 1 : Options and CloudFormation Template
Bastion hosts are a useful service for connecting to and managing virtual networks. They provide an entry point for external access while acting as a firewall-like barrier to restrict who and what can administer your network.
AWS offers other services for accessing resources within a VPC, such as the AWS VPN Client. However, using a bastion host is often simpler and more cost-effective, especially for organizations with multiple VPCs or smaller teams.
AWS provides various combinations of services with slight variations in functionality. However, in the three examples below, each begins with an EC2 instance serving as the bastion host. The services and requirements for connecting to the bastion instance are outlined below.
Option 1 : Use AWS System Manager
AWS Systems Manager is a suite of services, one of which allows you to connect to instances via a shell. To enable this, the instance must have the required agent running with the appropriate permissions. Once configured, you can connect to the instance through the AWS Systems Manager console or the command line.
Guidelines:
- The instance can be placed in any subnet.
- The instance must have outbound access on port 443 to the internet or to Systems Manager endpoints.
- The instance profile must include the AmazonSSMManagedInstanceCore policy.
- Users must have the ssm:StartSession permission to initiate a session via Systems Manager.
- The instance must have the Systems Manager Agent installed and running.
Using Session Manager : Connect to your Amazon EC2 instance using Session Manager
Option 2 : Use Amazon EC2 Instance Connect
Amazon EC2 Instance Connect simplifies SSH access to an instance. The instance must have the required agent running. When using EC2 Instance Connect, an SSH key is temporarily pushed to the instance and remains valid for only 60 seconds, during which the client can establish an SSH connection using that key.
Guidelines:
- The instance must be in a public subnet with a public IP address.
- The instance's Security Group must allow SSH traffic:
- Port 22 traffic from the internet or specific source IP addresses.
- Traffic from the Instance Connect console IP address range (if using the console).
- Users must have the ec2-instance-connect:SendSSHPublicKey permission.
- The instance must have the EC2 Instance Connect agent installed and running.
Using Instance Connect : Connect to your Linux instance using EC2 Instance Connect
Option 3 : Use Amazon EC2 Instance Connect Endpoints
Amazon EC2 Instance Connect Endpoints allow you to connect to instances within a VPC using EC2 Instance Connect, without requiring public IP addresses. This option is similar to Option 2, but it eliminates the need for the bastion instance to have a public IP.
Guidelines:
- The instance can be placed in any subnet.
- The instance's Security Group must allow SSH traffic from the EC2 Instance Connect Endpoint.
- Users must have the ec2-instance-connect:SendSSHPublicKey permission.
- The instance must have the EC2 Instance Connect agent installed and running.
Using Instance Connect Endpoints : Connect to your instances using EC2 Instance Connect Endpoint
Bastion Host Template
This is the template I’ve been using for a while. It creates an EC2 instance as the bastion host in the specified subnet and includes several additional features:
- Uses Spot Capacity – This reduces costs by approximately 66% with minimal impact on functionality. The only potential issue is if AWS reclaims the instance while it is in use, which would terminate active connections. However, since the instance is set to stop/start, it should automatically restart as long as Spot capacity is available (which is generally the case for smaller instances).
- Automatic Security Patching – On startup, the instance automatically applies security patches to address any known vulnerabilities.
- Auto Shutdown When Idle – If there are no active SSH or Systems Manager connections, the instance shuts itself down to reduce costs. Restarting it is simple using an AWS CLI command.
- Systems Manager Integration – The instance is preconfigured with the necessary permissions to allow AWS Systems Manager connections. However, the instance must have outbound access on port 443 to the internet or Systems Manager endpoints for this to work.
When the instance is initially created, it runs a startup script that performs the following actions:
- Upgrades AWS CLI – Removes AWS CLI v1 and installs AWS CLI v2.
- Applies Security Patches – Updates the instance with any available security patches.
- Enables Automatic Patching – Creates a startup script that applies security patches each time the instance boots.
- Configures Auto Shutdown – Creates a script that checks for active usage and sets up a cron job to run every 5 minutes. If the instance has been running for at least 10 minutes with no SSH or SSM activity in the last 30 minutes, it automatically shuts down to save costs.
The CloudFormation template is at:
https://github.com/larryjkl/public/blob/main/bastion-instance/bastion-instance.yml
The template creates a bastion host in the subnet you specify, but configuring the network depends on the option you choose. The template creates a Security Group for the bastion instance; however, it does not include any ingress or egress rules. You’ll need to add the appropriate rules based on your chosen approach.
In Part 2, I’ll provide a full walkthrough of creating a bastion host using an Instance Connect Endpoint (Option 3), which currently appears to be the best available option. In Part 3, I’ll cover how to use the bastion instance to tunnel to other resources within your VPC, allowing you to access them from your local machine.
Articles
Some useful AWS Java Lambda development hints
(JUNE 3 2025)Comparison of AWS Container Options and Cost
(APRIL 30 2025)Solving a Dynamic Routing Challenge with AWS Services : A Cost-Saving IOT Project
(APRIL 16 2025)Bastion Hosts in AWS, Part 1 : Options and CloudFormation Template
(MARCH 7 2025)Amazon CloudFront VPC Origins: Enhanced Security and Simplicity
(JANUARY 3 2025)Yet another AWS VPC CloudFormation Template
(DECEMBER 3 2024)Spot NAT Instances - A cheaper AWS NAT Gateway alternative
(NOVEMBER 23 2024)