Updated March 31, 2023
Introduction to Ansible SSH Key
In Ansible, we need to connect to remote nodes to execute tasks and play on them. The connection methods for target remote hosts can be defined and set as per actuals. But Ansible uses native OpenSSH as its default connection method. This is because OpenSSH supports ControlPersist, Kerberos, and the defined options in ~/.ssh/config like jump host setup. For SSH connections, Ansible considers that we are using SSH keys to connect to target remote machines. These keys are specific to a host and will not work if your target node is reinstalled or the key was regenerated. In this article, we will try to learn about many methods and options to use Ansible SSH Key.
Explaining the Ansible SSH Key
An SSH key is a combination of two keys which are public and private. The private key is kept locally and the public key is shared with remote hosts to which we want to connect. This combination is used for achieving asymmetric encryption, means is something is encrypted with one key of this combination, then another key of combination is used to decrypt that. In Ansible, we are using OpenSSH to make SSH connections to remote target nodes.
Though Ansible SSH key is the default, for making the connection. But this can be superseded by password if you give –ask-pass for the remote user or –ask-become-pass for privileged user’s password, while running ansible or ansible-playbook on the command line.
We can either set up SSH connection using keys with remotes hosts by either Linux commands or Ansible itself using a module named authorized_keys.
How Does Ansible SSH Key Works?
To make this the SSH connection using keys in Ansible. We must follow steps, which can be done in multiple ways which we will discuss in this document.
- Generate a key pair containing private and public keys as id_rsa and pub respectively.
These will be generated under ~/.ssh directory by default, if not set otherwise.
- Send public key pub to remote hosts by copying it in file ~/.ssh/authorized_keys at end of the file.
- Make ssh connection to the remote host and give yes when it asks to make entry of fingerprint of target hosts to ~/.ssh/known_hosts. If you do not do this, then every time the SSH connection is made, the system will ask to add
This can either be done by Linux command or by using the Ansible authorized_keys module. In this article, we see this Ansible module and its parameters with available options. Some of those are described as below: –
- Key: The SSH public key. It accepts a string or
- Path: Path to authorized_keys file, default is ~/.ssh/authorized_keys.
- State: Should the key be present or absent from file ~/.ssh/authorized_keys.
- User: The user which will be used in this
- Validate_certs: When using https url for the source of the key file, this is used to set whether to allow validating certificate for that source site or not. Default is
- Remove: To set whether to remove all other non-specified keys from ~/.ssh/authorized_keys.
Examples of Ansible SSH Key
Now by using examples, we will try to learn about the Ansible authorized_keys module and some other ways to use keys to setup successful connection to remote target hosts, which you might have to use in day to day operations. We will take some examples, but before going there, we first understand our lab, we used for testing purpose.
Here we have an Ansible control server named ansible-controller and two remotes hosts named host-one and host-two. We will create playbooks and run Ansible commands on the ansible-controller node and see the results on remote hosts.
In this example, we will define the SSH key in the playbook by using a variable named ansible_ssh_private_key_file. Also in this example, we use a non-root user named ec2-user to run playbooks on remote target This user exists on the Ansible controller as well as remote target nodes. The playbook looks like below: –
---
name: This will print one of Ansible facts from remote hosts: all
vars:
ansible_ssh_private_key_file: "https://cdn.educba.com/var/tmp/key_1.pem" tasks:
name: Here we use Ansible debug module to print hostname and IPv4 debug:
msg: Hostname is "{{ ansible_hostname }}" and IPv4 is "{{ ansible_default_ipv4.address }}"
Now running this playbook, ansible picks the .pem file from this location and make the connection with remote target nodes. The output will be like below: –
ansible -playbook /var/tmp/debug_ansible_fact.yml
This variable can be set on below location: –
- Inside playbooks like
- Inside Inventory file against the hostname/IP/group/
- Inside group_vars or host_vars files
- Inside cfg, if this is used for all connections.
Now in this example, we will use an Ansible playbook to create a key combination for a user. Then copy the public key from Ansible controller node to remote target nodes in ~/.ssh/authorized_keys file using Ansible authorized_key
For this, we have made a setup like this. So that currently, our playbooks are failing because we don’t have a successful connection to remote target nodes.
ansible -playbook /var/tmp/debug_ansible_fact_l.yml
Now we create SSH public and private keys on the controller node using the below command.
# ssh-keygen -q -b 2048 -t rsa -N "" -f ~/.ssh/id_rsa
This will create 2 files like below: –
ls -l .ssh/id_rsa*
Now we create a playbook like below which will use Ansible authorized module to copy the public key file to remote hosts: –
---
name: copy public key from controller node to remote nodes hosts: all
tasks:
name: add the public key to authorized_keys using Ansible module authorized_key:
user: ec2-user state: present key: '{{ item }}'
with_file:
- ~/.ssh/id_rsa.pub
Now execute this playbook, but to execute this playbook, we need to pass a key in the command line or we can use parameters to ask for the password. In the below run, we used a key to connect to the remote target node.
ansible -playbook ansible_authorized_key.yml --private-key /var/tmp/key_l.pem
Now when we run the same Ansible playbook which we ran previously, it will run smoothly like below. Because now we have the public key of the controller node copied to remote target node’s authorized keys file, this has made ssh password less from the controller to remote nodes.
ansible -playbook /var/tmp/debug_ansible_fact_l.yml
Conclusion
As we saw that SSH keys play an important role to make a secure connection to remote target nodes. Also, reaching all your infrastructure from a single control can be quite risky if your connection method is not secure, but using Ansible SSH keys try to make this possible. So we need to use it wisely. So learn it first and then use it.
Recommended Articles
This is a guide to Ansible SSH Key. Here we discuss How Does Ansible SSH Key Works and Examples along with the commands and outputs. You may also look at the following articles to learn more –