How to generate SSH key in Terraform using tls_private_key?
The Terraform's module tls_private_key can help you to generate the TLS Private key. Here is what happens when you use Terraform's tls_private_key module -
- At first you generate RSA or ECDAS private key.
- After generating the private key we need to encode the private key as PEM file.
- After that tls_private_key module will help you to download the private_key(PEM) locally
- Finally the tls_private_key module will also set the permission to 0600
All the above tasks are carried out behind the scene by module tls_private_key.
This blog post will help you to understand tls_private_key module as well as how to use it inside Terraform project
(Note - The complete terraform code you can find at the bottom of the page)
Table of Content
- Create tls_private_key resource inside Terraform file
- Create aws_key_pair and store public key onto AWS
- Verify the generated public and private keys
- Create AWS EC2 instance using the generated tls_private_key
- Conclusion
1. Create tls_private_key resource inside Terraform file
When you work with Terraform you need to define resource and since we are using the tls_private_key module, so we will be creating a resource for tls_private_key -
1# file name : main.tf
2# The following configuration will enable you to use tls_private_key module
3
4resource "tls_private_key" "terrafrom_generated_private_key" {
5 algorithm = "RSA"
6 rsa_bits = 4096
7}
Other supported Algorithm- ECDSA P384 and ED25519
Also apart from RSA 5096 algorithm, you can use other algorithms such as - ECDSA P384 and ED25519 for generating the
Here is the code snippet for ECDSA P384 and ED25519 -
1resource "tls_private_key" "ecdsa-p384-example" {
2 algorithm = "ECDSA"
3 ecdsa_curve = "P384"
4}
1resource "tls_private_key" "ed25519-example" {
2 algorithm = "ED25519"
3}
2. Create aws_key_pair and store the public key onto AWS
The next terraform module we are going to use is aws_key_pair. You need to keep a couple of things in your mind while working with the key generation -
- Private key - The private key will be generated and stored locally on your working computer
- Public key - Public key will be automatically uploaded to AWS.
1resource "aws_key_pair" "generated_key" {
2
3 # Name of key: Write the custom name of your key
4 key_name = "aws_keys_pairs"
5
6 # Public Key: The public will be generated using the reference of tls_private_key.terrafrom_generated_private_key
7 public_key = tls_private_key.terrafrom_generated_private_key.public_key_openssh
8
9 # Store private key : Generate and save private key(aws_keys_pairs.pem) in current directory
10 provisioner "local-exec" {
11 command = <<-EOT
12 echo '${tls_private_key.terrafrom_generated_private_key.private_key_pem}' > aws_keys_pairs.pem
13 chmod 400 aws_keys_pairs.pem
14 EOT
15 }
16}
2.1 Run the Terraform code
Here is the complete Terraform code for generating the SSH Keys -
1provider "aws" {
2 region = "eu-central-1"
3 shared_credentials_files = ["/Users/rwagh/.aws/credentials"]
4 #access_key = ""
5 #secret_key = ""
6}
7
8resource "tls_private_key" "terrafrom_generated_private_key" {
9 algorithm = "RSA"
10 rsa_bits = 4096
11}
12
13resource "aws_key_pair" "generated_key" {
14
15 # Name of key : Write the custom name of your key
16 key_name = "aws_keys_pairs"
17
18 # Public Key: The public will be generated using the reference of tls_private_key.terrafrom_generated_private_key
19 public_key = tls_private_key.terrafrom_generated_private_key.public_key_openssh
20
21 # Store private key : Generate and save private key(aws_keys_pairs.pem) in current directory
22 provisioner "local-exec" {
23 command = <<-EOT
24 echo '${tls_private_key.terrafrom_generated_private_key.private_key_pem}' > aws_keys_pairs.pem
25 chmod 400 aws_keys_pairs.pem
26 EOT
27 }
28}
Note-
- Make sure to replace the access key and secret key in the above Terraform code based on your AWS account
2.2 Execute - "$ terraform init" command
Now we have our Terraform code ready and the first command we are going to run is $ terraform init
.
The key points to notice over here -
- The
$ terraform init
command will find the latest version of tls - After that it will download and install the same latest version.
As you can see in the following screenshot of the terminal it has downloaded all the required dependencies of tls
2.3 Execute - "$ terraform plan" command
After successfully running the $ terraform init command, let's run the next command .i.e. $ terraform plan
Here is the screenshot of the terminal after running the terraform plan command.
You will notice the following things -
- The terraform plan command will generate the keys with the name - aws_keys_pairs.pem
- Also it will create those keys using algorithm RSA and ecdsa_curve
2.4 Execute - "$ terraform apply" command
Finally, run $ terraform apply
command to generate both public as well as private keys.
Here is the screenshot from the terminal -
3. Verify the generated public and private keys
Let's first verify the public key which is generated on our local system. Goto your project where you have you
main.tf
and there you will find the private key -
Here is the screenshot -
Verify the Public key on AWS
- Log into to your AWS account-> EC2 Dashboard -> Key Pair
- Click on key Pair link
4. Create AWS EC2 instance using the generated tls_private_key
Now let's take one step forward and use the existing Terraform Code but this time we are going to create EC2 instance using the generated tls_private_key.
Here is the Terraform code which I have updated after the Step-3 -
1
2 provider "aws" {
3 region = "eu-central-1"
4 shared_credentials_files = ["/Users/rwagh/.aws/credentials"]
5 }
6
7 resource "tls_private_key" "terrafrom_generated_private_key" {
8 algorithm = "RSA"
9 rsa_bits = 4096
10 }
11
12 resource "aws_key_pair" "generated_key" {
13
14 # Name of key: Write the custom name of your key
15 key_name = "aws_keys_pairs"
16
17 # Public Key: The public will be generated using the reference of tls_private_key.terrafrom_generated_private_key
18 public_key = tls_private_key.terrafrom_generated_private_key.public_key_openssh
19
20 # Store private key : Generate and save private key(aws_keys_pairs.pem) in current directory
21 provisioner "local-exec" {
22 command = <<-EOT
23 echo '${tls_private_key.terrafrom_generated_private_key.private_key_pem}' > aws_keys_pairs.pem
24 chmod 400 aws_keys_pairs.pem
25 EOT
26 }
27 }
28
29 # 1. EC2 Instance
30 resource "aws_instance" "ec2_example" {
31
32 ami = "ami-0767046d1677be5a0"
33 instance_type = "t2.micro"
34
35 # 2. Key Name
36 # Specify the key name and it should match with key_name from the resource "aws_key_pair"
37 key_name= "aws_keys_pairs"
38 tags = {
39 Name = "Terraform EC2 - using tls_private_key module"
40 }
41
42 #3. Connection Block-
43 connection {
44 type = "ssh"
45 host = self.public_ip
46 user = "ubuntu"
47
48 # Mention the exact private key name which will be generated
49 private_key = file("aws_keys_pairs.pem")
50 timeout = "4m"
51 }
52 }
Here are the additional changes which I did to my Terraform code -
1. EC2 Instance - I have added one more Terraform resource .i.e. - aws_instance for provisioning the EC2 instance.
2. Key Name- You need to add a key name which should be the same which we have created using Terraform's tls_private_key module
3. Connection Block- At last you need to mention the connection block where you will connect to EC2 instance using the private key.
Refer to the following screenshot
Here is the ec2 instance which is up and running on AWS with the generated tls_private_key-
Also when you click on connect (EC2 -> Instances -> i-0fc06a99b85eac11f -> Connect to instance) then you will reference to the same private key -
5. Conclusion
I hope this article will help you to understand the concept of SSL Key generation using Terraform's tls_private_key module.
If you do not want to use the Terraform's tls_private_key module then you have to manually generate the SSH Keys by yourself. Here is one more article where you will find how to generate the SSH Keys manually and use them inside your terraform project
Read More - Terragrunt -
Posts in this Series
- Securing Sensitive Data in Terraform
- Boost Your AWS Security with Terraform : A Step-by-Step Guide
- How to Load Input Data from a File in Terraform?
- Can Terraform be used to provision on-premises infrastructure?
- Fixing the Terraform Error creating IAM Role. MalformedPolicyDocument Has prohibited field Resource
- In terraform how to handle null value with default value?
- Terraform use module output variables as inputs for another module?
- How to Reference a Resource Created by a Terraform Module?
- Understanding Terraform Escape Sequences
- How to fix private-dns-enabled cannot be set because there is already a conflicting DNS domain?
- Use Terraform to manage AWS IAM Policies, Roles and Users
- How to split Your Terraform main.tf File into Multiple Files
- How to use Terraform variable within variable
- Mastering the Terraform Lookup Function for Dynamic Keys
- Copy files to EC2 and S3 bucket using Terraform
- Troubleshooting Error creating EC2 Subnet InvalidSubnet Range The CIDR is Invalid
- Troubleshooting InvalidParameter Security group and subnet belong to different networks
- Managing strings in Terraform: A comprehensive guide
- How to use terraform depends_on meta argument?
- What is user_data in Terraform?
- Why you should not store terraform state file(.tfstate) inside Git Repository?
- How to import existing resource using terraform import comand?
- Terraform - A detailed guide on setting up ALB(Application Load Balancer) and SSL?
- Testing Infrastructure as Code with Terraform?
- How to remove a resource from Terraform state?
- What is Terraform null Resource?
- In terraform how to skip creation of resource if the resource already exist?
- How to setup Virtual machine on Google Cloud Platform
- How to use Terraform locals?
- Terraform Guide - Docker Containers & AWS ECR(elastic container registry)?
- How to generate SSH key in Terraform using tls_private_key?
- How to fix-Terraform Error acquiring the state lock ConditionalCheckFiledException?
- Terraform Template - A complete guide?
- How to use Terragrunt?
- Terraform and AWS Multi account Setup?
- Terraform and AWS credentials handling?
- How to fix-error configuring S3 Backend no valid credential sources for S3 Backend found?
- Terraform state locking using DynamoDB (aws_dynamodb_table)?
- Managing Terraform states?
- Securing AWS secrets using HashiCorp Vault with Terraform?
- How to use Workspaces in Terraform?
- How to run specific terraform resource, module, target?
- How Terraform modules works?
- Secure AWS EC2s & GCP VMs with Terraform SSH Keys!
- What is terraform provisioner?
- Is terraform destroy needed before terraform apply?
- How to fix terraform error Your query returned no results. Please change your search criteria and try again?
- How to use Terraform Data sources?
- How to use Terraform resource meta arguments?
- How to use Terraform Dynamic blocks?
- Terraform - How to nuke AWS resources and save additional AWS infrastructure cost?
- Understanding terraform count, for_each and for loop?
- How to use Terraform output values?
- How to fix error configuring Terraform AWS Provider error validating provider credentials error calling sts GetCallerIdentity SignatureDoesNotMatch?
- How to fix Invalid function argument on line in provider credentials file google Invalid value for path parameter no file exists
- How to fix error value for undeclared variable a variable named was assigned on the command line?
- What is variable.tf and terraform.tfvars?
- How to use Terraform Variables - Locals,Input,Output
- Terraform create EC2 Instance on AWS
- How to fix Error creating service account googleapi Error 403 Identity and Access Management (IAM) API has not been used in project before or it is disabled
- Install terraform on Ubuntu 20.04, CentOS 8, MacOS, Windows 10, Fedora 33, Red hat 8 and Solaris 11