Creating SSH Keys with Terraform: A Step-by-Step Guide
Written on
Chapter 1: Introduction to SSH Keys and Terraform
Setting up cloud servers with Terraform is a straightforward process. However, to connect to these servers using your CI/CD tools, you must configure SSH key pairs. This guide will walk you through generating SSH key pairs with Terraform and using these keys to connect your server to GitHub Actions. By integrating Terraform and GitHub, you can streamline your infrastructure deployment.
Understanding the Terraform and GitHub Workflow
Creating SSH keys with Terraform is quite simple. You can produce a public and private RSA key pair using the following Terraform configuration:
The Hashicorp TLS provider supports various encryption methods, making it suitable for this task. However, keep in mind that the public/private key pair will be stored unencrypted in the Terraform state. It's advisable to use secure remote state storage solutions like Terraform Cloud, which is a great free option for personal projects.
#### What is Terraform Cloud?
Terraform Cloud is Hashicorp's managed service for executing Terraform configurations. It provides a centralized platform for managing infrastructure as code.
Chapter 2: Managing SSH Keys for Production
For larger production environments, it's crucial to handle your SSH keys outside of Terraform.
Using the Generated SSH Keys
To illustrate the use of generated SSH keys, we'll provision a virtual machine (VM) and utilize the SSH key. Although this example uses Digital Ocean, you can apply it to any cloud provider that allows SSH key associations with VMs.
Below is a sample configuration for DigitalOcean. Remember, you'll need to set up the provider and obtain an API token, which is beyond the scope of this tutorial. The TLS provider generates key pairs in both OpenSSH and PEM formats; in this case, we use the more common OpenSSH format with the public_key_openssh property.
#### Connecting to Your Server
Once your SSH key is set up, your server will be ready for configuration. But how do you connect to it? You shouldn’t handle the keys directly; instead, let’s transfer this sensitive information to GitHub, enabling GitHub Actions to SSH into the server.
Integrating Private SSH Keys with GitHub Actions
To connect to your server via GitHub Actions, you'll need to manage your SSH keys and configurations effectively, ideally using ssh-agent to oversee the key management seamlessly. Here’s a simple workflow employing shimataro/ssh-key-action@v2 to set up the ssh-agent.
As shown in the example, you need to define two secrets: ${{ secrets.SSH_KEY }} (the private SSH key for server access) and ${{ secrets.KNOWN_HOSTS }} (to verify that the server is indeed yours, preventing imposters).
#### Understanding Known Hosts
The known_hosts file is an essential security feature that many users disable due to misunderstandings. It's vital to understand its purpose for maintaining secure connections.
You will also provision these secrets using the GitHub Terraform provider. Specifically, you will create environment secrets for an environment labeled digitalocean. The workflow environment: digitalocean corresponds to that specific setting.
You can find more information on setting up environments with Terraform here:
How to Configure GitHub Environments with Terraform?
Chapter 3: Creating the Necessary Secrets
Let’s focus on creating the required secrets. First, we’ll address ${{ secrets.SSH_KEY }}. This step is straightforward; you’ll utilize the previously defined resource tls_private_key.ssh and save the private_key_pem as a secret.
Next, let’s look at ${{ secrets.KNOWN_HOSTS }}. This process requires a bit more effort. The known_hosts configuration is typically created using the ssh-keyscan utility to gather the server's public host key. Fortunately, there is a simple provider to manage this task: the sshclient provider.
Here’s a template that can be used to create the known_hosts file, accommodating multiple servers by appending outputs from ssh-keyscan.
With these configurations in place, your server is now prepared to be accessed via GitHub Actions using tools like Ansible.
Conclusion
Congratulations! You’ve successfully set up a robust configuration using Terraform to provision your server through Infrastructure as Code (IaC). Establishing your server is just the beginning; you must also consider how your tools will interact with it. Ensure that your SSH configuration is correct and that you do not overlook validating the known_hosts.
This article is part of a larger initiative exploring how to use Terraform, Ansible, and GitHub for small self-hosted projects by addressing various questions, including:
- How to configure GitHub Environments with Terraform?
- How to provision a VM on DigitalOcean with Terraform?
- How to create SSH keys with Terraform?
- How to create Ansible Inventory with Terraform?
- How to run an Ansible playbook using GitHub Actions?
GitHub Repository: xNok/infra-bootstrap-tools - A collection of scripts for setting up a host with Docker Swarm and Caddy.
Learn how to set up Azure infrastructure with Terraform, including configuring Linux VMs with SSH keys in this detailed tutorial.
This video demonstrates how to create an AWS Keypair using Terraform and attach it to an EC2 instance for secure access.