# AWS with Terraform Tutorial: AWS Key Pairs (10)

> How to configure and use the Terraform aws_key_pair resource to upload an SSH public key to AWS and use it for public key authentication on EC2 instances.

- Source: https://www.itwonderlab.com/aws-terraform-tutorial-aws-key-pairs/
- Published: 2024-03-01
- Updated: 2026-10-05
- Author: Javier Ruiz Jiménez (https://www.javierruizjimenez.com/)
- Site: IT Wonder Lab (https://www.itwonderlab.com/)

---

## How to Create, and Manage AWS Key Pairs with Terraform

**How to configure and use the Terraform `aws_key_pair` resource block to create and manage AWS Key Pairs for performing SSH Public Key Authentication into EC2 instances.**

Welcome to our tutorial series where we dive into cloud infrastructure deployment using **[Terraform or OpenTofu on AWS](https://www.itwonderlab.com/tag/aws-terraform-essential-guide/)**. In this series, the fundamentals are shown, guiding you through the process of minimizing resource usage and simplifying the deployment complexities associated with cloud infrastructure.

This comprehensive **OpenTofu and Terraform tutorial** guides you step-by-step through creating infrastructure in AWS using Terraform.

![Terraform Basics, AWS Basics, Terraform AWS Provider, AWS VPC, AWS Subnets, AWS Internet Gateway, AWS NAT Gateway, AWS Routing Tables, AWS Security Groups, AWS Key Pairs, AWS AMIs, AWS EC2 Instances, AWS RDS, AWS Route 53 (DNS), AWS Auto Scaling, AWS Load Balancers, Terraform AWS & Ansible, Terraform Modules, Terraform Backends, Terraform Tools, Terraform CI/CD.](https://www.itwonderlab.com/media/tutorials/AWS-Terraform-Essentials/ITWL-Tutorials-AWS-Terraform-Essentials-Steps.svg)

Infrastructure as Code (IaC) helps maintain consistency, enables version control, enhances collaboration among teams, allows for easier replication of environments, streamlines the deployment and management of infrastructure boosting efficiency, and reducing errors in managing complex systems.

### Prerequisites

Read the previous sections of the tutorial, listed in the [series index](#series) at the end of this page.

### AWS Key Pair

An AWS Key Pair is a set of security credentials that consists of a **public key** and a **private key**. It is used to securely connect to Amazon EC2 instances and authenticate access using **[Public key authentication](https://www.itwonderlab.com/public-key-authentication/)** for SSH.

![AWS key pair: Terraform uploads only the public key to AWS and the instance stores it, while the private key stays on your computer and is used to connect over SSH](https://www.itwonderlab.com/media/tutorials/AWS-Terraform-Essentials/ITWL-AWS-Terraform-Key-Pair.svg "Key pairs: the public key goes to AWS, the private key stays with you")

The AWS Key Pair can be generated using the AWS Console or using external tools like ssh-keygen. AWS only stores the Public Key and AWS generated Private Keys are deleted after being generated and downloaded. See [Generating and using AWS Key Pairs with Terraform or OpenTofu](https://www.itwonderlab.com/aws-key-pairs-terraform/) for more details.

In this tutorial the Key Pair is generated outside AWS, using the command line tool `ssh-keygen`.

During instance launch, [Cloud-init](https://www.itwonderlab.com/cloud-init/) appends the AWS stored Public Key to the instance authorized\_keys file inside the ~/.ssh/ directory.

### How to create an AWS Key Pair with Terraform

Previous sections of this [AWS with Terraform guide](https://www.itwonderlab.com/tag/aws-terraform-essential-guide/) have covered basic information about Terraform and AWS and have configured and used the AWS Terraform provider to create a VPC, four subnets, one Internet Gateway, two NAT Gateways, three Routing Tables, and Security Groups.

It is time to:

-   Generate a Key Pair that will allow SSH Authentication into the instance.
-   Upload the Key Pair Public Key to AWS using Terraform (to be used in Cloud-init scripts).

### Generate a Public Key using ssh-keygen

#### Prerequisites

The ssh-keygen command is part of OpenSSH authentication key utility and is readily available on most Linux distributions:

```shell
$ ssh-keygen
```

#### Generate a Key Pair

There are multiple ways to generate [SSH](https://www.itwonderlab.com/ssh/) Key Pairs depending on the needs.

Command line quick generation without a passphrase

-   `-t ed25519` indicates using the [Edwards-curve Digital Signature Algorithm](https://www.itwonderlab.com/aws-key-pairs-terraform/#about-edwards-curve-digital-signature-algorithm-ed25519) for key generation.
-   `-N ""` avoids setting a passphrase (a secret used to protect the private key).
-   `-C "Demo IT Wonder Lab SSH User"` is a text description of the Key Pair.
-   `-f ~/keys/ditwl-kp-config-user-ecdsa` specifies where to store the private and public key files.

Generate the Key Pair:

```shell
$ ssh-keygen -t ed25519 -N "" -C "Demo IT Wonder Lab SSH User" -f ~/keys/ditwl-kp-config-user-ecdsa
Generating public/private ed25519 key pair.
Your identification has been saved in /home/jruiz/keys/ditwl-kp-config-user-ecdsa
Your public key has been saved in /home/jruiz/keys/ditwl-kp-config-user-ecdsa.pub
The key fingerprint is:
SHA256:w3ErTHem1Iz3JVvhmL7rx5uVE0b4idJauyTh6mGqirQ Demo IT Wonder Lab SSH User
The key's randomart image is:
+--[ED25519 256]--+
|               . |
|           +  + o|
|        o = *..=o|
|       + = * .== |
|        S.o  oo+ |
|     .  .oo . . +|
|    . .  B =   +.|
|     E  = B o   *|
|   .o... o o  .Bo|
+----[SHA256]-----+
```

Two files are generated in the ~/keys/ directory (~ is the user home directory):

-   `ditwl-kp-config-user-ecdsa`: private key, to use by SSH and Ansible.
-   `ditwl-kp-config-user-ecdsa.pub`: a public key to be distributed to EC2 instances using AWS Console or Terraform.

> [!NOTE]
> Make sure to store the files in a secure location and make a backup.

#### Set the right permission to the file

The private key file should be readable only by its owner. Set the right permission:

```shell
$ chmod 600 $HOME/keys/ditwl_kp_infradmin.pem
```

#### Terraform Code for Key Pairs

Key Pair creation in AWS (uploading, as it has already been created locally using ssh-keygen) is done with the `aws_key_pair` Terraform Block.

Add the following block to the `terraform-aws-tutorial.tf` created in previous sections.

```yaml
# Upload a Private Key Pair for SSH Instance Authentication
resource "aws_key_pair" "ditwl-kp-config-user" {
  key_name   = "ditwl-kp-config-user"
  public_key = file("~/keys/ditwl-kp-config-user-ecdsa.pub")
}
```

### Run the Terraform Plan

Open a command line shell in the directory where the file `terraform-aws-tutorial.tf` is located, and run the Terraform or OpenTofu `plan` and `apply` commands.

#### Plan using OpenTofu

Run `tofu plan` to generate and review the execution plan. Check each line and value to make sure that it corresponds to the desired change.

Terraform will refresh the state comparing it with the Cloud resources and produce a plan for the resources that need to be created, updated, or destroyed.

In the previous section of the tutorial, some resources were commented out to reduce the infrastructure cost during development. As the Public Key doesn’t have any dependency yet with the commented code, there is no need to uncomment.

Run the Terraform plan:

```shell
$ tofu plan
aws_vpc.ditlw-vpc: Refreshing state... [id=vpc-0d9d5a25ebe999037]
...
OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

OpenTofu will perform the following actions:

  # aws_key_pair.ditwl-kp-config-user will be created
  + resource "aws_key_pair" "ditwl-kp-config-user" {
      + arn             = (known after apply)
      + fingerprint     = (known after apply)
      + id              = (known after apply)
      + key_name        = "ditwl-kp-config-user"
      + key_name_prefix = (known after apply)
      + key_pair_id     = (known after apply)
      + key_type        = (known after apply)
      + public_key      = "ssh-ed25519 AAAAC3NzaC1lZYUA1NTE5AAASIA1CQW/T/mJrP+YWKg+l100+JYlPLNIHBFYRNy3uyZUh Demo IT Wonder Lab SSH User"
      + tags_all        = {
          + "cost_center" = "marketing-department"
          + "environment" = "pro"
          + "owner"       = "IT Wonder Lab"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.
...
```

#### Apply the changes using OpenTofu

Run `tofu apply` to generate and **apply** the execution plan. OpenTofu will generate a new plan and ask for confirmation before applying the changes. Review again the changes and answer yes or no to apply the changes in AWS.

```shell
$ tofu apply
aws_vpc.ditlw-vpc: Refreshing state... [id=vpc-0d9d5a25ebe999037]
...
OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

OpenTofu will perform the following actions:

  # aws_key_pair.ditwl-kp-config-user will be created
  + resource "aws_key_pair" "ditwl-kp-config-user" {
      + arn             = (known after apply)
      + fingerprint     = (known after apply)
      + id              = (known after apply)
      + key_name        = "ditwl-kp-config-user"
      + key_name_prefix = (known after apply)
      + key_pair_id     = (known after apply)
      + key_type        = (known after apply)
      + public_key      = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1CQW/T/mJrP+YWLg+l800+JYlPLNIHVFXRNy3zyZUh Demo IT Wonder Lab SSH User"
      + tags_all        = {
          + "cost_center" = "marketing-department"
          + "environment" = "pro"
          + "owner"       = "IT Wonder Lab"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  OpenTofu will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_key_pair.ditwl-kp-config-user: Creating...
aws_key_pair.ditwl-kp-config-user: Creation complete after 2s [id=ditwl-kp-config-user]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```

Review the result, it should be `1 (resource) added, 0 changed, 0 destroyed`.

Check that the Key Pair has been created in AWS Console.

Navigate to [AWS Console: EC2 – Key Pairs](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#KeyPairs:).

![Key pairs EC2 us east](https://www.itwonderlab.com/media/tutorials/Terraform-AWS-Key-Pair/Key-pairs-EC2-us-east-1.png)

### Key Pairs Cost

There is no cost for creating or having Key Pairs in AWS.

### Common Questions About AWS Key Pairs

#### Can a lost AWS Key Pair be regenerated?

AWS doesn’t allow regeneration of lost key pairs. If you lose the private key, you’ll need to create a new key pair and update your instances accordingly. Authorized keys injection can be done by stopping the instance and mounting the EBS root volume in another instance to make changes in its file system.

#### Where should the AWS Key Pair be stored?

Private key should be protected. Store it securely and avoid sharing it. It’s crucial for accessing instances. AWS recommends using a password-protected, encrypted key store.

#### Can the same Key Pair be used for multiple instances?

Yes, you can use the same key pair for multiple instances. It simplifies management, but be cautious about security implications and consider creating separate key pairs for different purposes and different environments to reduce risk.

#### How to associate an AWS Key Pair with an EC2 instance?

During the instance creation process, you can specify the key pair.

#### What’s the role of AWS Key Pairs in security groups?

AWS Key Pairs and security groups serve different purposes. Key pairs are for instance access, while security groups control inbound and outbound traffic to instances. They complement each other for a secure setup. A key pair is not the only option: [AWS Systems Manager Session Manager](https://www.itwonderlab.com/aws-systems-manager/) gives shell access without SSH keys or open ports.

### Next Steps

Continue with [AWS AMIs](https://www.itwonderlab.com/aws-terraform-tutorial-aws-ami/), or see the [full series index](#series).
