Skip to content

Instantly share code, notes, and snippets.

@shirou
Last active March 14, 2024 12:16
Show Gist options
  • Save shirou/6928012 to your computer and use it in GitHub Desktop.
Save shirou/6928012 to your computer and use it in GitHub Desktop.
run ssh-keyscan to add keys to known_hosts. This is a playbook for ansible
---
- hosts: all
gather_facts: no
sudo: no
tasks:
- name: run ssh-keyscan to add keys to known_hosts
local_action: shell ssh-keyscan {{ ansible_ssh_host }} >> ~/.ssh/known_hosts
@cfaria929
Copy link

local_action: shell ssh-keyscan {{ inventory_hostname }} >> ~/.ssh/known_hosts

I found that {{ ansible_ssh_host }} made everything show up as localhost in my known_hosts file. the above corrected for me

@stepansantalov
Copy link

This adds multiple lines each run, you should check if line non-existant or not the same before add.

@thomasrlord
Copy link

@cfaria929 solution worked for me. Thanks!

@electropolis
Copy link

local_action: shell ssh-keyscan {{ inventory_hostname }} >> ~/.ssh/known_hosts

I found that {{ ansible_ssh_host }} made everything show up as localhost in my known_hosts file. the above corrected for me

But this will fail.

@rdkls
Copy link

rdkls commented Sep 6, 2018

    - name: get port, default 22
      delegate_to: localhost
      set_fact:
        ansible_ssh_port: "{{ hostvars[inventory_hostname]['ansible_ssh_port'] | default('22') }}"

    - name: Ensure ssh host key known
      delegate_to: localhost
      lineinfile:
        dest: ~/.ssh/known_hosts
        create: yes
        state: present
        line: "{{ lookup('pipe', 'ssh-keyscan -trsa -p' + ansible_ssh_port + ' ' + ansible_ssh_host) }}"

@cbrunnkvist
Copy link

cbrunnkvist commented Mar 20, 2019

@rdkls must have meant

line: "{{ lookup('pipe', 'ssh-keyscan -trsa -p' + ansible_ssh_port + ' ' + inventory_hostname) }}"

@realtebo
Copy link

realtebo commented Jul 8, 2020

@rdkls yopur snippet is precious ! The line is simply amazing, where did you found documented the lookup with pipe ?

@sicet7
Copy link

sicet7 commented Oct 17, 2021

I am running Ansible 2.11
And i have these 2 working 4 any1 interested :-)
They are based on the same pipe solution @rdkls made :-)

-   hosts: all
    gather_facts: no
    become: no

    tasks:
        -   name: Setup Known Hosts With Port
            delegate_to: localhost
            known_hosts:
                key: "{{ lookup('pipe', 'ssh-keyscan -trsa -p ' + lookup('config', 'DEFAULT_REMOTE_PORT') | string + ' ' + inventory_hostname) }}"
                name: "{{ inventory_hostname }}"
                state: present
            when: lookup('config', 'DEFAULT_REMOTE_PORT') | string != "None"

        -   name: Setup Known Hosts Without Port
            delegate_to: localhost
            known_hosts:
                key: "{{ lookup('pipe', 'ssh-keyscan -trsa ' + inventory_hostname) }}"
                name: "{{ inventory_hostname }}"
                state: present
            when: lookup('config', 'DEFAULT_REMOTE_PORT') | string == "None"
-   hosts: 127.0.0.1
    connection: local
    gather_facts: no
    become: no

    tasks:
        -   name: Setup Known Hosts With Port
            known_hosts:
                key: "{{ lookup('pipe', 'ssh-keyscan -trsa -p' + lookup('config', 'DEFAULT_REMOTE_PORT') | string + ' ' + item.value.inventory_hostname) }}"
                name: "{{ item.value.inventory_hostname }}"
                state: present
            when: lookup('config', 'DEFAULT_REMOTE_PORT') | string != "None"
            with_items: "{{ hostvars | dict2items }}"

        -   name: Setup Known Hosts Without Port
            known_hosts:
                key: "{{ lookup('pipe', 'ssh-keyscan -trsa ' + item.value.inventory_hostname) }}"
                name: "{{ item.value.inventory_hostname }}"
                state: present
            when: lookup('config', 'DEFAULT_REMOTE_PORT') | string == "None"
            with_items: "{{ hostvars | dict2items }}"

@DanielDavis5
Copy link

Ditch the pipes.

- name: Scan for SSH host keys.
  local_action:
    module: shell
    cmd: ssh-keyscan 192.168.1.1 2>/dev/null
  changed_when: False
  register: ssh_scan

- name: Update known_hosts.
  local_action:
    module: known_hosts
    key: "{{ item }}"
    name: "{{ ansible_host }}"
  with_items: "{{ ssh_scan.stdout_lines }}"

@oerp-odoo
Copy link

@DanielDavis5 this is a good solution as you don't need to use extra hacks. Though to me it was not working if I was redirecting to /dev/null, all the output would be registered to stderr. If I keep ssh-keyscan some-host only, then it works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment