Terraform AWS Bastion host based on Docker Bastion
A Bastion host is providing isolation between not safe external world and private VPC for infrastructure. That's what Amazon himself writes about it:
Including bastion hosts in your VPC environment enables you to securely connect to your Linux instances without exposing your environment to the Internet. After you set up your bastion hosts, you can access the other instances in your VPC through Secure Shell (SSH) connections on Linux. Bastion hosts are also configured with security groups to provide fine-grained ingress control. source
- Can be run with low consumption of costs or even just on AWS Free Tier
- No need additional provisioning tools like Ansible, Chief of Puppet, all based on clear Terraform
- The module is almost an independent with zero-external resources dependencies except for
VPC ID
andSubnets Id
which Bastion module assigned to - Provisioning based on CoreOS ignitions so very fast, declarative and predictable
- Providing a two-mode of work: with using an
SSH
demon on the host machine or more secure - with additional isolation by runningSSH
Bastion inDocker
container (most recommended) - Possible to upgrade or downgrade a Bastion
sshd
(SSH Server) version (only when used BastionSSH
Docker version) - Can be set custom Docker image and version for
SSH
(with Docker version only) by default is using this one https://github.com/binlab/docker-bastion - Optional generation
SSH
pair for host, by default (RSA-4096) (not recommended, better to provisioning externalSSH
public key) - Access to Bastion by
SSH
also can by provisioning Root CA certificate and principals - Custom
SSH Authorized Principals
can be configured for bought modes: Host and Docker. More https://man.openbsd.org/sshd_config#AuthorizedPrincipalsFile - Provided assigning external own Root CA for cases when Bastion need secure communicate with internal infrastructure
For deploying you need a list of permissions. For beginners might be difficult to set up minimal need permissions, so here the list wildcard for main actions.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BastionProvisioning",
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": "*"
}
]
}
The module can be deployed with almost default values of variables. For more details of the default values looking here
...
module "bastion" {
source = "github.com/binlab/terraform-aws-bastion?ref=v0.1.0"
vpc_id = vpc.vpc_id
vpc_subnet_id = vpc.public_subnets[0]
ec2_ssh_cidr = ["0.0.0.0/0"]
bastion_ssh_cidr = ["0.0.0.0/0"]
ec2_ssh_auth_keys = [file("~/.ssh/id_rsa.pub")]
bastion_ssh_auth_keys = [file("~/.ssh/id_rsa.pub")]
}
output "ec2_ssh_private_key" {
value = module.bastion.ec2_ssh_private_key
}
output "bastion_public_ip" {
value = module.bastion.public_ip
}
output "bastion_public_dns" {
value = module.bastion.public_dns
}
Then run:
$ terraform init
$ terraform apply
After deploying the process you should see:
...
bastion_public_dns = ec2-12-34-56-78.us-east-1.compute.amazonaws.com
bastion_public_ip = 12.34.56.78
ec2_ssh_private_key =
$
* ec2_ssh_private_key
is empty because we defined own key
- Add examples of use with different cases
- Hosted module on Terraform Registry - #11
- Add validation of input data in variables.tf
- Add support Fedora CoreOS as announced CoreOS Container Linux will reach its end of life on May 26, 2020 and will no longer receive updates.
- Replace creating EC2 instances to an autoscaling group
- Add support of OpenStack (OS) Terraform module
- Add support of Google Cloud Platform (GCP) Terraform module
- Add support of Microsoft Azure Terraform module
- Add support of AliCloud Terraform module
- Add support of Oracle Cloud (OCI) Terraform module
- Requirements block and versions.tf may not accurately display a real minimum version of providers. A declared versions ware just an installed in the time of development and testing of the module and can give guaranties of working with this or higher version. If you use older versions of modules for some reason and can give some guarantees of working with it, please create an issue for downscaling some version to minimal needed.
Name | Version |
---|---|
terraform | >= 0.12 |
aws | >= 2.53.0 |
ignition | >= 1.2.1 |
tls | >= 2.1.1 |
Name | Version |
---|---|
aws | >= 2.53.0 |
ignition | >= 1.2.1 |
tls | >= 2.1.1 |
Name | Description | Type | Default | Required |
---|---|---|---|---|
ami_channel | AMI filter for OS channel [stable/edge/beta/etc] | string |
"stable" |
no |
ami_image | Specific AMI image ID in current Avalability Zone e.g. [ami-123456] If provided nodes will be run on it, for cases when image built by Packer if set it will disable search images by "ami_vendor" and "ami_channel". Note: Instance OS should support CoreOS Ignition provisioning |
string |
"" |
no |
ami_vendor | AMI filter for OS vendor [coreos/flatcar] | string |
"flatcar" |
no |
associate_public_ip | Associate a public IP address with an instance in a VPC in time of launch |
bool |
true |
no |
availability_zone | Index of Availability Zone to deploy, starting from 0. For example: "us-east-1a"=0, "us-east-1b"=1, "us-east-1c"=2 ... |
number |
0 |
no |
bastion_ssh_auth_keys | List of SSH authorized keys assigned to "bastion" user By default is ["false"] which means disabled pass external keys and dont generate |
list(string) |
[] |
no |
bastion_ssh_cidr | Allowed CIDRs to connect to a cluster on ALB endpoint | list(string) |
[ |
no |
bastion_ssh_port | Bastion SSH port open to the users connect. May be open to the whole world so try to not use the standard port (22). Changing this value might request redeploy an instance (need to reconfigure SSH config) |
number |
10022 |
no |
ca_ssh_public_keys | List of SSH Certificate Authority public keys. Specifies a public keys of certificate authorities that are trusted to sign user certificates for authentication. More: https://man.openbsd.org/sshd_config#TrustedUserCAKeys |
list(string) |
[] |
no |
ca_tls_public_keys | List of custom Certificate Authority public keys. Used when need to connect from Vault to resources with a self-signed certificate |
list(string) |
[] |
no |
cpu_credits | The credit option for CPU usage [unlimited/standard] | string |
"standard" |
no |
description | Description for Tags in all resources. | string |
"Bastion Tower" |
no |
docker_repo | Vault Docker repository URI | string |
"docker://binlab/bastion" |
no |
docker_tag | Vault Docker image version tag | string |
"1.2.0" |
no |
ec2_ssh_algorithm | The name of the algorithm to use for the key. Currently-supported values are "RSA" and "ECDSA". Applying Only if variable "ec2_ssh_auth_keys" not set. |
string |
"RSA" |
no |
ec2_ssh_auth_keys | List of SSH authorized keys assigned to "Core" user (sudo user) | list(string) |
[] |
no |
ec2_ssh_cidr | List of CIDR/IP which will be allowed to connect to EC2 instances on SSH port. Generally not needed to use. If need, you can connect to the instance via bastion Sometimes need just for debugging. By default disallowed all IPs. Allow it with the caution. |
list(string) |
[ |
no |
ec2_ssh_ecdsa_curve | When algorithm is "ECDSA", the name of the elliptic curve to use. May be any one of "P224", "P256", "P384" or "P521", with "P256" as the default. Applying Only if variable "ec2_ssh_auth_keys" not set. |
string |
"P256" |
no |
ec2_ssh_port | EC2 instance SSH port. Generally not needed to use. If need, you can connect to the instance via Bastion itself. Sometimes need just for debugging. |
number |
22 |
no |
ec2_ssh_rsa_bits | When algorithm is "RSA", the size of the generated RSA key in bits. Defaults to 4096. Applying Only if variable "ec2_ssh_auth_keys" not set. |
number |
4096 |
no |
instance_type | Type of instance e.g. [t3.small] | string |
"t3.small" |
no |
monitoring | CloudWatch detailed monitoring [true/false] | bool |
false |
no |
prefix | Prefix of a tag "Name", can be a namespace. Format of "Name" tag "--" |
string |
"tf-" |
no |
security_groups | List of external Security Groups for assigning to EC2 instances. Useful for custom configuration with another infrastructure to which the Bastion connected. |
list(string) |
[] |
no |
ssh_admin_principals | List of SSH authorized principals for user "Core" when SSH login configured via Certificate Authority ("ca_ssh_public_key" is set) https://man.openbsd.org/sshd_config#AuthorizedPrincipalsFile |
list(string) |
[ |
no |
ssh_bastion_principals | List of SSH authorized principals for "Bastion" user when SSH login configured via Certificate Authority ("ca_ssh_public_key" is set) https://man.openbsd.org/sshd_config#AuthorizedPrincipalsFile |
list(string) |
[ |
no |
ssh_core_principals | List of SSH authorized principals for user "Admin" when SSH login configured via Certificate Authority ("ca_ssh_public_key" is set) More: https://man.openbsd.org/sshd_config#AuthorizedPrincipalsFile |
list(string) |
[ |
no |
stack | Stack name and tag "Name", can be a project name. Format of "Name" tag "--" |
string |
"binlab" |
no |
tags | Map of tags assigned to each or created resources in AWS. By default, used predefined described map in a file "locals.tf". Each of them can be overwritten here separately. |
map(string) |
{} |
no |
volume_size | Node (Root) volume block device Size (GB) e.g. [8] | number |
8 |
no |
volume_type | Node (Root) volume block Device Type e.g. [gp2] | string |
"gp2" |
no |
vpc_id | External VPC ID which Bastion module assigned to | string |
n/a | yes |
vpc_subnet_id | External VPC Subnet ID which Bastion module assigned to | string |
n/a | yes |
Name | Description |
---|---|
ec2_ssh_private_key | SSH private key which generated by module and its public key part assigned to each of nodes. Don't recommended do this as a private key will be kept open and stored in a state file. Instead of this set variable "ssh_authorized_keys". Please note, if "ssh_authorized_keys" set "ssh_private_key" return empty output |
public_dns | Public DNS name associated with an instance by AWS Can be assigned to a domain name by CNAME record |
public_ip | Public IP associated with an instance by AWS Can be assigned to a domain name by "A record" |
security_group_id | Security Group ID which created within the module Useful for assigning to other Security Groups as a source |