Generate a SSH key via Terraform for EC2

Terraform

As one of the longest lasting forms of access authentication Secure Shell (SSH) is a core tool used in every day computing. Additionally, it comes from a time before concepts like Identity Provider (Idp) or Single Sign-On (SSO). The design pattern is the user keeps a private key, then the public key is added to all the remote machines the user would connect too. This has some design incompatibility with modern system design. Namely, ephemeral resources and Zero Trust.

So how can we still use SSH in a modern development process? Well, that is a hard question to answer. But one step in the right direction is to treat the keys like cloud computing resources: disposable and replaceable.

How it’s done

# Generate a private TLS key using ED25519 encryption with a length of 2048 bits
resource "tls_private_key" "this" {
  algorithm = "ED25519"
  rsa_bits  = 2048
}

# Leverage the TLS private key to generate a SSH public/private key pair
resource "aws_key_pair" "this" {
  key_name   = "dev-dje"
  public_key = tls_private_key.this.public_key_openssh

  # when creating, pipe the private key value to the localhost ~/.ssh directory
  provisioner "local-exec" {
    # create a new one, chmod permissions of the new key, add to key chain
    when    = create
    command = "echo '${tls_private_key.this.private_key_openssh}' > ~/.ssh/${self.id}.pem; chmod 0400 ~/.ssh/${self.id}.pem"
  }

  # When this resources is destroyed, delete the associated key from the file system
  provisioner "local-exec" {
    when    = destroy
    command = "rm ~/.ssh/${self.id}.pem"
  }
}

# Finally, assign the key pair to the EC2 instance as part of the standard configuration
resource "aws_instance" "this" {
  depends_on = [
    tls_private_key.this
  ]
...
  instance_type = "t2.micro"
  key_name      = aws_key_pair.this.key_name
...
}

Caveats

  • Requires the usage of the -i /path/to/key CLI argument when using SSH. It is possible to add the key to the ssh keychain, but the idea is for the key to be ephemeral, do we want a long list of nonexistent keys in your chain?
  • The encryption material is stored in the Terraform state, in plain text. Typically the state file should be well secured and stored in a access controlled manner. But it is important to point out this security impact.

Closing

While not a solution to everyones authentication problems this solution provides a quick and easy way to generate a SSH key pair for short term usage. It also helps enforce the pattern of ephemeral resources as everything is disposable; nothing is long lived.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.