Ansible playbook and SSH keys

Ákos Takács - Jun 13 '23 - - Dev Community

Introduction

Last time (LINK) we configured a very simple Ansible playbook, and we used password authentication instead of SSH keys. That was easy, except the fact that macOS didn't support the requirements, so I had to run a Linux virtual machine as Ansible controller.

The problem with passwords is that not all servers allow password authentication for security reasons and the way we did it last time, we had to type the password every time we ran the playbook. Not to mention if someone finds out your password they can access your server even if they don't have access to your workstation where your SSH keys are.

You can also watch the video about this on YouTube

Table of contents

Before you begin

Requirements

» Back to table of contents «

  • The project requires Python 3.11. If you have an older version and you don't know how you could install a new version, read about Nix in Install Ansible 8 on Ubuntu 20.04 LTS using Nix
  • You will also need to create a virtual Python environment. In this tutorial I used the "venv" Python module and the name of the folder of the virtual environment will be "venv".
  • You will also need an Ubuntu remote server. I recommend an Ubuntu 22.04 virtual machine.

Download the already written code of the previous episode

» Back to table of contents «

If you started the tutorial with this episode, clone the project from GitHub:



git clone https://github.com/rimelek/homelab.git
cd homelab


Enter fullscreen mode Exit fullscreen mode

If you cloned the project now, or you want to make sure you are using the exact same code I did, switch to the previous episode in a new branch



git checkout -b tutorial.episode.1b tutorial.episode.1


Enter fullscreen mode Exit fullscreen mode

Have the inventory file

» Back to table of contents «

Copy the inventory template



cp inventory-example.yml inventory.yml


Enter fullscreen mode Exit fullscreen mode

And change ansible_host to the IP address of your Ubuntu server that you use for this tutorial, and change ansible_user to the username on the remote server that Ansible can use to log in.

Activate the Python virtual environment

» Back to table of contents «

How you activate the virtual environment, depends on how you created it. The previous episode describes the way to create and activate the virtual environment using the "venv" Python module.

For example:



python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt


Enter fullscreen mode Exit fullscreen mode

Generate an SSH key

» Back to table of contents «

First you need to generate an SSH key pair, install the public key on the remote server and configure the private key on the ansible controller. The simple command to generate an SSH key would be



ssh-keygen


Enter fullscreen mode Exit fullscreen mode

and pressing enter without providing any passphrase. If you have many SSH keys, you might want to set a custom path for the key, and you can also change the default algorithm.



ssh-keygen -f ~/.ssh/ansible -t ed25519


Enter fullscreen mode Exit fullscreen mode

When it asks for a passphrase, you can leave it empty or set it to protect your SSH key. Since not using passphrase would be too easy, we will use it and follow the recommendations of the Ansible documentation.

Install the SSH public key on the remote server

» Back to table of contents «

You need to install the public key on the remote server.



ssh-copy-id -i ~/.ssh/ansible.pub ta@192.168.4.58


Enter fullscreen mode Exit fullscreen mode

All you need to pass are the path of the public key and the connection string. Since I have no client configuration yet, I passed the username and IP address as well in the connection string. Depending on the chosen algorithm, you would see something like this on the remote server in $HOME/.ssh/authorized_keys



ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICc/6Mhk0/yj1mpJPw0rMpgbp/2Dev7oieSTuj8/6LvJ ubuntu@ansible-controller


Enter fullscreen mode Exit fullscreen mode

Configure Ansible to use the SSH private key

» Back to table of contents «

You need to set the path of the SSH private key in the inventory file:



ansible_ssh_private_key_file: ~/.ssh/ansible


Enter fullscreen mode Exit fullscreen mode

So the final inventory file would look like this:



all:
  vars:
    ansible_user: ta
  hosts:
    ta-lxlt:
      ansible_host: 192.168.4.58
      ansible_ssh_private_key_file: ~/.ssh/ansible


