cloudposse / terraform-aws-ec2-bastion-server

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.
https://cloudposse.com/accelerate
Apache License 2.0
155 stars 110 forks source link

Add support for multiple keypairs #26

Open dmattia opened 4 years ago

dmattia commented 4 years ago

It would be great if this module could make EC2s that multiple different users could ssh onto.

One way to do this would be to create an s3 bucket that IAM Users could upload public keys to, and then a cronjob could be setup in the user_data that would read in those keys.

Another way would be to have a var take in a list of public keys, and then the user_data could iterate over those keys and add them all as authorized keys.

I would be down to do either of these options if there is interest

m0xx commented 4 years ago

I just had the same idea with the s3 scheme you described. I think it would be better than using user_data since it would re-create the instance every times keys changes... if I'm correct.

dmattia commented 4 years ago

Yep, that's my understanding. Though in theory, the EC2s made from this module should be able to be recreated all the time unless you're manually installing deps on the bastion host.

Truth be told, I have a module in my company where I did go with the S3 route, and it's worked well overall. I made this issue because I'm hoping to migrate from our private module to this one.

But there are a few reasons why I haven't loved the experience with the S3 bucket, and why I like the pure terraform approach:

m0xx commented 4 years ago

Thanks for the feedback very interesting.

  1. How to add keys via user_data?
  2. How would you manage the changes of the instance ip? With elastic ip?
dmattia commented 4 years ago
  1. This can be done by appending the list of public keys to ~/.ssh/authorized_keys
  2. Right now I just let the IP change, but am using DNS so I don't have to think about the ip. With strict host checking on my local machine, this does mean that I would have to update known_hosts after every deploy.

So if you don't want to have to update known_hosts, I think an EIP is a good idea. So we could add something like:

variable use_eip {
  type = bool
  description = "When true, an elastic IP address will be set on the instance"
  default = false
}

variable existing_eip_id {
  description = "If set, and var.use_eip is true, this existing EIP will be used for the EC2 instance. If not set, an EIP will be allocated within this module"
  default = null
}

variable authorized_keys {
  type = list(string)
  default = []
  description = "Public keys that are authorized to ssh onto the instance"
}
timcosta commented 3 years ago

Bit of a necro, but just found this module after using several other cloudposse modules and wanted to drop a link to https://github.com/Guimove/terraform-aws-bastion in here. We're using it to automate the generation of users using keys from an S3 bucket, and it'll log everything users do to the same S3 bucket for auditing purposes. Allows our users to provision access to the bastion by creating a PR with their public key to a repo, and on merge TF will upload the key to S3 and then this module will set everything else up. Might be some inspiration for adding similar functionality here!