A Terraform module for creating bastion host on AWS EC2 and populate its ~/.ssh/authorized_keys with public keys from bucket
Alternatives To Tf_aws_bastion_s3_keys
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Terraform Aws Ssh Bastion Service205
24 days ago1mitHCL
Terraform plan to deploy ssh bastion as a containerised, stateless service on AWS with IAM based authentication
Terraform Aws Bastion183
6 days ago4apache-2.0HCL
Terraform module which creates SSH bastion infrastructure on AWS
2 years ago9apache-2.0HCL
A Terraform module for creating bastion host on AWS EC2 and populate its ~/.ssh/authorized_keys with public keys from bucket
Terraform Aws Labs129
5 years ago1mitHCL
Terraform template for AWS provider ☁️
Terraform Aws Ec2 Bastion Server121
21 days ago13apache-2.0HCL
Terraform module to define a generic Bastion host with parameterized user_data and support for AWS SSM Session Manager for remote access with IAM authentication.
3 days ago33mitHTML
Resources for my self-hosted homelab
Terraform Sample Digitalocean Architectures100
2 years ago5apache-2.0HCL
Deployable Production Cloud Architectures for use on DigitalOcean via Terraform
3 years agoPython
Architect infrastructure on AWS using YAML
Terraform Example98
7 years agoHCL
Terraform, Ansible, sticky tape and magic
Libvirt Ocp4 Provisioner83
4 days ago3mitHCL
Automate your OCP4 installation
Alternatives To Tf_aws_bastion_s3_keys
Select To Compare

Alternative Project Comparisons


A Terraform module for creating resilient bastion host using auto-scaling group (min=max=desired=1) and populate its ~/.ssh/authorized_keys with public keys fetched from S3 bucket.

This module can append public keys, setup cron to update them and run additional commands at the end of setup. Note that if it is set up to update the keys, removing a key from the bucket will also remove it from the bastion host.

Only SSH access is allowed to the bastion host.

Input variables:

  • name - Name (default, bastion)
  • instance_type - Instance type (default, t2.micro)
  • ami - AMI ID of Ubuntu (see samples/
  • region - Region (default, eu-west-1)
  • iam_instance_profile - IAM instance profile which is allowed to access S3 bucket (see samples/
  • enable_monitoring - Whether to enable detailed monitoring (default, true)
  • s3_bucket_name - S3 bucket name which contains public keys (see samples/
  • s3_bucket_uri– S3 URI which contains the public keys. If specified, s3_bucket_name will be ignored
  • vpc_id - VPC where bastion host should be created
  • subnet_ids - List of subnet IDs where auto-scaling should create instances
  • keys_update_frequency - How often to update keys. A cron timespec or an empty string to turn off (default)
  • additional_user_data_script - Additional user-data script to run at the end
  • user_data_file - Override whold user-data script to add some custom security policies or to add support for OS you prefer. If not specified (by default) standard script will be used.
  • associate_public_ip_address - Whether to auto-assign public IP to the instance (by default - false)
  • eip - EIP to put into EC2 tag (can be used with scripts like skymill/aws-ec2-assign-elastic-ip, default - empty value)
  • key_name - Launch configuration key name to be applied to created instance(s).
  • allowed_cidr - A list of CIDR Networks to allow ssh access to. Defaults to ""
  • allowed_ipv6_cidr - A list of IPv6 CIDR Networks to allow ssh access to. Defaults to "::/0"
  • allowed_security_groups - A list of Security Group ID's to allow access to the bastion host (useful if bastion is deployed internally) Defaults to empty list
  • extra_tags - Optional a list of Key/Values Tags to be associated to the bastion host (see Interpolated Tags)


  • ssh_user - SSH user to login to bastion
  • security_group_id - ID of the security group the bastion host is launched in.

Terraform versions

For Terraform 0.12, use the version from master:

source  = ""

For Terraform 0.11, pin the module version to match v1.*. For e.g.:

source  = ""


Basic example - In your terraform code add something like this:

module "bastion" {
  source                      = ""
  instance_type               = "t2.micro"
  ami                         = "ami-123456"
  region                      = "eu-west-1"
  iam_instance_profile        = "s3_readonly"
  s3_bucket_name              = "public-keys-demo-bucket"
  vpc_id                      = "vpc-123456"
  subnet_ids                  = ["subnet-123456", "subnet-6789123", "subnet-321321"]
  keys_update_frequency       = "5,20,35,50 * * * *"
  additional_user_data_script = "date"

If you want to assign EIP to instance launched by an auto-scaling group you can provide the desired eip as module input and then execute additional_user_data_script which sets EIP. This way you can use Route53 with EIP, which will always point to existing bastion instance. You will also need to add ec2:AssociateAddress permission to iam_instance_profile (see samples/

module "bastion" {
  // see above
  eip = "${aws_eip.bastion.public_ip}"
  iam_instance_profile        = "s3_readonly-allow_associateaddress"
  additional_user_data_script = <<EOF
REGION=$(curl -s | grep region | awk -F\" '{print $4}')
INSTANCE_ID=$(curl -s
aws ec2 associate-address --region $REGION --instance-id $INSTANCE_ID --allocation-id ${}

resource "aws_eip" "bastion" {
  vpc = true

resource "aws_route53_record" "bastion" {
  zone_id = "..."
  name    = ""
  type    = "A"
  ttl     = "3600"
  records = [aws_eip.bastion.public_ip]

After you run terraform apply you should be able to login to your bastion host like:

$ ssh ${module.bastion.ssh_user}@${aws_eip.bastion.public_ip}

or even like this:

$ ssh [email protected]

PS: In some cases you may consider adding flag -A to ssh command to enable forwarding of the authentication agent connection.


Name Description Type Default Required
additional_user_data_script string "" no
allowed_cidr A list of CIDR Networks to allow ssh access to. list(string) [ "" ] no
allowed_ipv6_cidr A list of IPv6 CIDR Networks to allow ssh access to. list(string) [ "::/0" ] no
allowed_security_groups A list of Security Group ID's to allow access to. list(string) [] no
ami string n/a yes
apply_changes_immediately Whether to apply the changes at once and recreate auto-scaling group string "false" no
associate_public_ip_address string "false" no
eip string "" no
enable_hourly_cron_updates string "false" no
enable_monitoring string "true" no
extra_tags A list of tags to associate to the bastion instance. object [] no
iam_instance_profile string n/a yes
instance_type string "t2.micro" no
instance_volume_size_gb The root volume size, in gigabytes string "8" no
key_name string "" no
keys_update_frequency string "" no
name string "bastion" no
region string "eu-west-1" no
s3_bucket_name string n/a yes
s3_bucket_uri string "" no
security_group_ids Comma seperated list of security groups to apply to the bastion. string "" no
ssh_user string "ubuntu" no
subnet_ids A list of subnet ids list [] no
user_data_file string "" no
vpc_id string n/a yes


Name Description


Created and maintained by Anton Babenko.


Apache 2 Licensed. See LICENSE for full details.

Popular Bastion Host Projects
Popular Terraform Projects
Popular Security Categories
Related Searches

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Bastion Host