How to Create Key Pair in AWS using Terraform in Right Way

How to Create Key Pair in AWS using Terraform in Right Way

How to Create Key Pair in AWS using Terraform in Right Way

Connecting to a Linux EC2 instance via SSH is a very common pattern in AWS. There are many ways in which you can SSH into your Linux instance. One of the popular ways is to use an SSH client and you need a keypair for that.

In this tutorial, you’ll learn to create an SSH key pair, use the public key of the key pair to create key pair on AWS using Terraform and download the created key pair on your local system.

So are you ready?

Don’t want to miss any posts from us? join us on our Facebook group, and follow us on Facebook, Twitter, LinkedIn, and Instagram. You can also subscribe to our newsletter below to not miss any updates from us.

What is Key Pair in AWS?

As you might already know, a key pair consists of a public key that is used to encrypt data and a private key that is used to decrypt data. Together they are called key pairs.

Key Pair = Public Key + Private Key

When you create an EC2 instance and you know you will be doing SSH into your instance. you provide a keypair so that you can use it later to connect to your instance. . A key pair is a security credential that you use while connecting to your EC2 instance.

The way it works is EC2 stores the public key on the instance and you store the private key. So while connecting to the instance, you provide your private key and you get access to your instance.

Note: Please note that EC2 doesn’t store your private key so you can’t recover it if you lose it. Also, anyone who has your key can connect to your instance. So keep your private key safe.

Prerequisite

Assumption: Before you use this tutorial to create a key pair using terraform, you should know how to create a resource on AWS using terraform. If you are a beginner I highly recommend you to read my previous post on Getting Started With Terraform on AWS In Right Way. Once you have read the post, you are ready to move ahead with this post further.

Related: 5 Ways to Create and Manage Resources in AWS

How to Create Key Pair in AWS using Terraform in Right Way

You can create an AWS EC2 key pair using terraform resource aws_key_pair. This is what it looks like-

resource "aws_key_pair" "demo_key_pair" {
  key_name   = "keypairname"
  public_key = "<Public Key>"
}

All you need to provide is the name of your key pair and the public key part of your key pair. At this point, there are two prominent ways in which you can generate a key and provide the public key to public_key attribute of aws_key_pair resource to create a key pair.

Let’s see step by step way in which you can create an EC2 key pair on AWS using terraform.

Steps to Create Key Pair in AWS using Terraform

  1. Create an SSH Key Pair
  2. Use the Public Key to Create Key Pair on AWS
  3. Download the Private Key to the Local System
  4. Validate Created Key Pair

Step 1. Create an SSH Key Pair

There are at least two ways in which you can create an SSH key consisting of a private key/public key so that you can use the public key part of it to create a key pair on AWS.

  1. Create a key using the tls_private_key terraform resource.
  2. Create a key outside terraform
Way 1: Create a key using tls_private_key terraform resource.

Terraform lets you generate SSH private key on the fly using tls_private_key resource. I see people using tls_private_key who don’t want to keep the manual activity of creating the key outside terraform. But this comes at a cost. The private key generated by tls_private_key is stored unencrypted in your terraform state file which is unsafe.

This resource can be used to create a throw-away development environment and that’s it. Never ever even think of using it in production.

However, just for the sake of knowledge, this is how you can create a key using tls_private_key in terraform.

Explanation:

#Resource to create a SSH private key
resource "tls_private_key" "demo_key" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

algorithm: It’s the name of the algorithm that will be used for generating the private keys. It can be RSAECDSA or ED25519

rsa_bits: We are using the RSA algorithm. In the case of RSA, you need to provide the size of the key. By default it’s 2048 bits however I have chosen 4096 for better security/strength of the key.

Note: You access your public key by tls_private_key.demo_key.public_key_openssh. So this is what you provide in the public_key field while creating a key pair using Terraform.

Way 2: Create a key outside terraform and use it to create key pair

As we saw that although creating a key using tls_private_key provides an automated way, it’s not safe at all. Therefore, it’s recommended to create and manage your keys outside Terraform.

Open a terminal in your system and create an SSH key using the below command(Works in Windows 10 as well)

ssh-keygen -t rsa -b 4096

Enter the file in which to save the key: Provide a file name

Enter passphrase: Just hit enter as we don’t want to put any passphrase

For confirming the passphrase hit enter again and the key gets generated.

How to Create AWS Key Pair using Terraform in Right Way 3

You see the location where the public key is generated. filename.pub usually as you can see in the above screenshot. Open the public key file and keep the content of it handy as you will need it while creating the keypair.

Step 2. Use the Public Key to Create Key Pair on AWS

Whichever way you created the key, now are ready with the public key. So we are set to create a key pair.

Create Key Pair using Public Key from public_key Resource

#Resource to Create Key Pair
resource "aws_key_pair" "generated_key" {
  key_name   = var.key_pair_name
  public_key = tls_private_key.demo_key.public_key_openssh
}

Explanation:

tls_private_key.demo_key.public_key_openssh returns the public key part of the create SSH key.

Create Key Pair using Public Key from Outside Terraform

Create a variable public_key and paste the content of the public key in the default value for the variable like below. Have one more variable for the key pair name.

#Variable Declaration
variable "public_key" {
  type = string
  default  = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD3BVBp88VgmeWU0ERBBP0C0wIvC9iaFuvOrwwU01EF13e2wjT7XQ8aIvj3CvvVXvoFK5rbms+i2Ky6F0okAS/M+il2PJgKfSUZuKiLUgr652NTADyBTxmDiMCVg/ytT/oBWxW8EF0Iu8cHkjxr1a+gIxQAZV3AgAsCVhs7gYdT5n28gZncYdCfuUp2+dAe9QvJ6RkBSy/ObaC7WrnXI/ld6BsZNJeLVpOzPjbgbRgmMOXKX87vERdi0vQ64QW7DnE/AjhR4SZ8GWxsty8sJvcuvzX2QOA5TUFtteuFE0rqFjXXCwzuysveXYwHqphs0d6LneHkRDj23ChGKaha8pLvharjq8DUtlVZ3UCBRbsT4/joeM/S71LANkhnatqTsIISP+Sg8MCt21oABvQLAcTV0j/OuDH3h+iPavkm5/EbhbZHDqavW54C4RhreKGBNjWifz1X0HByHg+z/niiEOTAfYfB0X9jqmx9r1a+iOoiPc4NBOVBWxBzq718G6xt1rEXwfmOQol0LI+mVGRBmMLgPGBvniXQv04rQqhQmRvkXHDj8nlXhNoaoXMR0pzvFuxRq/AZnCbaDRRWbEbmUREWLNFB+ZPa0qSMIBH1u8+3p3TxOumnQWw3TxRtSVfTwIPuxjFNyjCe4SyEh90aEK5P/IAPhe9x+O435Z+Es9331Q== preeti@LAPTOP-Example"
}

#Variable Declaration
variable "key_pair_name" {
  type = string
  default  = "demokeypair"
}

Now you can use these variables to create a key pair like below-

#Resource to Create Key Pair
resource "aws_key_pair" "generated_key" {
  key_name   = var.key_pair_name
  public_key = var.public_key
}

After the key pair creation, you can use it, as usual, to create an EC2 instance using this key-

key_name = aws_key_pair.generated_key.key_name

Instead of pasting the content of the public file, you can use the file function to load its content. So creating key pair will look like this-

#Resource to Create Key Pair
resource "aws_key_pair" "generated_key2" {
  key_name   = var.key_pair_name
  public_key = file("demokey.pub")
}

Step 3. Download the Private Key to the Local System

If you have created the SSH key outside Terraform, you already have your private key with you. However, If you have used the tls_private_key resource, you need to save it to your local system.

Let’s see how to do that.

If you are on a Linux system you can use a simple Linux command to save the file using local-exec provisioner.

#Resource to Create Key Pair
resource "aws_key_pair" "demo_key" {
  key_name   = var.key_pair_name
  public_key = tls_private_key.demo_key.public_key_openssh
  
  provisioner "local-exec"{
    command = "echo '${tls_private_key.demo_key.private_key_pem}' > ./${var.key_pair_name}.pem"
  }
}

However, this doesn’t work on Windows.

Windows :

Use local_file resource to download the key pair locally on your system,

resource "local_file" "local_key_pair" {
  filename = "${var.key_pair_name}.pem"
  file_permission = "0400"
  content = tls_private_key.demo_key.private_key_pem
}

Step 4. Validate Created Key Pair

Login to AWS Management Console, search EC2 and open EC2.

You will see EC2 Dashboard.

From the left nav menu -> Network and Security -> Key Pairs

Clicking on Key Pairs you can see your created key pair.

How to Create AWS Key Pair using Terraform in Right Way 1

You can also verify locally created private key or the private key file has been downloaded in your specified path.

How to Create AWS Key Pair using Terraform in Right Way 2

Final Terraform Configuration File Example Specifying Both Methods of Key Creation and Key Pair

main.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }
}

provider "aws" {
  profile = "default"
  region  = "ap-south-1"
}

