Managed EC2 bastion host setup written in AWS CDK
EC2BastionHost construct in your CDK project: @finnairoyj/cdk-bastion-hostfcli
The solution can be deployed out-of-the-box to any account that has the Finnair LandingZone managed VPC setup. The solution can also be deployed to any other VPC but requires configuration of the target VPC and Subnets.
fcli tool uses EICE as default and SSM SessionManager only as a backup solution. Target instance must also support SSM in order for this to workimport { EC2BastionHost } from '@finnairoyj/cdk-constructs-lib/ec2'
//...
export class MyCDKStack extends Stack {
constructor(scope: Construct, id: string, props: StackProps) {
super(scope, id, props)
//...
// Bastion host setup with no additional config
new EC2BastionHost(this, 'BastionHostAML2023', {})
}
}
The bastion instance is automatically scaled up / down by the AWS EC2 Autoscaling. Do not try to manually
launch / shut down / terminate the instance! Instead, use the provided fcli tool to manage the instance,
or set up custom autoscaling schedules that suit your requirements
The bastion setup provides some options for customizing the setup. For example, RPM packages installed at startup can be added via the configuration parameters. See API docs for more info.
Supported customizations include:
Name tag of the instance and some resource naming like log groupsdnf package manager toolfcli helper toolThe fcli tool is a helper for connecting to and managing the bastion host. It also supports connecting
with native SSH to any EC2 instance that is connectable over the EC2 InstanceConnect or the older SSM SessionManager
as a backup solution. Connecting via the EC2 InstanceConnect Endpoint should be preferred. More info on the EICE
in Confluence
❯ npx fcli ssh --help
Usage: fcli ssh [options]
Connect to an EC2 instance with SSH over EC2 InstanceConnect
Options:
-s, --scale <direction> Scale bastion host instance (choices: "up", "down")
-b --bastion Connect to EC2 bastion host
--region <region> AWS Region. Defaults to current region
--tunnels <environment> Open tunnels to target instance with local port forwarding. Tunnels are specified in 'tunnels.yml' file that must be located in current folder (choices: "dev", "test",
"preprod", "prod", "tools", "sandbox")
-L <tunnel> SSH tunnels to open to bastion host using SSH local port forwarding (-L argument).
Supports multiple instances of the -L option to open multiple tunnels.
Format: -L <LocalPort>:<Hostname/IP>:<RemotePort>.
Example: -L 8080:myservice.dev.application.internal:8080
--debug Enable debug logging
--instance <instanceId> Connect to the given instance
--profile <profile> AWS login profile to use
-u, --username <os-user> Username on target instance
-h, --help display help for command
npx fcli ssh --bastion
tunnels.yml file / dev environmentnpx fcli ssh --bastion --tunnels dev
npx fcli ssh
npx fcli ssh --instance <instance-id>
npx fcli ssh --bastion -L 5432:my.database.int:5432
tunnels.yml fileYou can configure pre-defined SSH tunnel definitions in the tunnels.yml file located in the project root.
You can define any number of tunnels that will be opened simultaneously. The configuration file supports
defining separate tunnel configurations for each application environment (AWS account)
## Define SSH tunnels that can be opened by giving the --tunnels option to the SSH tool
##
## Example:
## tunnels:
## dev:
## database:
## localPort: 3306
## hostName: database.dev.application.internal
## remotePort: 3306
## IP addresses are also supported
tunnels:
dev:
some-instance:
localPort: 12345
hostName: 10.0.0.102
remotePort: 12345
The SSH session duration over the EIC Endpoint is limitet to 1 hour by AWS. Long-running tasks should be scripted and executed in the background in order to avoid issues caused by SSH session being terminated
/work volume to allow persisting data and other setups between bastion launches