5.8 KiB
Assignment
The Nautilus DevOps team is planning to test several Ansible playbooks on different app servers in Stratos DC. Before that, some pre-requisites must be met. Essentially, the team needs to set up a password-less SSH connection between Ansible controller and Ansible managed nodes. One of the tickets is assigned to you; please complete the task as per details mentioned below:
a. Jump host is our Ansible controller, and we are going to run Ansible playbooks through thor user from jump host.
b. There is an inventory file /home/thor/ansible/inventory on jump host. Using that inventory file test Ansible ping from jump host to App Server 2, make sure ping works.
Solution
Passwordless SSH — jump host (thor) → App Server 2 (stapp02)
Set up key-based SSH from the Ansible controller to App Server 2, then confirm with an Ansible ping.
Note: this is an Ansible/SSH task, not Kubernetes — no manifests to pipe into
kubectl. Heredocs are used for the files; the key-copy step is interactive by design.
Step 1 — Generate an SSH key pair for thor (if none exists)
# Check first — don't overwrite an existing key
ls -l ~/.ssh/id_rsa.pub 2>/dev/null || ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
-N ""— empty passphrase, so SSH never prompts (that's the whole point of password-less).-f ~/.ssh/id_rsa— the default location Ansible/SSH look in, so no extra config is needed.
Step 2 — Copy the public key to App Server 2
ssh-copy-id steve@stapp02
This prompts for steve's password once — that's expected and unavoidable; it's the one-time
bootstrap that establishes trust. Accept the host-key fingerprint if asked (yes).
Verify the username for App Server 2 against your lab's wiki.
stevefollows the common Stratos DC pattern, but confirm rather than assume.
Confirm it worked — this should log in with no password prompt:
ssh steve@stapp02 hostname
exit
Step 3 — Inventory
The inventory already exists and may contain password variables. With key-based auth in place, those are no longer needed:
# Inspect what's there first
cat /home/thor/ansible/inventory
cat > /home/thor/ansible/inventory <<'EOF'
[app_servers]
stapp02 ansible_user=steve ansible_connection=ssh
EOF
Step 4 — Test the Ansible ping
cd /home/thor/ansible
ansible -i inventory stapp02 -m ping
Expected:
stapp02 | SUCCESS => {
"ansible_facts": {...},
"changed": false,
"ping": "pong"
}
How it works
What "password-less" actually means
SSH supports several auth methods. Password auth requires a secret typed (or supplied via
sshpass/ansible_ssh_pass) on every connection. Public-key auth instead proves identity
cryptographically:
ssh-keygencreates a key pair on the controller — a private key (~/.ssh/id_rsa, stays on the jump host, never shared) and a public key (~/.ssh/id_rsa.pub).ssh-copy-idappends that public key to~/.ssh/authorized_keyson the managed node.- On each later connection, the server challenges the client to prove it holds the matching private key. No password crosses the wire, and nothing needs to be typed.
That one-time password prompt in Step 2 exists because you must authenticate somehow to install the key. After that, it's never needed again.
Why the inventory drops ansible_ssh_pass
With the key installed, Ansible connects over SSH using thor's private key automatically — it's at
the default path, so no ansible_ssh_private_key_file is required either. Leaving a stale
ansible_ssh_pass in the inventory isn't fatal, but removing it is the point of the exercise:
authentication is now key-based, and the inventory should reflect that.
What remains:
| Variable | Purpose |
|---|---|
ansible_user=steve |
Still required — it tells Ansible which remote account to log in as. Key auth proves who you are, not whom you connect as. |
ansible_connection=ssh |
Transport plugin; the default for remote hosts, stated explicitly. |
stapp02 resolves from the jump host, so the inventory name doubles as the connection target — no
ansible_host needed. Confirm with getent hosts stapp02 if unsure.
Why the ping module is the right test
ansible -m ping isn't ICMP — it opens a real SSH connection, runs a trivial Python module on the
target, and returns pong. So a SUCCESS result proves the entire chain works: hostname
resolution, SSH key authentication, the remote user, and Python on the managed node. That's exactly
what requirement (b) asks you to demonstrate.
Host key checking
The first connection prompts to accept the host's fingerprint. Doing it manually in Step 2 (via
ssh-copy-id/ssh) gets it into ~/.ssh/known_hosts before Ansible runs, which is the cleanest
approach. If Ansible still trips on it, add an ansible.cfg beside the inventory:
cat > /home/thor/ansible/ansible.cfg <<'EOF'
[defaults]
host_key_checking = False
EOF
Verify
# Key exists on the controller
ls -l ~/.ssh/id_rsa ~/.ssh/id_rsa.pub
# Key installed on the target (should list thor's key)
ssh steve@stapp02 "cat ~/.ssh/authorized_keys"
# Passwordless login works
ssh steve@stapp02 hostname
# The required check
cd /home/thor/ansible && ansible -i inventory stapp02 -m ping
Expected — both key files present, thor@jump_host visible in the target's authorized_keys, SSH
logging in without a prompt, and the ping returning SUCCESS with "ping": "pong".
Still prompted for a password? Permissions are the usual culprit: on the target,
~/.sshmust be700and~/.ssh/authorized_keys600— SSH silently refuses keys on loosely-permissioned files. On the controller,~/.ssh/id_rsamust be600.