Create AWS EC2 Instance With Key Pairs Using Terraform
Tags: devops, aws, terraform
Published: 2023-01-26 05:33:23

Terraform has become one of my favorite tools I tried out recently. If you are reading this article, then I’m guessing you are already familiar with it. But if not, check out this 👉 [introduction](https://developer.hashicorp.com/terraform/intro) to get some basics first.

# **Write configuration**

For this tutorial, we will primarily use 3 *tf* config files. Let’s create a dedicated directory to store them.

```bash
mkdir aws-ec2-with-key-pairs
cd aws-ec2-with-key-pairs
```

Now that we are in the directory, create the config files and open them on your favorite code editor. I’m using [Visual Studio Code](https://code.visualstudio.com/).

```bash
touch main.tf variable.tf output.tf
code .
```

## [**variable.tf**](http://variable.tf)

This is where we will save our config variables which will be used in [*main.tf*](http://main.tf)*,*

```json
variable "instance-region" {
  description = "Value of AWS region"
  type        = string
  default     = "eu-central-1"
}

variable "instance-name" {
  description = "Value of the Name tag for the EC2 instance"
  type        = string
  default     = "OverEngineeredVPS"
}

variable "key-pair" {
  description = "Value of AWS SSH key-pair name"
  type        = string
  default     = "oei-key-pair"
}
```

## [**main.tf**](http://main.tf)

Let’s use the variables we set to create an EC2 instance.

```javascript
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.2.0"
}

resource "tls_private_key" "oei-key" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "aws_key_pair" "oei-key-pair" {
  key_name = "oei-key-pair"
  public_key = tls_private_key.oei-key.public_key_openssh
}

provider "aws" {
  region = var.instance-region
}

resource "aws_instance" "oei-server" {
  ami           = "ami-09042b2f6d07d164a" // for frankfurt + ubuntu
  instance_type = "t2.small" // $0.023/H
  key_name      = "oei-key-pair"

  tags = {
    Name = var.instance-name
  }
}
```

Now if we run this file, it will create an ec2 server on **eu-central-1(**as we specified in [*variable.tf*](http://variable.tf)) with a key-pair called **oei-key-pair**. But if you wish to use a different location, make sure to change your **ami** value according to the [AWS configuration](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html).

## [**output.tf**](http://output.tf)

We will use this file to output the results on the console.

```javascript
output "instance_id" {
  description = "ID of the EC2 instance"
  value       = aws_instance.oei-server.id
}

output "instance_public_ip" {
  description = "Public IP address of the EC2 instance"
  value       = aws_instance.oei-server.public_ip
}

output "instance_public_DNS" {
  description = "Public IP address of the EC2 instance"
  value       = aws_instance.oei-server.public_dns
}

output "instance_public_key" {
  description = "Public key of oe-key-pair"
  value       = tls_private_key.oei-key.public_key_openssh
  sensitive   = true
}

output "instance_private_key" {
  description = "Private key of oe-key-pair"
  value       =  tls_private_key.oei-key.private_key_pem
  sensitive   = true
}
```

Notice I used the ***sensitive*** flag on **instance\_public\_key** & **instance\_private\_key** so that it does not show the plain output by default.

# **Apply the configuration**

Now that we have written our config file, let’s run these 👇🏼 commands to let Terraform do its job.

```javascript
terraform init
```

This will download and install the AWS plugins for the providers we used. After the installation is done, run `terraform plan` to see the changes that will take place on the infrastructure. If everything looks alright, let’s apply the changes by running 👇🏼

```javascript
terraform apply
```

This will take some time. But once it is done, you should be able to run `terraform output` to see the results we specified on [*output.tf*](http://output.tf)*.*


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uurd32wybcc9iuf4d7d7.png)


To check the sensitive output, just run `terraform output -raw “key name”`. Example: 👇🏼


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ht6ldopvbvk80o9kgwn.png)




# **Conclusion**

Thanks for reading the article guys. Hope it helped!