BASTET: Bastion Access Secured by Tokenized Ephemeral endpoinT
This Terraform module will create an EC2 instance in the desired subnet of your VPC and allow you to connect to it via AWS Session Manager.
Requirements:
-
Terraform 0.12 or upper
-
aws-cli
-
python 2 or 3
-
bash/sh
-
curl
-
jq
Limitation:
-
Amazon Linux AMI bastion only (cannot be customized)
You will be able to:
-
Activate or not the EC2 instance bastion creation
-
Choose how many time your AWS SSM session will be valid.
-
Activate or not the auto-shutdown (kamikaze) behavior of your bastion
-
Choose how many time your bastion will stay up and running before auto-shutdown (if activated)
-
Add a custom IAM rôle policy to your bastion EC2 instance if needed
-
Choose the instance type (default:
t2.nano
) -
Switch to classic-bastion mode (SSH key + random SSH port)
-
Perform an SSH connection directly through Session Manager (aws-cli SSM plugin requiered) thanks to the temporary AWS credentials available in the module outputs
-
Customize the bastion cloud-init YAML file: capability to add
runcmd
and/orwrite_files
and/orpackages
instructions to the instance user_data
Module implementation code examples:
module "bastet" {
source = "github.com/sdesousa86/terraform-aws-bastet.git?ref=2.0.0"
aws_cli_profile = "sandbox"
resource_name_prefix = "myproduct-env"
region = "eu-west-1"
tags = {
"Name" = "myproduct-dev"
"Environment" = "dev"
"Product" = "myproduct"
"TechOwner" = "me@mailbox.com"
"Owner" = "myboss@mailbox.com"
"BusinessUnit" = "theonewhowillpay"
}
deploy_bastion = true
kamikaze_bastion = true
bastion_lifetime = 1800
session_duration = 1800
classic_bastion = true
vpc_id = "vpc-aaabbbccc11133555"
bastion_subnet_id = "subnet-aaabbbccc11133555"
bastion_subnet_is_public = true
classic_bastion_ingress_cidr_blocks = ["0.0.0.0/0"]
aditionnal_cloud_init_packages_provided = true
aditionnal_cloud_init_packages = templatefile("${path.module}/templates/bastion-aditionnal-cloud-init-packages.tpl.yml", {})
bastion_custom_iam_policy_provided = true
bastion_custom_iam_policy = templatefile("${path.module}/templates/my_custom__bastion_iam_policy.tpl.json", {})
bastion_instance_type = "t2.nano"
}
With bastion-aditionnal-cloud-init-packages.tpl.yml
equal to:
- mysql
Note
|
!!! Watch out for the indentation in the aditionnal_cloud_init_* template files !!! |
SSH connection (classic-bastion mode enabled):
ssh -i ./bastion_private_key.pem -p <classic_bastion_ssh_port> ec2-user@<classic_bastion_public_ip>
Name | Type | Default | Description |
---|---|---|---|
|
|
|
Used to build name of the module resources (mandatory input ⇒ no default value) |
|
|
|
AWS region where the resources will be created (mandatory input ⇒ no default value) |
|
|
|
The ID of your AWS VPC where your bastion will run (mandatory input ⇒ no default value) |
|
|
|
The ID of the subnet where your bastion will run (mandatory input ⇒ no default value) |
|
|
|
You must indicate if the provided subnet is a public subnet (Route table with route to an Internet Gateway) or not (mandatory input ⇒ no default value) |
|
|
|
The aws-cli profile name that will be use (if the provided aws-cli profile is not valid, the script that use it will try to use your system default AWS credentials) |
|
|
|
Map of tags to set for each resources that accept tags |
|
|
|
Activate or not the EC2 instance bastion creation |
|
|
|
Switch to classic-bastion mode (SSH key + random SSH port) |
|
|
|
IPs to whithelist for classic-bastion access (!! Mandatory input if classic_bastion = true !! (Even if you want to set it to ["0.0.0.0/0"])) |
|
|
|
Time during which tokenized URL will be valid (in seconds). Min: 900 seconds (15 minutes) - Max: 43,200 seconds (12 hours) |
|
|
|
Activate or not the auto-shutdown (kamikaze) behavior of your bastion |
|
|
|
Time, in seconds, before your bastion will automatically shutdown (only if kamikaze_bastion = true) |
|
|
|
Indicate if a bastion_custom_iam_policy is provided (Terraform will raise an error if a bastion_custom_iam_policy is rovided and the value is set to false) |
|
|
|
A custom IAM rôle policy JSON object for your bastion EC2 instance (optional) |
|
|
|
The bastion instance type |
|
|
|
Indicate if an aditionnal_cloud_init_packages is provided (Terraform will raise an error if a aditionnal_cloud_init_packages is rovided and the value is set to false) |
|
|
|
Cloud Init YAML string starting with 'packages:' |
|
|
|
Indicate if an aditionnal_cloud_init_write_files is provided (Terraform will raise an error if a aditionnal_cloud_init_write_files is rovided and the value is set to false) |
|
|
|
Cloud Init YAML string starting with 'write_files:' |
|
|
|
Indicate if an aditionnal_cloud_init_runcmd is provided (Terraform will raise an error if a aditionnal_cloud_init_runcmd is rovided and the value is set to false) |
|
|
|
Cloud Init YAML string starting with 'runcmd:' |
Name | Type | Description |
---|---|---|
|
|
The temporary tokenized URL that will allow you to connect to the deployed bastion instance via AWS Session Manager |
|
|
The temporary AWS credentials that have been used to generate the bastion_session_manager_url (can be used to perform an SSH connection directly through Session Manager via aws-cli) |
|
|
The EC2 instance ID of the bastion |
|
|
The private IP of the bastion instance in the provided subnet |
|
|
The security group ID of the bastion instance |
|
|
Time during which your session will be valid (in seconds) |
|
|
Indicate if kamikaze bastion behaviour has been enabled or not |
|
|
Time remaining before the instance is shut down by itself (in seconds) |
|
|
Indicate if the deploy_bastion input argument as been set to true or false |
|
|
The public IP of the bastion (when classic-bastion mode is enabled) |
|
|
The local relative path where the bastion private key file ( |
|
|
The random SSH port to connect to the bastion (when classic-bastion mode is enabled) |