Enter fullscreen mode Exit fullscreen mode

Don't forget to activate your virtual python environment if you have one (see my previous post)

If you run the playbook now, it will still ask for the passphrase.



ansible-playbook -i inventory.yml playbook.yml


Enter fullscreen mode Exit fullscreen mode

Output:



PLAY [Play 1] ************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************
Enter passphrase for key '/home/ubuntu/.ssh/ansible':


Enter fullscreen mode Exit fullscreen mode

Type the passphrase, press enter, wait for the playbook to be finished and run in again. It might not ask for the passphrase again if you do it quickly enough, although, if you use the same key with a simple ssh command from the terminal you will probably get a passphrase prompt every time. Since you don't always run playbooks so quickly, you can follow Ansible's documentation and configure the SSH agent.



ssh-agent $SHELL
ssh-add ~/.ssh/ansible


Enter fullscreen mode Exit fullscreen mode

Since it starts a new bash shell, the name of the virtual environment will disappear from your prompt. If you want it back, you need to activate the virtual environment again, but the ansible commands would work without it.

The ssh-add command will ask for the passphrase, and you can run the playbook again without the passphrase prompt.



ansible-playbook -i inventory.yml playbook.yml


Enter fullscreen mode Exit fullscreen mode

And that's not all. You can also use a simple SSH command like below to use the added ssh key and log in to your remote server without a passphrase:



ssh ta@192.168.4.58


Enter fullscreen mode Exit fullscreen mode

SSH key without a passphrase

» Back to table of contents «

Since my goal is to help you create a local environment for testing and learning, if you feel the previous solution was too complicated for you to log in to a sandbox virtual machine, you can also choose not to set a passphrase when you generate the key. Adding a configuration to your $HOME/.ssh/config file like below could be enough for a simple SSH command too:



Host 192.168.4.58
  IdentityFile ~/.ssh/ansible


Enter fullscreen mode Exit fullscreen mode

This is actually what I use for my local virtual machines and if you try to find out how multipass lets you get a shell in the virtual machine, you will find out it has an SSH key and you in fact use SSH connection when you run multipass shell VM_NAME

Conclusion

» Back to table of contents «

In this post I wanted to focus on the SSH keys, so you can start to use it. There are different ways for different environments, and you need to decide what is more important. Security or convenience. Of course if you are building your home lab for learning, you might want to learn about security as well, but you don't necessarily have to start with that. Later, when you really need to use more secrets, passwords in your Ansible playbooks, you will use some encrypted configuration files too, however, if you try to start with the most secure configuration which can also work in a production environment you might give up without having enough motivation to invest more time in security.

Keep that in mind and your (professional) life will be easier with Ansible, not harder.

The final source code of this episode can be found on GitHub:

https://github.com/rimelek/homelab/tree/tutorial.episode.2

GitHub logo rimelek / homelab

Source code to create a home lab. Part of a video tutorial

README

This project was created to help you build your own home lab where you can test your applications and configurations without breaking your workstation, so you can learn on cheap devices without paying for more expensive cloud services.

The project contains code written for the tutorial, but you can also use parts of it if you refer to this repository.

Tutorial on YouTube in English: https://www.youtube.com/watch?v=K9grKS335Mo&list=PLzMwEMzC_9o7VN1qlfh-avKsgmiU8Jofv

Tutorial on YouTube in Hungarian: https://www.youtube.com/watch?v=dmg7lYsj374&list=PLUHwLCacitP4DU2v_DEHQI0U2tQg0a421

Note: The inventory.yml file is not shared since that depends on the actual environment so it will be different for everyone. If you want to learn more about the inventory file watch the videos on YouTube or read the written version on https://dev.to. Links in the video descriptions on YouTube.

You can also find an example inventory file in the project root. You can copy that and change the content, so you will use your IP…

. . . . . . . . . . . . . . . . . .
Terabox Video Player