#Name of the key pair
variable "key_pair_name" {
  type = string
  default  = "demokeypair"
}
#Public Key to use in Key pair Generation
variable "public_key" {
  type = string
  default  = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD3BVBp88VgmeWU0ERBBP0C0wIvC9iaFuvOrwwU01EF13e2wjT7XQ8aIvj3CvvVXvoFK5rbms+i2Ky6F0okAS/M+il2PJgKfSUZuKiLUgr652NTADyBTxmDiMCVg/ytT/oBWxW8EF0Iu8cHkjxr1a+gIxQAZV3AgAsCVhs7gYdT5n28gZncYdCfuUp2+dAe9QvJ6RkBSy/ObaC7WrnXI/ld6BsZNJeLVpOzPjbgbRgmMOXKX87vERdi0vQ64QW7DnE/AjhR4SZ8GWxsty8sJvcuvzX2QOA5TUFtteuFE0rqFjXXCwzuysveXYwHqphs0d6LneHkRDj23ChGKaha8pLvharjq8DUtlVZ3UCBRbsT4/joeM/S71LANkhnatqTsIISP+Sg8MCt21oABvQLAcTV0j/OuDH3h+iPavkm5/EbhbZHDqavW54C4RhreKGBNjWifz1X0HByHg+z/niiEOTAfYfB0X9jqmx9r1a+iOoiPc4NBOVBWxBzq718G6xt1rEXwfmOQol0LI+mVGRBmMLgPGBvniXQv04rQqhQmRvkXHDj8nlXhNoaoXMR0pzvFuxRq/AZnCbaDRRWbEbmUREWLNFB+ZPa0qSMIBH1u8+3p3TxOumnQWw3TxRtSVfTwIPuxjFNyjCe4SyEh90aEK5P/IAPhe9x+O435Z+Es9331Q== preeti@LAPTOP-AT9G4G0G"
}

#Resource to create SSH Key or Private Key
resource "tls_private_key" "demo_key" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

#Resource to Create Key Pair & Download Locally on Linux
resource "aws_key_pair" "demo_key_pair" {
  key_name   = var.key_pair_name
  public_key = tls_private_key.demo_key.public_key_openssh
  
  provisioner "local-exec"{
    command = "echo '${tls_private_key.demo_key.private_key_pem}' > ./${var.key_pair_name}.pem"
  }
}

#Resource to Create Key Pair using Public Key
resource "aws_key_pair" "key1" {
  key_name   = "demo_key_1"
  public_key = var.public_key
}

#Resource to Create Key Pair From File
resource "aws_key_pair" "key2" {
  key_name   = "demo_key_2"
  public_key = file("demokey.pub")
}

#Resource to Download Key Pair on Windows
resource "local_file" "local_key_pair" {
  filename = "${var.key_pair_name}.pem"
  file_permission = "0400"
  content = tls_private_key.demo_key.private_key_pem
}

#Example Instance Creation using Key Pair
resource "aws_instance" "demo-instance" {
	ami = "ami-06489866022e12a14"
	instance_type = "t2.micro"
	key_name = aws_key_pair.demo_key_pair.key_name
}

Once you have decided on which way you want to create your key, simplify this main.tf to suit your need. And then use the below set of commands to create your key in AWS.

terraform init - To initialize project directory with AWS specific plugins
terraform plan- To see what's being created
terraform apply- To actually create resource to AWS
terraform destroy- To delete/detroy the created resource

Clean Up

If you are creating this Key Pair for learning purposes, you can go ahead and delete your key pair

Simply run terraform destroy and it will delete all that you created using main.tf.

Happy Learning !!!

Note: Use terraform destroy with caution. As it deletes whatever you created. So make sure intend to do so.

Conclusion

In this post, you learnt how to create key pair in AWS using Terraform in right way

  • We learnt about the AWS EC2 Key Pair and how it works
  • Different ways to create an SSH Key
  • Why creating an SSH key outside Terraform is recommended?
  • Creating Key Pair on AWS using Public Key Part of SSH Key
  • How to use that key pair to create an instance

I hope you found this post helpful. Were you able to Create Key Pair in AWS using Terraform in Right Way? Please let me know in the comment section.

Enjoyed the content?

Subscribe to our newsletter below to get awesome AWS learning materials delivered straight to your inbox.

Don’t forget to motivate me by-

  • Adding a comment below on what you liked and what can be improved.
  • Follow us on
  • Subscribe to our newsletter to get notified each time we post new content
  • Share this post with your friends

2 thoughts on “How to Create Key Pair in AWS using Terraform in Right Way

  1. Hi Preeti

    Thank you for this content, it’s was very relevant for me today 🙂

    In late April 2022 AWS added the ability to finally create a KeyPair via CloudFormation
    https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-keypair.html

    From the docs:
    “When you create a new key pair, the private key is saved to AWS Systems Manager Parameter Store, using a parameter with the following name: /ec2/keypair/{key_pair_id}.”

    1. Is there no Terraform equivilant to this?
    2. Why not use something like https://github.com/terraform-aws-modules/terraform-aws-key-pair
    3. There is a missing ‘ (or one too much) in the command of the #Resource to Create Key Pair & Download Locally on Linux section. This line works
    command = “echo ‘${tls_private_key.demo_key.private_key_pem}’ > ${var.key_pair_name}.pem”

Leave a Reply

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