DevOps Day 86: Ansible Ping Module Usage (Password-less SSH)¶
This document provides a comprehensive solution for DevOps Day 86. The goal was to establish a secure, password-less SSH connection between the Ansible controller (Jump Host) and the managed nodes (App Servers), and then verify this connection using the Ansible ping module.
Table of Contents¶
- DevOps Day 86: Ansible Ping Module Usage (Password-less SSH)
- Table of Contents
- Task Overview
- Step-by-Step Solution
- Deep Dive: Concepts Used
- Troubleshooting
Task Overview¶
Objective: The Nautilus DevOps team needs to enable password-less SSH authentication for the user thor on the Jump Host to connect to App Server 1 (and others).
Requirements:
1. Generate Keys: Create an RSA SSH key pair for the user thor on the Jump Host.
2. Copy Keys: Install the public key onto the target App Servers (stapp01, stapp02, stapp03).
3. Update Inventory: Modify /home/thor/ansible/inventory to remove hardcoded passwords.
4. Test: Verify connectivity to App Server 1 using ansible -m ping.
Step-by-Step Solution¶
1. Generate SSH Keys¶
First, we generate a secure RSA key pair on the controller (Jump Host).
Command:
ssh-keygen -t rsa -b 4096
/home/thor/.ssh/id_rsa).
* Passphrase: Press Enter twice to leave it empty (for truly automated, password-less login).
2. Distribute Public Keys¶
Next, we copy the newly created public key (id_rsa.pub) to the authorized_keys file on each app server.
Commands:
# For App Server 1 (Tony)
ssh-copy-id tony@stapp01
# Password: Ir0nM@n
# For App Server 2 (Steve)
ssh-copy-id steve@stapp02
# Password: Am3ric@
# For App Server 3 (Banner)
ssh-copy-id banner@stapp03
# Password: BigGr33n
3. Update the Inventory File¶
Since we now have key-based authentication, we must remove the ansible_ssh_pass (or ansible_ssh_password) variable from the inventory. It is no longer needed and keeping it is a security risk.
Command:
vi /home/thor/ansible/inventory
New Content:
[app]
stapp01 ansible_host=stapp01 ansible_user=tony ansible_ssh_common_args='-o StrictHostKeyChecking=no'
stapp02 ansible_host=stapp02 ansible_user=steve ansible_ssh_common_args='-o StrictHostKeyChecking=no'
stapp03 ansible_host=stapp03 ansible_user=banner ansible_ssh_common_args='-o StrictHostKeyChecking=no'
ansible_ssh_pass=...
* Kept: ansible_user=... (Ansible still needs to know who to login as)
4. Validate with Ansible Ping¶
Finally, verify that Ansible can connect without asking for a password.
Command:
ansible stapp01 -i inventory -m ping
Expected Output:
stapp01 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
Deep Dive: Concepts Used¶
Password-less SSH¶
This mechanism uses asymmetric cryptography.
1. Private Key (id_rsa): Kept secret on the Jump Host. It's like your actual physical key.
2. Public Key (id_rsa.pub): Copied to the server. It's like the lock.
When Ansible connects, the server uses the "lock" (public key) to create a challenge that only the "key" (private key) can solve. If solved, access is granted without a password.
Ansible Ping Module¶
The ping module is not an ICMP ping (like the network command ping google.com).
* What it does: It attempts to SSH into the remote server, verify valid login credentials, and check if a usable Python interpreter is available.
* Why use it? It is the definitive test for "Is Ansible ready to run playbooks on this host?"
Troubleshooting¶
Issue: "Permission denied (publickey,password)"
* Cause: The public key was not correctly copied to the server, or permissions on ~/.ssh are wrong.
* Fix: Run ssh -v tony@stapp01 to debug. Retry ssh-copy-id. Ensure you removed ansible_ssh_pass from the inventory if it was incorrect.
Issue: Still prompted for password
* Cause: You might have set a passphrase when creating the key in step 1.
* Fix: Generate a new key without a passphrase, or use ssh-agent to cache the passphrase for the session.
Issue: "Host key verification failed"
* Cause: The known_hosts file doesn't recognize the server fingerprint.
* Fix: Ensure ansible_ssh_common_args='-o StrictHostKeyChecking=no' is in your inventory or ansible.cfg.